Backed out 4 changesets (bug 1626967) for breaking Raptor tests godot-c and wm-c. a=backout

Backed out changeset 985eea91c36c (bug 1626967)
Backed out changeset 837dab8ce31c (bug 1626967)
Backed out changeset f48ad40e60af (bug 1626967)
Backed out changeset 29aaf3ff21ea (bug 1626967)

--HG--
extra : amend_source : 8f86b92aa59cde8a0fdc9fec7b9994c79a6f19df
This commit is contained in:
Sebastian Hengst 2020-04-08 10:06:47 +02:00
parent 88bbcf97df
commit b5fa1b7063
40 changed files with 640 additions and 899 deletions

View File

@ -55,7 +55,7 @@ rev = "72f813a03cefbdf8e2c58c7410f3556c79429a06"
[source."https://github.com/bytecodealliance/wasmtime"]
git = "https://github.com/bytecodealliance/wasmtime"
replace-with = "vendored-sources"
rev = "6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
rev = "5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
[source."https://github.com/badboy/failure"]
git = "https://github.com/badboy/failure"

36
Cargo.lock generated
View File

@ -715,22 +715,22 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
dependencies = [
"cranelift-entity 0.62.0",
"cranelift-entity 0.60.0",
]
[[package]]
name = "cranelift-codegen"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
dependencies = [
"byteorder",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-entity 0.62.0",
"cranelift-entity 0.60.0",
"log",
"smallvec 1.2.0",
"target-lexicon 0.10.0",
@ -739,17 +739,17 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
dependencies = [
"cranelift-codegen-shared",
"cranelift-entity 0.62.0",
"cranelift-entity 0.60.0",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
[[package]]
name = "cranelift-entity"
@ -758,13 +758,13 @@ source = "git+https://github.com/PLSysSec/lucet_sandbox_compiler?rev=5e870faf6f9
[[package]]
name = "cranelift-entity"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
[[package]]
name = "cranelift-frontend"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
dependencies = [
"cranelift-codegen",
"log",
@ -774,11 +774,11 @@ dependencies = [
[[package]]
name = "cranelift-wasm"
version = "0.62.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=6a68130d5b0296379fae0b8de5fbb8a1499b67a5#6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
version = "0.60.0"
source = "git+https://github.com/bytecodealliance/wasmtime?rev=5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c#5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
dependencies = [
"cranelift-codegen",
"cranelift-entity 0.62.0",
"cranelift-entity 0.60.0",
"cranelift-frontend",
"log",
"thiserror",

View File

@ -76,8 +76,8 @@ failure_derive = { git = "https://github.com/badboy/failure", rev = "64af847bc5f
[patch.crates-io.cranelift-codegen]
git = "https://github.com/bytecodealliance/wasmtime"
rev = "6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
rev = "5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"
[patch.crates-io.cranelift-wasm]
git = "https://github.com/bytecodealliance/wasmtime"
rev = "6a68130d5b0296379fae0b8de5fbb8a1499b67a5"
rev = "5cfcbeb59d477e028c6fb312f1cf63aa711fcc3c"

View File

@ -119,12 +119,11 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
// Omit the check when framePushed is small and we know there's no
// recursion.
if (func.frame_pushed < MAX_UNCHECKED_LEAF_FRAME_SIZE &&
!func.contains_calls) {
masm.reserveStack(func.frame_pushed);
if (func.framePushed < MAX_UNCHECKED_LEAF_FRAME_SIZE && !func.containsCalls) {
masm.reserveStack(func.framePushed);
} else {
std::pair<CodeOffset, uint32_t> pair = masm.wasmReserveStackChecked(
func.frame_pushed, BytecodeOffset(lineOrBytecode));
func.framePushed, BytecodeOffset(lineOrBytecode));
CodeOffset trapInsnOffset = pair.first;
size_t nBytesReservedBeforeTrap = pair.second;
@ -142,11 +141,9 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
&functionEntryStackMap)) {
return false;
}
// In debug builds, we'll always have a stack map, even if there are no
// refs to track.
MOZ_ALWAYS_TRUE(functionEntryStackMap);
if (functionEntryStackMap &&
!stackMaps->add((uint8_t*)(uintptr_t)trapInsnOffset.offset(),
functionEntryStackMap)) {
@ -154,36 +151,36 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
return false;
}
}
MOZ_ASSERT(masm.framePushed() == func.frame_pushed);
MOZ_ASSERT(masm.framePushed() == func.framePushed);
// Copy the machine code; handle jump tables and other read-only data below.
uint32_t funcBase = masm.currentOffset();
if (!masm.appendRawCode(func.code, func.code_size)) {
if (!masm.appendRawCode(func.code, func.codeSize)) {
return false;
}
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
uint32_t codeEnd = masm.currentOffset();
#endif
wasm::GenerateFunctionEpilogue(masm, func.frame_pushed, offsets);
wasm::GenerateFunctionEpilogue(masm, func.framePushed, offsets);
if (func.num_rodata_relocs > 0) {
if (func.numRodataRelocs > 0) {
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
constexpr size_t jumptableElementSize = 4;
MOZ_ASSERT(func.jumptables_size % jumptableElementSize == 0);
MOZ_ASSERT(func.jumptablesSize % jumptableElementSize == 0);
// Align the jump tables properly.
masm.haltingAlign(jumptableElementSize);
// Copy over the tables and read-only data.
uint32_t rodataBase = masm.currentOffset();
if (!masm.appendRawCode(func.code + func.code_size,
func.total_size - func.code_size)) {
if (!masm.appendRawCode(func.code + func.codeSize,
func.totalSize - func.codeSize)) {
return false;
}
uint32_t numElem = func.jumptables_size / jumptableElementSize;
uint32_t numElem = func.jumptablesSize / jumptableElementSize;
uint32_t bias = rodataBase - codeEnd;
// Bias the jump table(s). The table values are negative values
@ -198,9 +195,9 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
// Patch up the code locations. These represent forward distances that also
// become greater, so we add a positive value.
for (uint32_t i = 0; i < func.num_rodata_relocs; i++) {
MOZ_ASSERT(func.rodata_relocs[i] < func.code_size);
masm.addToPCRel4(funcBase + func.rodata_relocs[i], bias);
for (uint32_t i = 0; i < func.numRodataRelocs; i++) {
MOZ_ASSERT(func.rodataRelocs[i] < func.codeSize);
masm.addToPCRel4(funcBase + func.rodataRelocs[i], bias);
}
#else
MOZ_CRASH("No jump table support on this platform");
@ -218,11 +215,11 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
maplet->offsetBy(funcBase);
}
for (size_t i = 0; i < func.num_metadata; i++) {
for (size_t i = 0; i < func.numMetadata; i++) {
const CraneliftMetadataEntry& metadata = func.metadatas[i];
CheckedInt<size_t> offset = funcBase;
offset += metadata.code_offset;
offset += metadata.codeOffset;
if (!offset.isValid()) {
return false;
}
@ -231,16 +228,19 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
// Check code offsets.
MOZ_ASSERT(offset.value() >= offsets->normalEntry);
MOZ_ASSERT(offset.value() < offsets->ret);
MOZ_ASSERT(metadata.module_bytecode_offset != 0);
// Check bytecode offsets.
if (lineOrBytecode > 0) {
MOZ_ASSERT(metadata.module_bytecode_offset >= lineOrBytecode);
MOZ_ASSERT(metadata.module_bytecode_offset <
if (metadata.moduleBytecodeOffset > 0 && lineOrBytecode > 0) {
MOZ_ASSERT(metadata.moduleBytecodeOffset >= lineOrBytecode);
MOZ_ASSERT(metadata.moduleBytecodeOffset <
lineOrBytecode + funcBytecodeSize);
}
#endif
uint32_t bytecodeOffset = metadata.module_bytecode_offset;
// TODO(bug 1532716): Cranelift gives null bytecode offsets for symbolic
// accesses.
uint32_t bytecodeOffset = metadata.moduleBytecodeOffset
? metadata.moduleBytecodeOffset
: lineOrBytecode;
switch (metadata.which) {
case CraneliftMetadataEntry::Which::DirectCall: {
@ -259,14 +259,15 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
masm.append(trap, wasm::TrapSite(offset.value(), trapOffset));
break;
}
case CraneliftMetadataEntry::Which::MemoryAccess: {
BytecodeOffset trapOffset(bytecodeOffset);
masm.appendOutOfBoundsTrap(trapOffset, offset.value());
break;
}
case CraneliftMetadataEntry::Which::SymbolicAccess: {
CodeOffset raOffset(offset.value());
CallSiteDesc desc(bytecodeOffset, CallSiteDesc::Symbolic);
masm.append(desc, raOffset);
SymbolicAddress sym =
ToSymbolicAddress(BD_SymbolicAddress(metadata.extra));
masm.append(SymbolicAccess(raOffset, sym));
masm.append(SymbolicAccess(CodeOffset(offset.value()), sym));
break;
}
default: {
@ -291,15 +292,15 @@ class AutoCranelift {
public:
explicit AutoCranelift(const ModuleEnvironment& env)
: env_(env), compiler_(nullptr) {
staticEnv_.ref_types_enabled = env.refTypesEnabled();
staticEnv_.refTypesEnabled = env.refTypesEnabled();
#ifdef WASM_SUPPORTS_HUGE_MEMORY
if (env.hugeMemoryEnabled()) {
// In the huge memory configuration, we always reserve the full 4 GB
// index space for a heap.
staticEnv_.static_memory_bound = HugeIndexRange;
staticEnv_.memory_guard_size = HugeOffsetGuardLimit;
staticEnv_.staticMemoryBound = HugeIndexRange;
staticEnv_.memoryGuardSize = HugeOffsetGuardLimit;
} else {
staticEnv_.memory_guard_size = OffsetGuardLimit;
staticEnv_.memoryGuardSize = OffsetGuardLimit;
}
#endif
// Otherwise, heap bounds are stored in the `boundsCheckLimit` field
@ -320,7 +321,7 @@ class AutoCranelift {
CraneliftFuncCompileInput::CraneliftFuncCompileInput(
const FuncCompileInput& func)
: bytecode(func.begin),
bytecode_size(func.end - func.begin),
bytecodeSize(func.end - func.begin),
index(func.index),
offset_in_module(func.lineOrBytecode) {}
@ -330,50 +331,48 @@ static_assert(offsetof(TlsData, boundsCheckLimit) == sizeof(size_t),
CraneliftStaticEnvironment::CraneliftStaticEnvironment()
:
#ifdef JS_CODEGEN_X64
has_sse2(Assembler::HasSSE2()),
has_sse3(Assembler::HasSSE3()),
has_sse41(Assembler::HasSSE41()),
has_sse42(Assembler::HasSSE42()),
has_popcnt(Assembler::HasPOPCNT()),
has_avx(Assembler::HasAVX()),
has_bmi1(Assembler::HasBMI1()),
has_bmi2(Assembler::HasBMI2()),
has_lzcnt(Assembler::HasLZCNT()),
hasSse2(Assembler::HasSSE2()),
hasSse3(Assembler::HasSSE3()),
hasSse41(Assembler::HasSSE41()),
hasSse42(Assembler::HasSSE42()),
hasPopcnt(Assembler::HasPOPCNT()),
hasAvx(Assembler::HasAVX()),
hasBmi1(Assembler::HasBMI1()),
hasBmi2(Assembler::HasBMI2()),
hasLzcnt(Assembler::HasLZCNT()),
#else
has_sse2(false),
has_sse3(false),
has_sse41(false),
has_sse42(false),
has_popcnt(false),
has_avx(false),
has_bmi1(false),
has_bmi2(false),
has_lzcnt(false),
hasSse2(false),
hasSse3(false),
hasSse41(false),
hasSse42(false),
hasPopcnt(false),
hasAvx(false),
hasBmi1(false),
hasBmi2(false),
hasLzcnt(false),
#endif
#if defined(XP_WIN)
platform_is_windows(true),
platformIsWindows(true),
#else
platform_is_windows(false),
platformIsWindows(false),
#endif
ref_types_enabled(false),
static_memory_bound(0),
memory_guard_size(0),
memory_base_tls_offset(offsetof(TlsData, memoryBase)),
instance_tls_offset(offsetof(TlsData, instance)),
interrupt_tls_offset(offsetof(TlsData, interrupt)),
cx_tls_offset(offsetof(TlsData, cx)),
realm_cx_offset(JSContext::offsetOfRealm()),
realm_tls_offset(offsetof(TlsData, realm)),
realm_func_import_tls_offset(offsetof(FuncImportTls, realm)),
size_of_wasm_frame(sizeof(wasm::Frame)) {
refTypesEnabled(false),
staticMemoryBound(0),
memoryGuardSize(0),
memoryBaseTlsOffset(offsetof(TlsData, memoryBase)),
instanceTlsOffset(offsetof(TlsData, instance)),
interruptTlsOffset(offsetof(TlsData, interrupt)),
cxTlsOffset(offsetof(TlsData, cx)),
realmCxOffset(JSContext::offsetOfRealm()),
realmTlsOffset(offsetof(TlsData, realm)),
realmFuncImportTlsOffset(offsetof(FuncImportTls, realm)) {
}
// Most of BaldrMonkey's data structures refer to a "global offset" which is a
// byte offset into the `globalArea` field of the `TlsData` struct.
//
// Cranelift represents global variables with their byte offset from the "VM
// context pointer" which is the `WasmTlsReg` pointing to the `TlsData`
// struct.
// context pointer" which is the `WasmTlsReg` pointing to the `TlsData` struct.
//
// This function translates between the two.
@ -516,8 +515,8 @@ bool wasm::CraneliftCompileFunctions(const ModuleEnvironment& env,
const CodeRangeVector& codeRanges = code->codeRanges;
MOZ_ASSERT(codeRanges.length() >= inputs.length());
// Within the current batch, functions' code ranges have been added in
// the same order as the inputs.
// Within the current batch, functions' code ranges have been added in the
// same order as the inputs.
size_t firstCodeRangeIndex = codeRanges.length() - inputs.length();
for (size_t i = 0; i < inputs.length(); i++) {

View File

@ -13,8 +13,8 @@ name = "baldrdash"
# cranelift-wasm to pinned commits. If you want to update Cranelift in Gecko,
# you should update the following $TOP_LEVEL/Cargo.toml file: look for the
# revision (rev) hashes of both cranelift dependencies (codegen and wasm).
cranelift-codegen = { version = "0.62.0", default-features = false }
cranelift-wasm = "0.62.0"
cranelift-codegen = { version = "0.60.0", default-features = false }
cranelift-wasm = "0.60.0"
log = { version = "0.4.6", default-features = false, features = ["release_max_level_info"] }
env_logger = "0.6"
smallvec = "1.0"

View File

@ -57,27 +57,26 @@ struct ModuleEnvironment;
// to, but which can't be automatically provided to Rust.
struct CraneliftStaticEnvironment {
bool has_sse2;
bool has_sse3;
bool has_sse41;
bool has_sse42;
bool has_popcnt;
bool has_avx;
bool has_bmi1;
bool has_bmi2;
bool has_lzcnt;
bool platform_is_windows;
bool ref_types_enabled;
size_t static_memory_bound;
size_t memory_guard_size;
size_t memory_base_tls_offset;
size_t instance_tls_offset;
size_t interrupt_tls_offset;
size_t cx_tls_offset;
size_t realm_cx_offset;
size_t realm_tls_offset;
size_t realm_func_import_tls_offset;
size_t size_of_wasm_frame;
bool hasSse2;
bool hasSse3;
bool hasSse41;
bool hasSse42;
bool hasPopcnt;
bool hasAvx;
bool hasBmi1;
bool hasBmi2;
bool hasLzcnt;
bool platformIsWindows;
bool refTypesEnabled;
size_t staticMemoryBound;
size_t memoryGuardSize;
size_t memoryBaseTlsOffset;
size_t instanceTlsOffset;
size_t interruptTlsOffset;
size_t cxTlsOffset;
size_t realmCxOffset;
size_t realmTlsOffset;
size_t realmFuncImportTlsOffset;
// Not bindgen'd because it's inlined.
inline CraneliftStaticEnvironment();
@ -104,11 +103,11 @@ struct BD_Stackmaps;
struct CraneliftFuncCompileInput {
const uint8_t* bytecode;
size_t bytecode_size;
size_t bytecodeSize;
uint32_t index;
uint32_t offset_in_module;
// The stackmaps sink to use when compiling this function.
// The stackmaps sink to use when compiling this function
BD_Stackmaps* stackmaps;
// Not bindgen'd because it's inlined.
@ -123,9 +122,15 @@ struct CraneliftFuncCompileInput {
// handle them, with a lot of unsafe'ing.
struct CraneliftMetadataEntry {
enum Which { DirectCall, IndirectCall, Trap, SymbolicAccess } which;
uint32_t code_offset;
uint32_t module_bytecode_offset;
enum Which {
DirectCall,
IndirectCall,
Trap,
MemoryAccess,
SymbolicAccess
} which;
uint32_t codeOffset;
uint32_t moduleBytecodeOffset;
size_t extra;
};
@ -134,27 +139,27 @@ struct CraneliftMetadataEntry {
// prologue/epilogue etc.
struct CraneliftCompiledFunc {
size_t num_metadata;
size_t numMetadata;
const CraneliftMetadataEntry* metadatas;
size_t frame_pushed;
bool contains_calls;
size_t framePushed;
bool containsCalls;
// The compiled code comprises machine code, relocatable jump tables, and
// copyable read-only data, concatenated without padding. The "...Size"
// members give the sizes of the individual sections. The code starts at
// offsets 0; the other offsets can be derived from the sizes.
const uint8_t* code;
size_t code_size;
size_t jumptables_size;
size_t rodata_size;
size_t total_size;
size_t codeSize;
size_t jumptablesSize;
size_t rodataSize;
size_t totalSize;
// Relocation information for instructions that reference into the jump tables
// and read-only data segments. The relocation information is
// machine-specific.
size_t num_rodata_relocs;
const uint32_t* rodata_relocs;
size_t numRodataRelocs;
const uint32_t* rodataRelocs;
};
// Possible constant values for initializing globals.

View File

@ -236,7 +236,7 @@ impl<'a> ModuleEnvironment<'a> {
impl FuncCompileInput {
pub fn bytecode(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.bytecode, self.bytecode_size) }
unsafe { slice::from_raw_parts(self.bytecode, self.bytecodeSize) }
}
pub fn stackmaps(&self) -> Stackmaps {
@ -246,57 +246,65 @@ impl FuncCompileInput {
impl CompiledFunc {
pub fn reset(&mut self, compiled_func: &compile::CompiledFunc) {
self.num_metadata = compiled_func.metadata.len();
self.numMetadata = compiled_func.metadata.len();
self.metadatas = compiled_func.metadata.as_ptr();
self.frame_pushed = compiled_func.frame_pushed as usize;
self.contains_calls = compiled_func.contains_calls;
self.framePushed = compiled_func.frame_pushed as usize;
self.containsCalls = compiled_func.contains_calls;
self.code = compiled_func.code_buffer.as_ptr();
self.code_size = compiled_func.code_size as usize;
self.jumptables_size = compiled_func.jumptables_size as usize;
self.rodata_size = compiled_func.rodata_size as usize;
self.total_size = compiled_func.code_buffer.len();
self.codeSize = compiled_func.code_size as usize;
self.jumptablesSize = compiled_func.jumptables_size as usize;
self.rodataSize = compiled_func.rodata_size as usize;
self.totalSize = compiled_func.code_buffer.len();
self.num_rodata_relocs = compiled_func.rodata_relocs.len();
self.rodata_relocs = compiled_func.rodata_relocs.as_ptr();
self.numRodataRelocs = compiled_func.rodata_relocs.len();
self.rodataRelocs = compiled_func.rodata_relocs.as_ptr();
}
}
impl MetadataEntry {
pub fn direct_call(code_offset: CodeOffset, srcloc: SourceLoc, func_index: FuncIndex) -> Self {
pub fn direct_call(code_offset: CodeOffset, func_index: FuncIndex, srcloc: SourceLoc) -> Self {
Self {
which: CraneliftMetadataEntry_Which_DirectCall,
code_offset,
module_bytecode_offset: srcloc.bits(),
codeOffset: code_offset,
moduleBytecodeOffset: srcloc.bits(),
extra: func_index.index(),
}
}
pub fn indirect_call(ret_addr: CodeOffset, srcloc: SourceLoc) -> Self {
pub fn indirect_call(code_offset: CodeOffset, srcloc: SourceLoc) -> Self {
Self {
which: CraneliftMetadataEntry_Which_IndirectCall,
code_offset: ret_addr,
module_bytecode_offset: srcloc.bits(),
codeOffset: code_offset,
moduleBytecodeOffset: srcloc.bits(),
extra: 0,
}
}
pub fn trap(code_offset: CodeOffset, srcloc: SourceLoc, which: Trap) -> Self {
Self {
which: CraneliftMetadataEntry_Which_Trap,
code_offset,
module_bytecode_offset: srcloc.bits(),
codeOffset: code_offset,
moduleBytecodeOffset: srcloc.bits(),
extra: which as usize,
}
}
pub fn symbolic_access(
code_offset: CodeOffset,
srcloc: SourceLoc,
sym: SymbolicAddress,
) -> Self {
pub fn memory_access(code_offset: CodeOffset, srcloc: SourceLoc) -> Self {
Self {
which: CraneliftMetadataEntry_Which_MemoryAccess,
codeOffset: code_offset,
moduleBytecodeOffset: srcloc.bits(),
extra: 0,
}
}
pub fn symbolic_access(code_offset: CodeOffset, sym: SymbolicAddress) -> Self {
Self {
which: CraneliftMetadataEntry_Which_SymbolicAccess,
code_offset,
module_bytecode_offset: srcloc.bits(),
codeOffset: code_offset,
moduleBytecodeOffset: 0,
extra: sym as usize,
}
}
@ -305,7 +313,7 @@ impl MetadataEntry {
impl StaticEnvironment {
/// Returns the default calling convention on this machine.
pub fn call_conv(&self) -> isa::CallConv {
if self.platform_is_windows {
if self.platformIsWindows {
isa::CallConv::BaldrdashWindows
} else {
isa::CallConv::BaldrdashSystemV

View File

@ -22,22 +22,19 @@ use std::fmt;
use std::mem;
use cranelift_codegen::binemit::{
Addend, CodeInfo, CodeOffset, NullStackmapSink, Reloc, RelocSink, Stackmap, TrapSink,
Addend, CodeInfo, CodeOffset, NullStackmapSink, NullTrapSink, Reloc, RelocSink, Stackmap,
};
use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{
self, constant::ConstantOffset, stackslot::StackSize, ExternalName, JumpTable, SourceLoc,
TrapCode,
};
use cranelift_codegen::ir::{self, constant::ConstantOffset, stackslot::StackSize};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::CodegenResult;
use cranelift_codegen::Context;
use cranelift_wasm::{FuncIndex, FuncTranslator, ModuleTranslationState, WasmResult};
use crate::bindings;
use crate::isa::{make_isa, POINTER_SIZE};
use crate::isa::make_isa;
use crate::utils::DashResult;
use crate::wasm2clif::{init_sig, TransEnv, TRAP_THROW_REPORTED};
use crate::wasm2clif::{init_sig, TransEnv, POINTER_SIZE, TRAP_THROW_REPORTED};
// Namespace for user-defined functions.
const USER_FUNCTION_NAMESPACE: u32 = 0;
@ -161,6 +158,12 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
self.current_func.reset(frame_pushed, contains_calls);
// Generate metadata about function calls and traps now that the emitter knows where the
// Cranelift code is going to end up.
let mut metadata = mem::replace(&mut self.current_func.metadata, vec![]);
self.emit_metadata(&mut metadata, stackmaps);
mem::swap(&mut metadata, &mut self.current_func.metadata);
// TODO: If we can get a pointer into `size` pre-allocated bytes of memory, we wouldn't
// have to allocate and copy here.
// TODO(bbouvier) try to get this pointer from the C++ caller, with an unlikely callback to
@ -176,28 +179,22 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
}
{
let mut traps = Traps::new();
let mut relocs = Relocations::new(
let emit_env = &mut EmitEnv::new(
&mut self.current_func.metadata,
&mut self.current_func.rodata_relocs,
);
let mut trap_sink = NullTrapSink {};
let code_buffer = &mut self.current_func.code_buffer;
unsafe {
let code_buffer = &mut self.current_func.code_buffer;
self.context.emit_to_memory(
&*self.isa,
code_buffer.as_mut_ptr(),
&mut relocs,
&mut traps,
emit_env,
&mut trap_sink,
&mut NullStackmapSink {},
)
};
self.current_func.metadata.append(&mut traps.metadata);
}
if self.static_environ.ref_types_enabled {
self.emit_stackmaps(stackmaps);
}
self.current_func.code_size = info.code_size;
@ -207,31 +204,6 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
Ok(())
}
/// Iterate over each instruction to generate a stack map for each instruction that needs it.
///
/// Note a stackmap is associated to the address of the next instruction following the actual
/// instruction needing the stack map. This is because this is the only information
/// Spidermonkey has access to when it looks up a stack map (during stack frame iteration).
fn emit_stackmaps(&self, mut stackmaps: bindings::Stackmaps) {
let encinfo = self.isa.encoding_info();
let func = &self.context.func;
let stack_slots = &func.stack_slots;
for block in func.layout.blocks() {
let mut pending_safepoint = None;
for (offset, inst, inst_size) in func.inst_offsets(block, &encinfo) {
if let Some(stackmap) = pending_safepoint.take() {
stackmaps.add_stackmap(stack_slots, offset + inst_size, stackmap);
}
if func.dfg[inst].opcode() == ir::Opcode::Safepoint {
let args = func.dfg.inst_args(inst);
let stackmap = Stackmap::from_values(&args, func, &*self.isa);
pending_safepoint = Some(stackmap);
}
}
debug_assert!(pending_safepoint.is_none());
}
}
/// Compute the `framePushed` argument to pass to `GenerateFunctionPrologue`. This is the
/// number of frame bytes used by Cranelift, not counting the values pushed by the standard
/// prologue generated by `GenerateFunctionPrologue`.
@ -258,6 +230,246 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
// signatures which could be called.
!self.context.func.dfg.signatures.is_empty()
}
#[cfg(feature = "cranelift_x86")]
fn platform_specific_ignores_metadata(opcode: ir::Opcode) -> bool {
match opcode {
ir::Opcode::X86Sdivmodx | ir::Opcode::X86Udivmodx => true,
_ => false,
}
}
#[cfg(not(feature = "cranelift_x86"))]
fn platform_specific_ignores_metadata(_opcode: ir::Opcode) -> bool {
false
}
/// Emit metadata by scanning the compiled function before `emit_to_memory`.
///
/// - All call sites need metadata: direct, indirect, symbolic.
/// - All explicit traps must be registered.
///
/// We don't get enough callbacks through the `RelocSink` trait to generate all the metadata we
/// need.
fn emit_metadata(
&self,
metadata: &mut Vec<bindings::MetadataEntry>,
mut stackmaps: bindings::Stackmaps,
) {
let encinfo = self.isa.encoding_info();
let func = &self.context.func;
let stack_slots = &func.stack_slots;
for block in func.layout.blocks() {
let mut pending_safepoint = None;
for (offset, inst, inst_size) in func.inst_offsets(block, &encinfo) {
if let Some(stackmap) = pending_safepoint.take() {
stackmaps.add_stackmap(stack_slots, offset + inst_size, stackmap);
}
let opcode = func.dfg[inst].opcode();
match opcode {
ir::Opcode::Call => self.call_metadata(metadata, inst, offset + inst_size),
ir::Opcode::CallIndirect => {
self.indirect_call_metadata(metadata, inst, offset + inst_size)
}
ir::Opcode::Trap | ir::Opcode::Trapif | ir::Opcode::Trapff => {
self.trap_metadata(metadata, inst, offset)
}
ir::Opcode::Safepoint => {
let args = func.dfg.inst_args(inst);
let stackmap = Stackmap::from_values(&args, func, &*self.isa);
pending_safepoint = Some(stackmap);
}
ir::Opcode::Load
| ir::Opcode::LoadComplex
| ir::Opcode::Uload8
| ir::Opcode::Uload8Complex
| ir::Opcode::Sload8
| ir::Opcode::Sload8Complex
| ir::Opcode::Uload16
| ir::Opcode::Uload16Complex
| ir::Opcode::Sload16
| ir::Opcode::Sload16Complex
| ir::Opcode::Uload32
| ir::Opcode::Uload32Complex
| ir::Opcode::Sload32
| ir::Opcode::Sload32Complex
| ir::Opcode::Store
| ir::Opcode::StoreComplex
| ir::Opcode::Istore8
| ir::Opcode::Istore8Complex
| ir::Opcode::Istore16
| ir::Opcode::Istore16Complex
| ir::Opcode::Istore32
| ir::Opcode::Istore32Complex => self.memory_metadata(metadata, inst, offset),
// Instructions that are not going to trap in our use, even though their opcode
// says they can.
ir::Opcode::Spill
| ir::Opcode::Fill
| ir::Opcode::FillNop
| ir::Opcode::JumpTableEntry => {}
_ if BatchCompiler::platform_specific_ignores_metadata(opcode) => {}
_ => {
debug_assert!(!opcode.is_call(), "Missed call opcode");
debug_assert!(
!opcode.can_trap(),
"Missed trap: {}",
func.dfg.display_inst(inst, Some(self.isa.as_ref()))
);
debug_assert!(
!opcode.can_load(),
"Missed load: {}",
func.dfg.display_inst(inst, Some(self.isa.as_ref()))
);
debug_assert!(
!opcode.can_store(),
"Missed store: {}",
func.dfg.display_inst(inst, Some(self.isa.as_ref()))
);
}
}
}
assert!(pending_safepoint.is_none());
}
}
fn srcloc(&self, inst: ir::Inst) -> ir::SourceLoc {
let srcloc = self.context.func.srclocs[inst];
debug_assert!(
!srcloc.is_default(),
"No source location on {}",
self.context
.func
.dfg
.display_inst(inst, Some(self.isa.as_ref()))
);
srcloc
}
/// Emit metadata for direct call `inst`.
fn call_metadata(
&self,
metadata: &mut Vec<bindings::MetadataEntry>,
inst: ir::Inst,
ret_addr: CodeOffset,
) {
let func = &self.context.func;
// This is a direct call, so the callee should be a non-imported wasm
// function. We register both the call site *and* the target for relocation.
let callee = match func.dfg[inst] {
ir::InstructionData::Call { func_ref, .. } => &func.dfg.ext_funcs[func_ref].name,
_ => panic!("Bad format for call"),
};
let func_index = match *callee {
ir::ExternalName::User {
namespace: USER_FUNCTION_NAMESPACE,
index,
} => FuncIndex::new(index as usize),
_ => panic!("Direct call to {} unsupported", callee),
};
metadata.push(bindings::MetadataEntry::direct_call(
ret_addr,
func_index,
self.srcloc(inst),
));
}
/// Emit metadata for indirect call `inst`.
fn indirect_call_metadata(
&self,
metadata: &mut Vec<bindings::MetadataEntry>,
inst: ir::Inst,
ret_addr: CodeOffset,
) {
// A call_indirect instruction can represent either a table call or a far call to a runtime
// function. The CallSiteDesc::Kind enum does distinguish between the two, but it is not
// clear that the information is used anywhere. For now, we won't bother distinguishing
// them, and mark all calls as `Kind::Dynamic`.
//
// If we do need to make a distinction in the future, it is probably easiest to add a
// `call_far` instruction to Cranelift that encodes like an indirect call, but includes the
// callee like a direct call.
metadata.push(bindings::MetadataEntry::indirect_call(
ret_addr,
self.srcloc(inst),
));
}
fn trap_metadata(
&self,
metadata: &mut Vec<bindings::MetadataEntry>,
inst: ir::Inst,
offset: CodeOffset,
) {
let func = &self.context.func;
let (code, trap_offset) = match func.dfg[inst] {
ir::InstructionData::Trap { code, .. } => (code, 0),
ir::InstructionData::IntCondTrap { code, .. }
| ir::InstructionData::FloatCondTrap { code, .. } => {
// This instruction expands to a conditional branch over ud2 on Intel archs.
// The actual trap happens on the ud2 instruction.
(code, 2)
}
_ => panic!("Bad format for trap"),
};
// Translate the trap code into one of BaldrMonkey's trap codes.
let bd_trap = match code {
ir::TrapCode::StackOverflow => bindings::Trap::StackOverflow,
ir::TrapCode::HeapOutOfBounds => bindings::Trap::OutOfBounds,
ir::TrapCode::OutOfBounds => bindings::Trap::OutOfBounds,
ir::TrapCode::TableOutOfBounds => bindings::Trap::OutOfBounds,
ir::TrapCode::IndirectCallToNull => bindings::Trap::IndirectCallToNull,
ir::TrapCode::BadSignature => bindings::Trap::IndirectCallBadSig,
ir::TrapCode::IntegerOverflow => bindings::Trap::IntegerOverflow,
ir::TrapCode::IntegerDivisionByZero => bindings::Trap::IntegerDivideByZero,
ir::TrapCode::BadConversionToInteger => bindings::Trap::InvalidConversionToInteger,
ir::TrapCode::Interrupt => bindings::Trap::CheckInterrupt,
ir::TrapCode::UnreachableCodeReached => bindings::Trap::Unreachable,
ir::TrapCode::User(x) if x == TRAP_THROW_REPORTED => bindings::Trap::ThrowReported,
ir::TrapCode::User(_) => panic!("Uncovered trap code {}", code),
};
metadata.push(bindings::MetadataEntry::trap(
offset + trap_offset,
self.srcloc(inst),
bd_trap,
));
}
fn memory_metadata(
&self,
metadata: &mut Vec<bindings::MetadataEntry>,
inst: ir::Inst,
offset: CodeOffset,
) {
let func = &self.context.func;
let memflags = match func.dfg[inst] {
ir::InstructionData::Load { flags, .. }
| ir::InstructionData::LoadComplex { flags, .. }
| ir::InstructionData::Store { flags, .. }
| ir::InstructionData::StoreComplex { flags, .. } => flags,
_ => panic!("Bad format for memory access"),
};
// Some load/store instructions may be accessing VM data structures instead of the
// WebAssembly heap. These are tagged with `notrap` since their trapping is not part of
// the semantics, i.e. that would be a bug.
if memflags.notrap() {
return;
}
metadata.push(bindings::MetadataEntry::memory_access(
offset,
self.srcloc(inst),
));
}
}
impl<'a, 'b> fmt::Display for BatchCompiler<'a, 'b> {
@ -267,107 +479,74 @@ impl<'a, 'b> fmt::Display for BatchCompiler<'a, 'b> {
}
/// Create a Cranelift function name representing a WebAssembly function with `index`.
pub fn wasm_function_name(func: FuncIndex) -> ExternalName {
ExternalName::User {
pub fn wasm_function_name(func: FuncIndex) -> ir::ExternalName {
ir::ExternalName::User {
namespace: USER_FUNCTION_NAMESPACE,
index: func.index() as u32,
}
}
/// Create a Cranelift function name representing a builtin function.
pub fn symbolic_function_name(sym: bindings::SymbolicAddress) -> ExternalName {
ExternalName::User {
pub fn symbolic_function_name(sym: bindings::SymbolicAddress) -> ir::ExternalName {
ir::ExternalName::User {
namespace: SYMBOLIC_FUNCTION_NAMESPACE,
index: sym as u32,
}
}
struct Relocations<'a> {
/// References joined so we can implement `RelocSink`.
struct EmitEnv<'a> {
metadata: &'a mut Vec<bindings::MetadataEntry>,
rodata_relocs: &'a mut Vec<CodeOffset>,
}
impl<'a> Relocations<'a> {
fn new(
impl<'a> EmitEnv<'a> {
pub fn new(
metadata: &'a mut Vec<bindings::MetadataEntry>,
rodata_relocs: &'a mut Vec<CodeOffset>,
) -> Self {
Self {
) -> EmitEnv<'a> {
EmitEnv {
metadata,
rodata_relocs,
}
}
}
impl<'a> RelocSink for Relocations<'a> {
/// Add a relocation referencing a block at the current offset.
fn reloc_block(&mut self, _at: CodeOffset, _reloc: Reloc, _block_offset: CodeOffset) {
unimplemented!("block relocations NYI");
impl<'a> RelocSink for EmitEnv<'a> {
fn reloc_block(&mut self, _offset: CodeOffset, _reloc: Reloc, _block_offset: CodeOffset) {
unimplemented!();
}
/// Add a relocation referencing an external symbol at the current offset.
fn reloc_external(
&mut self,
at: CodeOffset,
srcloc: SourceLoc,
reloc: Reloc,
name: &ExternalName,
offset: CodeOffset,
_reloc: Reloc,
name: &ir::ExternalName,
_addend: Addend,
) {
debug_assert!(!srcloc.is_default());
// Decode the function name.
match *name {
ExternalName::User {
ir::ExternalName::User {
namespace: USER_FUNCTION_NAMESPACE,
index,
..
} => {
// A simple function call to another wasm function.
let payload_size = match reloc {
Reloc::X86CallPCRel4 => 4,
_ => panic!("unhandled call relocation"),
};
let func_index = FuncIndex::new(index as usize);
// The Spidermonkey relocation must point to the next instruction. Cranelift gives
// us the exact offset to the immediate, so fix it up by the relocation's size.
let offset = at + payload_size;
self.metadata.push(bindings::MetadataEntry::direct_call(
offset, srcloc, func_index,
));
// This is a direct function call handled by `call_metadata` above.
}
ExternalName::User {
ir::ExternalName::User {
namespace: SYMBOLIC_FUNCTION_NAMESPACE,
index,
} => {
let payload_size = match reloc {
Reloc::Abs8 => {
debug_assert_eq!(POINTER_SIZE, 8);
8
}
_ => panic!("unhandled user-space symbolic call relocation"),
};
// This is a symbolic function reference encoded by `symbolic_function_name()`.
let sym = index.into();
// The Spidermonkey relocation must point to the next instruction.
let offset = at + payload_size;
self.metadata.push(bindings::MetadataEntry::symbolic_access(
offset, srcloc, sym,
));
// The symbolic access patch address points *after* the stored pointer.
let offset = offset + POINTER_SIZE as u32;
self.metadata
.push(bindings::MetadataEntry::symbolic_access(offset, sym));
}
ExternalName::LibCall(call) => {
let payload_size = match reloc {
Reloc::Abs8 => {
debug_assert_eq!(POINTER_SIZE, 8);
8
}
_ => panic!("unhandled libcall symbolic call relocation"),
};
ir::ExternalName::LibCall(call) => {
let sym = match call {
ir::LibCall::CeilF32 => bindings::SymbolicAddress::CeilF32,
ir::LibCall::CeilF64 => bindings::SymbolicAddress::CeilF64,
@ -382,11 +561,10 @@ impl<'a> RelocSink for Relocations<'a> {
}
};
// The Spidermonkey relocation must point to the next instruction.
let offset = at + payload_size;
self.metadata.push(bindings::MetadataEntry::symbolic_access(
offset, srcloc, sym,
));
// The symbolic access patch address points *after* the stored pointer.
let offset = offset + POINTER_SIZE as u32;
self.metadata
.push(bindings::MetadataEntry::symbolic_access(offset, sym));
}
_ => {
@ -395,16 +573,10 @@ impl<'a> RelocSink for Relocations<'a> {
}
}
/// Add a relocation referencing a constant.
fn reloc_constant(&mut self, _at: CodeOffset, _reloc: Reloc, _const_offset: ConstantOffset) {
unimplemented!("constant pool relocations NYI");
}
/// Add a relocation referencing a jump table.
fn reloc_jt(&mut self, at: CodeOffset, reloc: Reloc, _jt: JumpTable) {
fn reloc_jt(&mut self, offset: CodeOffset, reloc: Reloc, _jt: ir::JumpTable) {
match reloc {
Reloc::X86PCRelRodata4 => {
self.rodata_relocs.push(at);
self.rodata_relocs.push(offset);
}
_ => {
panic!("Unhandled/unexpected reloc type");
@ -412,54 +584,12 @@ impl<'a> RelocSink for Relocations<'a> {
}
}
/// Track call sites information, giving us the return address offset.
fn add_call_site(&mut self, opcode: ir::Opcode, ret_addr: CodeOffset, srcloc: SourceLoc) {
// Direct calls need a plain relocation, so we don't need to handle them again.
if opcode == ir::Opcode::CallIndirect {
self.metadata
.push(bindings::MetadataEntry::indirect_call(ret_addr, srcloc));
}
}
}
struct Traps {
metadata: Vec<bindings::MetadataEntry>,
}
impl Traps {
fn new() -> Self {
Self {
metadata: Vec::new(),
}
}
}
impl TrapSink for Traps {
/// Add trap information for a specific offset.
fn trap(&mut self, trap_offset: CodeOffset, loc: SourceLoc, trap: TrapCode) {
// Translate the trap code into one of BaldrMonkey's trap codes.
use ir::TrapCode::*;
let bd_trap = match trap {
StackOverflow => {
// Cranelift will give us trap information for every spill/push/call. But
// Spidermonkey takes care of tracking stack overflows itself in the function
// entries, so we don't have to.
return;
}
HeapOutOfBounds | OutOfBounds | TableOutOfBounds => bindings::Trap::OutOfBounds,
IndirectCallToNull => bindings::Trap::IndirectCallToNull,
BadSignature => bindings::Trap::IndirectCallBadSig,
IntegerOverflow => bindings::Trap::IntegerOverflow,
IntegerDivisionByZero => bindings::Trap::IntegerDivideByZero,
BadConversionToInteger => bindings::Trap::InvalidConversionToInteger,
Interrupt => bindings::Trap::CheckInterrupt,
UnreachableCodeReached => bindings::Trap::Unreachable,
User(x) if x == TRAP_THROW_REPORTED => bindings::Trap::ThrowReported,
User(_) => panic!("Uncovered trap code {}", trap),
};
debug_assert!(!loc.is_default());
self.metadata
.push(bindings::MetadataEntry::trap(trap_offset, loc, bd_trap));
fn reloc_constant(
&mut self,
_offset: CodeOffset,
_reloc: Reloc,
_constant_pool_offset: ConstantOffset,
) {
unimplemented!("constant pools NYI");
}
}

View File

@ -29,11 +29,6 @@ use cranelift_codegen::settings::{self, Configurable};
use crate::bindings::StaticEnvironment;
use crate::utils::{BasicError, DashResult};
#[cfg(target_pointer_width = "64")]
pub const POINTER_SIZE: usize = 8;
#[cfg(target_pointer_width = "32")]
pub const POINTER_SIZE: usize = 4;
impl From<isa::LookupError> for BasicError {
fn from(err: isa::LookupError) -> BasicError {
BasicError::new(err.to_string())
@ -109,14 +104,16 @@ fn make_shared_flags(
sb.enable("avoid_div_traps")?;
// Cranelift needs to know how many words are pushed by `GenerateFunctionPrologue` so it can
// compute frame pointer offsets accurately. C++'s "sizeof" gives us the number of bytes, which
// we translate to the number of words, as expected by Cranelift.
debug_assert_eq!(env.size_of_wasm_frame % POINTER_SIZE, 0);
let num_words = env.size_of_wasm_frame / POINTER_SIZE;
sb.set("baldrdash_prologue_words", &num_words.to_string())?;
// compute frame pointer offsets accurately.
//
// 1. Return address (whether explicitly pushed on ARM or implicitly on x86).
// 2. TLS register.
// 3. Previous frame pointer.
//
sb.set("baldrdash_prologue_words", "3")?;
// Make sure that libcalls use the supplementary VMContext argument.
let libcall_call_conv = if env.platform_is_windows {
let libcall_call_conv = if env.platformIsWindows {
"baldrdash_windows"
} else {
"baldrdash_system_v"
@ -160,7 +157,7 @@ fn make_shared_flags(
sb.enable("use_pinned_reg_as_heap_base")?;
}
if env.ref_types_enabled {
if env.refTypesEnabled {
sb.enable("enable_safepoints")?;
}
@ -171,32 +168,32 @@ fn make_shared_flags(
fn make_isa_specific(env: &StaticEnvironment) -> DashResult<isa::Builder> {
let mut ib = isa::lookup_by_name("x86_64-unknown-unknown").map_err(BasicError::from)?;
if !env.has_sse2 {
if !env.hasSse2 {
return Err("SSE2 is mandatory for Baldrdash!".into());
}
if env.has_sse3 {
if env.hasSse3 {
ib.enable("has_sse3").map_err(BasicError::from)?;
}
if env.has_sse41 {
if env.hasSse41 {
ib.enable("has_sse41").map_err(BasicError::from)?;
}
if env.has_sse42 {
if env.hasSse42 {
ib.enable("has_sse42").map_err(BasicError::from)?;
}
if env.has_popcnt {
if env.hasPopcnt {
ib.enable("has_popcnt").map_err(BasicError::from)?;
}
if env.has_avx {
if env.hasAvx {
ib.enable("has_avx").map_err(BasicError::from)?;
}
if env.has_bmi1 {
if env.hasBmi1 {
ib.enable("has_bmi1").map_err(BasicError::from)?;
}
if env.has_bmi2 {
if env.hasBmi2 {
ib.enable("has_bmi2").map_err(BasicError::from)?;
}
if env.has_lzcnt {
if env.hasLzcnt {
ib.enable("has_lzcnt").map_err(BasicError::from)?;
}

View File

@ -36,12 +36,16 @@ use cranelift_wasm::{
use crate::bindings::{self, SymbolicAddress};
use crate::compile::{symbolic_function_name, wasm_function_name};
use crate::isa::POINTER_SIZE;
#[cfg(target_pointer_width = "64")]
pub const POINTER_TYPE: ir::Type = ir::types::I64;
const POINTER_TYPE: ir::Type = ir::types::I64;
#[cfg(target_pointer_width = "32")]
pub const POINTER_TYPE: ir::Type = ir::types::I32;
const POINTER_TYPE: ir::Type = ir::types::I32;
#[cfg(target_pointer_width = "64")]
pub const POINTER_SIZE: i32 = 8;
#[cfg(target_pointer_width = "32")]
pub const POINTER_SIZE: i32 = 4;
#[cfg(target_pointer_width = "64")]
pub const REF_TYPE: ir::Type = ir::types::R64;
@ -393,7 +397,7 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
let vmctx = self.get_vmctx_gv(pos.func);
let gv = pos.func.create_global_value(ir::GlobalValueData::IAddImm {
base: vmctx,
offset: imm64(self.static_env.instance_tls_offset),
offset: imm64(self.static_env.instanceTlsOffset),
global_type: POINTER_TYPE,
});
self.instance_gv = gv.into();
@ -413,7 +417,7 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
let vmctx = self.get_vmctx_gv(pos.func);
let gv = pos.func.create_global_value(ir::GlobalValueData::IAddImm {
base: vmctx,
offset: imm64(self.static_env.interrupt_tls_offset),
offset: imm64(self.static_env.interruptTlsOffset),
global_type: POINTER_TYPE,
});
self.interrupt_gv = gv.into();
@ -459,7 +463,7 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
.func
.create_global_value(ir::GlobalValueData::IAddImm {
base: vmctx,
offset: imm64(self.static_env.cx_tls_offset),
offset: imm64(self.static_env.cxTlsOffset),
global_type: POINTER_TYPE,
})
.into();
@ -471,7 +475,7 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
.func
.create_global_value(ir::GlobalValueData::IAddImm {
base: vmctx,
offset: imm64(self.static_env.realm_tls_offset),
offset: imm64(self.static_env.realmTlsOffset),
global_type: POINTER_TYPE,
})
.into();
@ -484,7 +488,7 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
let realm_addr_val = pos.ins().global_value(ptr, self.realm_addr.unwrap());
let realm = pos.ins().load(ptr, flags, realm_addr_val, 0);
pos.ins()
.store(flags, realm, cx, offset32(self.static_env.realm_cx_offset));
.store(flags, realm, cx, offset32(self.static_env.realmCxOffset));
}
/// Update the JSContext's realm value in preparation for making an indirect call through
@ -494,15 +498,12 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
let flags = ir::MemFlags::trusted();
let cx = pos
.ins()
.load(ptr, flags, vmctx, offset32(self.static_env.cx_tls_offset));
let realm = pos.ins().load(
ptr,
flags,
vmctx,
offset32(self.static_env.realm_tls_offset),
);
.load(ptr, flags, vmctx, offset32(self.static_env.cxTlsOffset));
let realm = pos
.ins()
.load(ptr, flags, vmctx, offset32(self.static_env.realmTlsOffset));
pos.ins()
.store(flags, realm, cx, offset32(self.static_env.realm_cx_offset));
.store(flags, realm, cx, offset32(self.static_env.realmCxOffset));
}
/// Update the JSContext's realm value in preparation for making a call to an imported
@ -517,15 +518,15 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
let flags = ir::MemFlags::trusted();
let cx = pos
.ins()
.load(ptr, flags, vmctx, offset32(self.static_env.cx_tls_offset));
.load(ptr, flags, vmctx, offset32(self.static_env.cxTlsOffset));
let realm = pos.ins().load(
ptr,
flags,
gv_addr,
offset32(self.static_env.realm_func_import_tls_offset),
offset32(self.static_env.realmFuncImportTlsOffset),
);
pos.ins()
.store(flags, realm, cx, offset32(self.static_env.realm_cx_offset));
.store(flags, realm, cx, offset32(self.static_env.realmCxOffset));
}
fn load_pinned_reg(&self, pos: &mut FuncCursor, vmctx: ir::Value) {
@ -534,7 +535,7 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
POINTER_TYPE,
ir::MemFlags::trusted(),
vmctx,
self.static_env.memory_base_tls_offset as i32,
self.static_env.memoryBaseTlsOffset as i32,
);
pos.ins().set_pinned_reg(heap_base);
}
@ -698,7 +699,7 @@ impl<'a, 'b, 'c> FuncEnvironment for TransEnv<'a, 'b, 'c> {
let vcmtx = self.get_vmctx_gv(func);
let bound = self.static_env.static_memory_bound as u64;
let bound = self.static_env.staticMemoryBound as u64;
let is_static = bound > 0;
// Get the `TlsData::memoryBase` field.
@ -717,7 +718,7 @@ impl<'a, 'b, 'c> FuncEnvironment for TransEnv<'a, 'b, 'c> {
// Get the `TlsData::boundsCheckLimit` field.
let bound_gv = func.create_global_value(ir::GlobalValueData::Load {
base: vcmtx,
offset: (POINTER_SIZE as i32).into(),
offset: POINTER_SIZE.into(),
global_type: ir::types::I32,
readonly: false,
});
@ -725,7 +726,7 @@ impl<'a, 'b, 'c> FuncEnvironment for TransEnv<'a, 'b, 'c> {
};
let min_size = (self.env.min_memory_length() as u64).into();
let offset_guard_size = (self.static_env.memory_guard_size as u64).into();
let offset_guard_size = (self.static_env.memoryGuardSize as u64).into();
Ok(func.create_heap(ir::HeapData {
base,
@ -869,12 +870,9 @@ impl<'a, 'b, 'c> FuncEnvironment for TransEnv<'a, 'b, 'c> {
// Handle external tables, set up environment.
// A function table call could redirect execution to another module with a different realm,
// so switch to this realm just in case.
let callee_vmctx = pos.ins().load(
POINTER_TYPE,
ir::MemFlags::trusted(),
entry,
POINTER_SIZE as i32,
);
let callee_vmctx =
pos.ins()
.load(POINTER_TYPE, ir::MemFlags::trusted(), entry, POINTER_SIZE);
self.switch_to_indirect_callee_realm(&mut pos, callee_vmctx);
self.load_pinned_reg(&mut pos, callee_vmctx);
@ -921,12 +919,9 @@ impl<'a, 'b, 'c> FuncEnvironment for TransEnv<'a, 'b, 'c> {
let fit_code = pos
.ins()
.load(POINTER_TYPE, ir::MemFlags::trusted(), gv_addr, 0);
let fit_tls = pos.ins().load(
POINTER_TYPE,
ir::MemFlags::trusted(),
gv_addr,
POINTER_SIZE as i32,
);
let fit_tls =
pos.ins()
.load(POINTER_TYPE, ir::MemFlags::trusted(), gv_addr, POINTER_SIZE);
// Switch to the callee's realm.
self.switch_to_import_realm(&mut pos, fit_tls, gv_addr);
@ -1272,6 +1267,6 @@ impl TableInfo {
pub fn entry_size(&self) -> i64 {
// Each entry is an `wasm::FunctionTableElem` which consists of the code pointer and a new
// VM context pointer.
(POINTER_SIZE * 2) as i64
i64::from(POINTER_SIZE) * 2
}
}

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"2826e4035b7d2cffaeb4b093fc3e33475fdd80c2cfae57cbdf1513918808477b","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"23a5c42d477197a947122e662068e681bb9ed31041c0b668c3267c3fce15d39e","src/map.rs":"a3b7f64cae7ec9c2a8038def315bcf90e8751552b1bc1c20b62fbb8c763866c4","src/node.rs":"28f7edd979f7b9712bc4ab30b0d2a1b8ad5485a4b1e8c09f3dcaf501b9b5ccd1","src/path.rs":"a86ee1c882c173e8af96fd53a416a0fb485dd3f045ac590ef313a9d9ecf90f56","src/pool.rs":"f6337b5417f7772e6878a160c1a40629199ff09997bdff18eb2a0ba770158600","src/set.rs":"281eb8b5ead1ffd395946464d881f9bb0e7fb61092aed701d72d2314b5f80994"},"package":null}
{"files":{"Cargo.toml":"0590650ee92ca1c67e40e0c18f6861f588bac5240e96049af89a290d28b6c774","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"23a5c42d477197a947122e662068e681bb9ed31041c0b668c3267c3fce15d39e","src/map.rs":"a3b7f64cae7ec9c2a8038def315bcf90e8751552b1bc1c20b62fbb8c763866c4","src/node.rs":"28f7edd979f7b9712bc4ab30b0d2a1b8ad5485a4b1e8c09f3dcaf501b9b5ccd1","src/path.rs":"a86ee1c882c173e8af96fd53a416a0fb485dd3f045ac590ef313a9d9ecf90f56","src/pool.rs":"f6337b5417f7772e6878a160c1a40629199ff09997bdff18eb2a0ba770158600","src/set.rs":"281eb8b5ead1ffd395946464d881f9bb0e7fb61092aed701d72d2314b5f80994"},"package":null}

View File

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-bforest"
version = "0.62.0"
version = "0.60.0"
description = "A forest of B+-trees"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://docs.rs/cranelift-bforest"
@ -12,7 +12,7 @@ keywords = ["btree", "forest", "set", "map"]
edition = "2018"
[dependencies]
cranelift-entity = { path = "../entity", version = "0.62.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.60.0", default-features = false }
[badges]
maintenance = { status = "experimental" }

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"f5c824a81cf3c40bded1bfcc325c15e6109724c3efbbc822d4c5782dbefe9f12","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"84a4b7e3301e3249716958a7aa4ea5ba8c6172e3c02f57ee3880504c4433ff19","src/cdsl/cpu_modes.rs":"996e45b374cfe85ac47c8c86c4459fe4c04b3158102b4c63b6ee434d5eed6a9e","src/cdsl/encodings.rs":"d884a564815a03c23369bcf31d13b122ae5ba84d0c80eda9312f0c0a829bf794","src/cdsl/formats.rs":"63e638305aa3ca6dd409ddf0e5e9605eeac1cc2631103e42fc6cbc87703d9b63","src/cdsl/instructions.rs":"41e1a230501de3f0da3960d8aa375c8bcd60ec62ede94ad61806816acbd8009a","src/cdsl/isa.rs":"ccabd6848b69eb069c10db61c7e7f86080777495714bb53d03e663c40541be94","src/cdsl/mod.rs":"0aa827923bf4c45e5ee2359573bd863e00f474acd532739f49dcd74a27553882","src/cdsl/operands.rs":"1c3411504de9c83112ff48e0ff1cfbb2e4ba5a9a15c1716f411ef31a4df59899","src/cdsl/recipes.rs":"80b7cd87332229b569e38086ceee8d557e679b9a32ad2e50bdb15c33337c3418","src/cdsl/regs.rs":"466a42a43355fc7623fe5d8e8d330622207a3af6a80cb9367bc0f06e224c9ee0","src/cdsl/settings.rs":"e6fd9a31925743b93b11f09c9c8271bab6aa2430aa053a2601957b4487df7d77","src/cdsl/type_inference.rs":"1efca8a095ffc899b7527bda6b9d9378c73d7283f8dceaa4819e8af599f8be21","src/cdsl/types.rs":"ff764c9e9c29a05677bff6164e7bc25a0c32655052d77ae580536abba8b1713b","src/cdsl/typevar.rs":"c7e80a3c52755f2d91fb5c3d18413b7c97777bd54d1aece8a17d1bbd9944c46a","src/cdsl/xform.rs":"55da0c3f2403147b535ab6ae5d69c623fbe839edecf2a3af1de84420cd58402d","src/default_map.rs":"101bb0282a124f9c921f6bd095f529e8753621450d783c3273b0b0394c2c5c03","src/error.rs":"e9b11b2feb2d867b94c8810fdc5a6c4e0d9131604a0bfa5340ff2639a55100b4","src/gen_binemit.rs":"515e243420b30d1e01f8ea630282d9b6d78a715e1951f3f20392e19a48164442","src/gen_encodings.rs":"f00cded6b68a9b48c9e3cd39a8b6f0ba136f4062c8f8666109158a72c62c3ed1","src/gen_inst.rs":"b275053977c0239211c1df35253154ba4dce2519f506088e71104de37d3db862","src/gen_legalizer.rs":"ea229ab9393cc5ba2242f626e74c624ea59314535e74b26602dafb8e96481a72","src/gen_registers.rs":"a904119ed803c9de24dedd15149a65337ffc168bb1d63df53d7fdebfb5f4b158","src/gen_settings.rs":"f3cc3d31f6cc898f30606caf084f0de220db2d3b1b5e5e4145fa7c9a9a1597e2","src/gen_types.rs":"f6c090e1646a43bf2fe81ae0a7029cc6f7dc6d43285368f56d86c35a21c469a6","src/isa/arm32/mod.rs":"8e09ec1b3caf2d22dce8517b37c356047bfce9a6dea712467d867ed05c4bedaf","src/isa/arm64/mod.rs":"b01f030925d3f2af37d7df1b4a800eb7f0d24f74a46e9154fd8b6752643eb2d5","src/isa/mod.rs":"136141f99f217ba42b9e3f7f47238ab19cc974bb3bef2e2df7f7b5a683989d46","src/isa/riscv/encodings.rs":"8abb1968d917588bc5fc5f5be6dd66bdec23ac456ba65f8138237c8e891e843c","src/isa/riscv/mod.rs":"a7b461a30bbfbc1e3b33645422ff40d5b1761c30cb5d4a8aa12e9a3b7f7aee51","src/isa/riscv/recipes.rs":"fd5a7418fa0d47cdf1b823b31553f1549c03e160ffffac9e22d611185774367e","src/isa/x86/encodings.rs":"3ebb8e638df80db4deb554bf79f4d74f1bb581b55daa631f3cb419f0fa29b7f5","src/isa/x86/instructions.rs":"3c1482583b031d2663b31ee8784f0cb61c8abef995afc7c8f8a6e7be010a2ba8","src/isa/x86/legalize.rs":"5b654c2410ab384cfb20815f1114af76a7967472a45b8d60232ddce9d9921682","src/isa/x86/mod.rs":"65953f998ff3fc3b333167e9979fc0f15f976b51ad75272ac19dcaad0981b371","src/isa/x86/opcodes.rs":"b54d7cd8590ef8cd866b169d50c291fa8b33d4de7c69bcb237e1c879873d08e0","src/isa/x86/recipes.rs":"2621264954661fd474024fc6a8f01aed9cc800aaab8273aede3bd36657851c40","src/isa/x86/registers.rs":"4be0a45d8acd465c31746b7976124025b06b453e3f6d587f93efb5af0e12b1a8","src/isa/x86/settings.rs":"49abb46533b3a5415cd033e0a98b5c9561e231f2dd9510d587dc69b204bb6706","src/lib.rs":"2491b0e74078914cb89d1778fa8174daf723fe76aaf7fed18741237d68f6df32","src/shared/entities.rs":"90f774a70e1c2a2e9a553c07a5e80e0fe54cf127434bd83e67274bba4e1a19ba","src/shared/formats.rs":"89ed4074f748637adf56b93ba952e398c45d43e6326d01676885939e3fe8bc4a","src/shared/immediates.rs":"e4a57657f6af9853794804eb41c01204a2c13a632f44f55d90e156a4b98c5f65","src/shared/instructions.rs":"f2b15219f21087dbe30198d40dc426decbe64decadd7efd9bf9f5e26272c72ef","src/shared/legalize.rs":"bc9c3292446c1d338df1c4ce19f3ac5482cfe582a04a5a1e82fc9aaa6aef25ea","src/shared/mod.rs":"c219625990bf15507ac1077b349ce20e5312d4e4707426183676d469e78792b7","src/shared/settings.rs":"2e791624b4e85f9e8adcee7169fe445ca8bcdc97d1da92c92ae9576988ab0470","src/shared/types.rs":"4702df132f4b5d70cc9411ec5221ba0b1bd4479252274e0223ae57b6d0331247","src/srcgen.rs":"dcfc159c8599270f17e6a978c4be255abca51556b5ef0da497faec4a4a1e62ce","src/unique_table.rs":"31aa54330ca4786af772d32e8cb6158b6504b88fa93fe177bf0c6cbe545a8d35"},"package":null}
{"files":{"Cargo.toml":"f4c0e8f821dc23fac1e439ff0505fbfb4dd02cf631b629f1d5552b2a9f6dd3a4","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"84a4b7e3301e3249716958a7aa4ea5ba8c6172e3c02f57ee3880504c4433ff19","src/cdsl/cpu_modes.rs":"996e45b374cfe85ac47c8c86c4459fe4c04b3158102b4c63b6ee434d5eed6a9e","src/cdsl/encodings.rs":"d884a564815a03c23369bcf31d13b122ae5ba84d0c80eda9312f0c0a829bf794","src/cdsl/formats.rs":"63e638305aa3ca6dd409ddf0e5e9605eeac1cc2631103e42fc6cbc87703d9b63","src/cdsl/instructions.rs":"41e1a230501de3f0da3960d8aa375c8bcd60ec62ede94ad61806816acbd8009a","src/cdsl/isa.rs":"ccabd6848b69eb069c10db61c7e7f86080777495714bb53d03e663c40541be94","src/cdsl/mod.rs":"0aa827923bf4c45e5ee2359573bd863e00f474acd532739f49dcd74a27553882","src/cdsl/operands.rs":"1c3411504de9c83112ff48e0ff1cfbb2e4ba5a9a15c1716f411ef31a4df59899","src/cdsl/recipes.rs":"80b7cd87332229b569e38086ceee8d557e679b9a32ad2e50bdb15c33337c3418","src/cdsl/regs.rs":"466a42a43355fc7623fe5d8e8d330622207a3af6a80cb9367bc0f06e224c9ee0","src/cdsl/settings.rs":"e6fd9a31925743b93b11f09c9c8271bab6aa2430aa053a2601957b4487df7d77","src/cdsl/type_inference.rs":"1efca8a095ffc899b7527bda6b9d9378c73d7283f8dceaa4819e8af599f8be21","src/cdsl/types.rs":"ff764c9e9c29a05677bff6164e7bc25a0c32655052d77ae580536abba8b1713b","src/cdsl/typevar.rs":"c7e80a3c52755f2d91fb5c3d18413b7c97777bd54d1aece8a17d1bbd9944c46a","src/cdsl/xform.rs":"55da0c3f2403147b535ab6ae5d69c623fbe839edecf2a3af1de84420cd58402d","src/default_map.rs":"101bb0282a124f9c921f6bd095f529e8753621450d783c3273b0b0394c2c5c03","src/error.rs":"e9b11b2feb2d867b94c8810fdc5a6c4e0d9131604a0bfa5340ff2639a55100b4","src/gen_binemit.rs":"515e243420b30d1e01f8ea630282d9b6d78a715e1951f3f20392e19a48164442","src/gen_encodings.rs":"f00cded6b68a9b48c9e3cd39a8b6f0ba136f4062c8f8666109158a72c62c3ed1","src/gen_inst.rs":"b275053977c0239211c1df35253154ba4dce2519f506088e71104de37d3db862","src/gen_legalizer.rs":"ea229ab9393cc5ba2242f626e74c624ea59314535e74b26602dafb8e96481a72","src/gen_registers.rs":"a904119ed803c9de24dedd15149a65337ffc168bb1d63df53d7fdebfb5f4b158","src/gen_settings.rs":"f3cc3d31f6cc898f30606caf084f0de220db2d3b1b5e5e4145fa7c9a9a1597e2","src/gen_types.rs":"f6c090e1646a43bf2fe81ae0a7029cc6f7dc6d43285368f56d86c35a21c469a6","src/isa/arm32/mod.rs":"8e09ec1b3caf2d22dce8517b37c356047bfce9a6dea712467d867ed05c4bedaf","src/isa/arm64/mod.rs":"b01f030925d3f2af37d7df1b4a800eb7f0d24f74a46e9154fd8b6752643eb2d5","src/isa/mod.rs":"136141f99f217ba42b9e3f7f47238ab19cc974bb3bef2e2df7f7b5a683989d46","src/isa/riscv/encodings.rs":"8abb1968d917588bc5fc5f5be6dd66bdec23ac456ba65f8138237c8e891e843c","src/isa/riscv/mod.rs":"a7b461a30bbfbc1e3b33645422ff40d5b1761c30cb5d4a8aa12e9a3b7f7aee51","src/isa/riscv/recipes.rs":"c9424cffed54cc4d328879a4613b9f6a2c2b7cde7e6e17b4fccd5f661aaf92f2","src/isa/x86/encodings.rs":"cbf3e7834c7d29de8f3faa4c70dad23167ae22d02fba5d7d518779b34535393d","src/isa/x86/instructions.rs":"3c1482583b031d2663b31ee8784f0cb61c8abef995afc7c8f8a6e7be010a2ba8","src/isa/x86/legalize.rs":"5b654c2410ab384cfb20815f1114af76a7967472a45b8d60232ddce9d9921682","src/isa/x86/mod.rs":"65953f998ff3fc3b333167e9979fc0f15f976b51ad75272ac19dcaad0981b371","src/isa/x86/opcodes.rs":"ddebd2f5a14d9d7e37be0a6dc7467d098a2df554ac1deb41c97e5d16273ed353","src/isa/x86/recipes.rs":"a90c48625cc0c60ae67436e333d330967d4ac67498685c62601b47c94c721e8d","src/isa/x86/registers.rs":"4be0a45d8acd465c31746b7976124025b06b453e3f6d587f93efb5af0e12b1a8","src/isa/x86/settings.rs":"49abb46533b3a5415cd033e0a98b5c9561e231f2dd9510d587dc69b204bb6706","src/lib.rs":"2491b0e74078914cb89d1778fa8174daf723fe76aaf7fed18741237d68f6df32","src/shared/entities.rs":"90f774a70e1c2a2e9a553c07a5e80e0fe54cf127434bd83e67274bba4e1a19ba","src/shared/formats.rs":"89ed4074f748637adf56b93ba952e398c45d43e6326d01676885939e3fe8bc4a","src/shared/immediates.rs":"e4a57657f6af9853794804eb41c01204a2c13a632f44f55d90e156a4b98c5f65","src/shared/instructions.rs":"4528650c9b26bd687458d407f46f3c6531cd6f31249024c94e4bf0b4205d7137","src/shared/legalize.rs":"bc9c3292446c1d338df1c4ce19f3ac5482cfe582a04a5a1e82fc9aaa6aef25ea","src/shared/mod.rs":"c219625990bf15507ac1077b349ce20e5312d4e4707426183676d469e78792b7","src/shared/settings.rs":"2e791624b4e85f9e8adcee7169fe445ca8bcdc97d1da92c92ae9576988ab0470","src/shared/types.rs":"4702df132f4b5d70cc9411ec5221ba0b1bd4479252274e0223ae57b6d0331247","src/srcgen.rs":"dcfc159c8599270f17e6a978c4be255abca51556b5ef0da497faec4a4a1e62ce","src/unique_table.rs":"31aa54330ca4786af772d32e8cb6158b6504b88fa93fe177bf0c6cbe545a8d35"},"package":null}

View File

@ -1,7 +1,7 @@
[package]
name = "cranelift-codegen-meta"
authors = ["The Cranelift Project Developers"]
version = "0.62.0"
version = "0.60.0"
description = "Metaprogram for cranelift-codegen code generator library"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/wasmtime"
@ -9,8 +9,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
cranelift-codegen-shared = { path = "../shared", version = "0.62.0" }
cranelift-entity = { path = "../../entity", version = "0.62.0" }
cranelift-codegen-shared = { path = "../shared", version = "0.60.0" }
cranelift-entity = { path = "../../entity", version = "0.60.0" }
[badges]
maintenance = { status = "experimental" }

View File

@ -205,8 +205,7 @@ pub(crate) fn define(shared_defs: &SharedDefinitions, regs: &IsaRegs) -> RecipeG
recipes.push(EncodingRecipeBuilder::new("UJcall", &formats.call, 4).emit(
r#"
sink.reloc_external(func.srclocs[inst],
Reloc::RiscvCall,
sink.reloc_external(Reloc::RiscvCall,
&func.dfg.ext_funcs[func_ref].name,
0);
// rd=%x1 is the standard link register.

View File

@ -156,7 +156,7 @@ impl PerCpuModeEncodings {
self.enc64(inst.bind(I32), template.infer_rex());
// I64 on x86_64: REX.W set; REX.RXB determined at runtime from registers.
self.enc64(inst.bind(I64), template.rex().w());
self.enc64(inst.bind(I64), template.infer_rex().w());
}
/// Adds I32/I64 encodings as appropriate for a typed instruction.
@ -192,7 +192,7 @@ impl PerCpuModeEncodings {
self.enc64(inst.bind(B32), template.infer_rex());
// B64 on x86_64: REX.W set; REX.RXB determined at runtime from registers.
self.enc64(inst.bind(B64), template.rex().w());
self.enc64(inst.bind(B64), template.infer_rex().w());
}
/// Add encodings for `inst.i32` to X86_32.
@ -313,10 +313,10 @@ impl PerCpuModeEncodings {
}
/// Add two encodings for `inst`:
/// - X86_32, no REX prefix, since this is not valid in 32-bit mode.
/// - X86_32, dynamically infer the REX prefix.
/// - X86_64, dynamically infer the REX prefix.
fn enc_both_inferred(&mut self, inst: impl Clone + Into<InstSpec>, template: Template) {
self.enc32(inst.clone(), template.clone());
self.enc32(inst.clone(), template.infer_rex());
self.enc64(inst, template.infer_rex());
}
fn enc_both_inferred_maybe_isap(
@ -325,7 +325,7 @@ impl PerCpuModeEncodings {
template: Template,
isap: Option<SettingPredicateNumber>,
) {
self.enc32_maybe_isap(inst.clone(), template.clone(), isap);
self.enc32_maybe_isap(inst.clone(), template.infer_rex(), isap);
self.enc64_maybe_isap(inst, template.infer_rex(), isap);
}
@ -1600,9 +1600,6 @@ fn define_simd(
let regspill = shared.by_name("regspill");
let sadd_sat = shared.by_name("sadd_sat");
let scalar_to_vector = shared.by_name("scalar_to_vector");
let sload8x8 = shared.by_name("sload8x8");
let sload16x4 = shared.by_name("sload16x4");
let sload32x2 = shared.by_name("sload32x2");
let spill = shared.by_name("spill");
let sqrt = shared.by_name("sqrt");
let sshr_imm = shared.by_name("sshr_imm");
@ -1610,9 +1607,6 @@ fn define_simd(
let store = shared.by_name("store");
let store_complex = shared.by_name("store_complex");
let uadd_sat = shared.by_name("uadd_sat");
let uload8x8 = shared.by_name("uload8x8");
let uload16x4 = shared.by_name("uload16x4");
let uload32x2 = shared.by_name("uload32x2");
let ushr_imm = shared.by_name("ushr_imm");
let usub_sat = shared.by_name("usub_sat");
let vconst = shared.by_name("vconst");
@ -1866,8 +1860,8 @@ fn define_simd(
// Store
let bound_store = store.bind(vector(ty, sse_vector_size)).bind(Any);
e.enc_both_inferred(bound_store.clone(), rec_fst.opcodes(&MOVUPS_STORE));
e.enc_both_inferred(bound_store.clone(), rec_fstDisp8.opcodes(&MOVUPS_STORE));
e.enc_both_inferred(bound_store, rec_fstDisp32.opcodes(&MOVUPS_STORE));
e.enc_both(bound_store.clone(), rec_fstDisp8.opcodes(&MOVUPS_STORE));
e.enc_both(bound_store, rec_fstDisp32.opcodes(&MOVUPS_STORE));
// Store complex
let bound_store_complex = store_complex.bind(vector(ty, sse_vector_size));
@ -1887,8 +1881,8 @@ fn define_simd(
// Load
let bound_load = load.bind(vector(ty, sse_vector_size)).bind(Any);
e.enc_both_inferred(bound_load.clone(), rec_fld.opcodes(&MOVUPS_LOAD));
e.enc_both_inferred(bound_load.clone(), rec_fldDisp8.opcodes(&MOVUPS_LOAD));
e.enc_both_inferred(bound_load, rec_fldDisp32.opcodes(&MOVUPS_LOAD));
e.enc_both(bound_load.clone(), rec_fldDisp8.opcodes(&MOVUPS_LOAD));
e.enc_both(bound_load, rec_fldDisp32.opcodes(&MOVUPS_LOAD));
// Load complex
let bound_load_complex = load_complex.bind(vector(ty, sse_vector_size));
@ -1932,24 +1926,6 @@ fn define_simd(
e.enc_32_64_rec(bound_copy_nop, rec_stacknull, 0);
}
// SIMD load extend
for (inst, opcodes) in &[
(uload8x8, &PMOVZXBW),
(uload16x4, &PMOVZXWD),
(uload32x2, &PMOVZXDQ),
(sload8x8, &PMOVSXBW),
(sload16x4, &PMOVSXWD),
(sload32x2, &PMOVSXDQ),
] {
let isap = Some(use_sse41_simd);
for recipe in &[rec_fld, rec_fldDisp8, rec_fldDisp32] {
let inst = *inst;
let template = recipe.opcodes(*opcodes);
e.enc_both_inferred_maybe_isap(inst.clone().bind(I32), template.clone(), isap);
e.enc64_maybe_isap(inst.bind(I64), template.infer_rex(), isap);
}
}
// SIMD integer addition
for (ty, opcodes) in &[(I8, &PADDB), (I16, &PADDW), (I32, &PADDD), (I64, &PADDQ)] {
let iadd = iadd.bind(vector(*ty, sse_vector_size));

View File

@ -417,30 +417,6 @@ pub static PMINUD: [u8; 4] = [0x66, 0x0f, 0x38, 0x3b];
/// xmm1 (SSE4.1).
pub static PMINUW: [u8; 4] = [0x66, 0x0f, 0x38, 0x3a];
/// Sign extend 8 packed 8-bit integers in the low 8 bytes of xmm2/m64 to 8 packed 16-bit
/// integers in xmm1 (SSE4.1).
pub static PMOVSXBW: [u8; 4] = [0x66, 0x0f, 0x38, 0x20];
/// Sign extend 4 packed 16-bit integers in the low 8 bytes of xmm2/m64 to 4 packed 32-bit
/// integers in xmm1 (SSE4.1).
pub static PMOVSXWD: [u8; 4] = [0x66, 0x0f, 0x38, 0x23];
/// Sign extend 2 packed 32-bit integers in the low 8 bytes of xmm2/m64 to 2 packed 64-bit
/// integers in xmm1.
pub static PMOVSXDQ: [u8; 4] = [0x66, 0x0f, 0x38, 0x25];
/// Zero extend 8 packed 8-bit integers in the low 8 bytes of xmm2/m64 to 8 packed 16-bit
/// integers in xmm1 (SSE4.1).
pub static PMOVZXBW: [u8; 4] = [0x66, 0x0f, 0x38, 0x30];
/// Zero extend 4 packed 16-bit integers in the low 8 bytes of xmm2/m64 to 4 packed 32-bit
/// integers in xmm1 (SSE4.1).
pub static PMOVZXWD: [u8; 4] = [0x66, 0x0f, 0x38, 0x33];
/// Zero extend 2 packed 32-bit integers in the low 8 bytes of xmm2/m64 to 2 packed 64-bit
/// integers in xmm1.
pub static PMOVZXDQ: [u8; 4] = [0x66, 0x0f, 0x38, 0x35];
/// Multiply the packed signed word integers in xmm1 and xmm2/m128, and store the low 16 bits of
/// the results in xmm1 (SSE2).
pub static PMULLW: [u8; 3] = [0x66, 0x0f, 0xd5];

View File

@ -335,7 +335,6 @@ impl<'builder> Template<'builder> {
("Rex".to_string() + opcode, self.op_bytes.len() as u64 + 1)
}
RecipePrefixKind::InferRex => {
assert_eq!(self.w_bit, 0, "A REX.W bit always requires a REX prefix; avoid using `infer_rex().w()` and use `rex().w()` instead.");
// Hook up the right function for inferred compute_size().
assert!(
self.inferred_rex_compute_size.is_some(),
@ -1009,7 +1008,7 @@ pub(crate) fn define<'shared>(
))
.emit(
r#"
{{PUT_OP}}(bits, rex2(out_reg0, in_reg0), sink);
{{PUT_OP}}(bits, rex2(in_reg0, out_reg0), sink);
modrm_rr(out_reg0, in_reg0, sink); // note the flipped register in the ModR/M byte
let imm:i64 = lane.into();
sink.put1(imm as u8);
@ -1258,8 +1257,7 @@ pub(crate) fn define<'shared>(
.emit(
r#"
{{PUT_OP}}(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(func.srclocs[inst],
Reloc::Abs4,
sink.reloc_external(Reloc::Abs4,
&func.dfg.ext_funcs[func_ref].name,
0);
sink.put4(0);
@ -1274,8 +1272,7 @@ pub(crate) fn define<'shared>(
.emit(
r#"
{{PUT_OP}}(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(func.srclocs[inst],
Reloc::Abs8,
sink.reloc_external(Reloc::Abs8,
&func.dfg.ext_funcs[func_ref].name,
0);
sink.put8(0);
@ -1290,8 +1287,7 @@ pub(crate) fn define<'shared>(
.emit(
r#"
{{PUT_OP}}(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(func.srclocs[inst],
Reloc::Abs4,
sink.reloc_external(Reloc::Abs4,
&func.dfg.ext_funcs[func_ref].name,
0);
// Write the immediate as `!0` for the benefit of BaldrMonkey.
@ -1307,8 +1303,7 @@ pub(crate) fn define<'shared>(
.emit(
r#"
{{PUT_OP}}(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(func.srclocs[inst],
Reloc::Abs8,
sink.reloc_external(Reloc::Abs8,
&func.dfg.ext_funcs[func_ref].name,
0);
// Write the immediate as `!0` for the benefit of BaldrMonkey.
@ -1328,8 +1323,7 @@ pub(crate) fn define<'shared>(
modrm_riprel(out_reg0, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(func.srclocs[inst],
Reloc::X86PCRel4,
sink.reloc_external(Reloc::X86PCRel4,
&func.dfg.ext_funcs[func_ref].name,
-4);
sink.put4(0);
@ -1348,8 +1342,7 @@ pub(crate) fn define<'shared>(
modrm_riprel(out_reg0, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(func.srclocs[inst],
Reloc::X86GOTPCRel4,
sink.reloc_external(Reloc::X86GOTPCRel4,
&func.dfg.ext_funcs[func_ref].name,
-4);
sink.put4(0);
@ -1364,8 +1357,7 @@ pub(crate) fn define<'shared>(
.emit(
r#"
{{PUT_OP}}(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(func.srclocs[inst],
Reloc::Abs4,
sink.reloc_external(Reloc::Abs4,
&func.global_values[global_value].symbol_name(),
0);
sink.put4(0);
@ -1380,8 +1372,7 @@ pub(crate) fn define<'shared>(
.emit(
r#"
{{PUT_OP}}(bits | (out_reg0 & 7), rex1(out_reg0), sink);
sink.reloc_external(func.srclocs[inst],
Reloc::Abs8,
sink.reloc_external(Reloc::Abs8,
&func.global_values[global_value].symbol_name(),
0);
sink.put8(0);
@ -1399,8 +1390,7 @@ pub(crate) fn define<'shared>(
modrm_rm(5, out_reg0, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(func.srclocs[inst],
Reloc::X86PCRel4,
sink.reloc_external(Reloc::X86PCRel4,
&func.global_values[global_value].symbol_name(),
-4);
sink.put4(0);
@ -1418,8 +1408,7 @@ pub(crate) fn define<'shared>(
modrm_rm(5, out_reg0, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(func.srclocs[inst],
Reloc::X86GOTPCRel4,
sink.reloc_external(Reloc::X86GOTPCRel4,
&func.global_values[global_value].symbol_name(),
-4);
sink.put4(0);
@ -1615,7 +1604,7 @@ pub(crate) fn define<'shared>(
);
// XX /r register-indirect store with 8-bit offset of FPR.
recipes.add_template_inferred(
recipes.add_template_recipe(
EncodingRecipeBuilder::new("fstDisp8", &formats.store, 2)
.operands_in(vec![fpr, gpr])
.inst_predicate(has_small_offset)
@ -1637,7 +1626,6 @@ pub(crate) fn define<'shared>(
sink.put1(offset as u8);
"#,
),
"size_plus_maybe_sib_inreg1_plus_rex_prefix_for_inreg0_inreg1",
);
// XX /r register-indirect store with 32-bit offset.
@ -1694,7 +1682,7 @@ pub(crate) fn define<'shared>(
);
// XX /r register-indirect store with 32-bit offset of FPR.
recipes.add_template_inferred(
recipes.add_template_recipe(
EncodingRecipeBuilder::new("fstDisp32", &formats.store, 5)
.operands_in(vec![fpr, gpr])
.clobbers_flags(false)
@ -1715,7 +1703,6 @@ pub(crate) fn define<'shared>(
sink.put4(offset as u32);
"#,
),
"size_plus_maybe_sib_inreg1_plus_rex_prefix_for_inreg0_inreg1",
);
}
@ -2100,7 +2087,7 @@ pub(crate) fn define<'shared>(
);
// XX /r float load with 8-bit offset.
recipes.add_template_inferred(
recipes.add_template_recipe(
EncodingRecipeBuilder::new("fldDisp8", &formats.load, 2)
.operands_in(vec![gpr])
.operands_out(vec![fpr])
@ -2123,7 +2110,6 @@ pub(crate) fn define<'shared>(
sink.put1(offset as u8);
"#,
),
"size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0",
);
let has_big_offset =
@ -2156,7 +2142,7 @@ pub(crate) fn define<'shared>(
);
// XX /r float load with 32-bit offset.
recipes.add_template_inferred(
recipes.add_template_recipe(
EncodingRecipeBuilder::new("fldDisp32", &formats.load, 5)
.operands_in(vec![gpr])
.operands_out(vec![fpr])
@ -2179,7 +2165,6 @@ pub(crate) fn define<'shared>(
sink.put4(offset as u32);
"#,
),
"size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0",
);
}
@ -2412,12 +2397,10 @@ pub(crate) fn define<'shared>(
{{PUT_OP}}(bits, BASE_REX, sink);
// The addend adjusts for the difference between the end of the
// instruction and the beginning of the immediate field.
sink.reloc_external(func.srclocs[inst],
Reloc::X86CallPCRel4,
sink.reloc_external(Reloc::X86CallPCRel4,
&func.dfg.ext_funcs[func_ref].name,
-4);
sink.put4(0);
sink.add_call_site(opcode, func.srclocs[inst]);
"#,
),
);
@ -2427,12 +2410,10 @@ pub(crate) fn define<'shared>(
r#"
sink.trap(TrapCode::StackOverflow, func.srclocs[inst]);
{{PUT_OP}}(bits, BASE_REX, sink);
sink.reloc_external(func.srclocs[inst],
Reloc::X86CallPLTRel4,
sink.reloc_external(Reloc::X86CallPLTRel4,
&func.dfg.ext_funcs[func_ref].name,
-4);
sink.put4(0);
sink.add_call_site(opcode, func.srclocs[inst]);
"#,
),
);
@ -2445,7 +2426,6 @@ pub(crate) fn define<'shared>(
sink.trap(TrapCode::StackOverflow, func.srclocs[inst]);
{{PUT_OP}}(bits, rex1(in_reg0), sink);
modrm_r_bits(in_reg0, bits, sink);
sink.add_call_site(opcode, func.srclocs[inst]);
"#,
),
);
@ -3335,8 +3315,7 @@ pub(crate) fn define<'shared>(
const LEA: u8 = 0x8d;
sink.put1(LEA); // lea
modrm_riprel(0b111/*out_reg0*/, sink); // 0x3d
sink.reloc_external(func.srclocs[inst],
Reloc::ElfX86_64TlsGd,
sink.reloc_external(Reloc::ElfX86_64TlsGd,
&func.global_values[global_value].symbol_name(),
-4);
sink.put4(0);
@ -3346,8 +3325,7 @@ pub(crate) fn define<'shared>(
sink.put1(0x66); // data16
sink.put1(0b01001000); // rex.w
sink.put1(0xe8); // call
sink.reloc_external(func.srclocs[inst],
Reloc::X86CallPLTRel4,
sink.reloc_external(Reloc::X86CallPLTRel4,
&ExternalName::LibCall(LibCall::ElfTlsGetAddr),
-4);
sink.put4(0);
@ -3368,8 +3346,7 @@ pub(crate) fn define<'shared>(
sink.put1(0x48); // rex
sink.put1(0x8b); // mov
modrm_riprel(0b111/*out_reg0*/, sink); // 0x3d
sink.reloc_external(func.srclocs[inst],
Reloc::MachOX86_64Tlv,
sink.reloc_external(Reloc::MachOX86_64Tlv,
&func.global_values[global_value].symbol_name(),
-4);
sink.put4(0);

View File

@ -1147,123 +1147,6 @@ pub(crate) fn define(
.can_store(true),
);
let I16x8 = &TypeVar::new(
"I16x8",
"A SIMD vector with exactly 8 lanes of 16-bit values",
TypeSetBuilder::new()
.ints(16..16)
.simd_lanes(8..8)
.includes_scalars(false)
.build(),
);
let a = &Operand::new("a", I16x8).with_doc("Value loaded");
ig.push(
Inst::new(
"uload8x8",
r#"
Load an 8x8 vector (64 bits) from memory at ``p + Offset`` and zero-extend into an i16x8
vector.
"#,
&formats.load,
)
.operands_in(vec![MemFlags, p, Offset])
.operands_out(vec![a])
.can_load(true),
);
ig.push(
Inst::new(
"sload8x8",
r#"
Load an 8x8 vector (64 bits) from memory at ``p + Offset`` and sign-extend into an i16x8
vector.
"#,
&formats.load,
)
.operands_in(vec![MemFlags, p, Offset])
.operands_out(vec![a])
.can_load(true),
);
let I32x4 = &TypeVar::new(
"I32x4",
"A SIMD vector with exactly 4 lanes of 32-bit values",
TypeSetBuilder::new()
.ints(32..32)
.simd_lanes(4..4)
.includes_scalars(false)
.build(),
);
let a = &Operand::new("a", I32x4).with_doc("Value loaded");
ig.push(
Inst::new(
"uload16x4",
r#"
Load an 16x4 vector (64 bits) from memory at ``p + Offset`` and zero-extend into an i32x4
vector.
"#,
&formats.load,
)
.operands_in(vec![MemFlags, p, Offset])
.operands_out(vec![a])
.can_load(true),
);
ig.push(
Inst::new(
"sload16x4",
r#"
Load a 16x4 vector (64 bits) from memory at ``p + Offset`` and sign-extend into an i32x4
vector.
"#,
&formats.load,
)
.operands_in(vec![MemFlags, p, Offset])
.operands_out(vec![a])
.can_load(true),
);
let I64x2 = &TypeVar::new(
"I64x2",
"A SIMD vector with exactly 2 lanes of 64-bit values",
TypeSetBuilder::new()
.ints(64..64)
.simd_lanes(2..2)
.includes_scalars(false)
.build(),
);
let a = &Operand::new("a", I64x2).with_doc("Value loaded");
ig.push(
Inst::new(
"uload32x2",
r#"
Load an 32x2 vector (64 bits) from memory at ``p + Offset`` and zero-extend into an i64x2
vector.
"#,
&formats.load,
)
.operands_in(vec![MemFlags, p, Offset])
.operands_out(vec![a])
.can_load(true),
);
ig.push(
Inst::new(
"sload32x2",
r#"
Load a 32x2 vector (64 bits) from memory at ``p + Offset`` and sign-extend into an i64x2
vector.
"#,
&formats.load,
)
.operands_in(vec![MemFlags, p, Offset])
.operands_out(vec![a])
.can_load(true),
);
let x = &Operand::new("x", Mem).with_doc("Value to be stored");
let a = &Operand::new("a", Mem).with_doc("Value loaded");
let Offset =

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"35beecf644d966a002873be06c3f087756b39bb9d206aa465d957df96b6d4304","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"a410bc2f5dcbde499c0cd299c2620bc8111e3c5b3fccdd9e2d85caf3c24fdab3","src/condcodes.rs":"b8d433b2217b86e172d25b6c65a3ce0cc8ca221062cad1b28b0c78d2159fbda9","src/constant_hash.rs":"ffc619f45aad62c6fdcb83553a05879691a72e9a0103375b2d6cc12d52cf72d0","src/constants.rs":"fed03a10a6316e06aa174091db6e7d1fbb5f73c82c31193012ec5ab52f1c603a","src/isa/mod.rs":"428a950eca14acbe783899ccb1aecf15027f8cbe205578308ebde203d10535f3","src/isa/x86/encoding_bits.rs":"7e013fb804b13f9f83a0d517c6f5105856938d08ad378cc44a6fe6a59adef270","src/isa/x86/mod.rs":"01ef4e4d7437f938badbe2137892183c1ac684da0f68a5bec7e06aad34f43b9b","src/lib.rs":"91f26f998f11fb9cb74d2ec171424e29badd417beef023674850ace57149c656"},"package":null}
{"files":{"Cargo.toml":"9b4276e6dafee6a97061c404a8418bf6bd683dd6cf4ae1997eafa990d2f20d6b","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"a410bc2f5dcbde499c0cd299c2620bc8111e3c5b3fccdd9e2d85caf3c24fdab3","src/condcodes.rs":"b8d433b2217b86e172d25b6c65a3ce0cc8ca221062cad1b28b0c78d2159fbda9","src/constant_hash.rs":"ffc619f45aad62c6fdcb83553a05879691a72e9a0103375b2d6cc12d52cf72d0","src/constants.rs":"fed03a10a6316e06aa174091db6e7d1fbb5f73c82c31193012ec5ab52f1c603a","src/isa/mod.rs":"428a950eca14acbe783899ccb1aecf15027f8cbe205578308ebde203d10535f3","src/isa/x86/encoding_bits.rs":"7e013fb804b13f9f83a0d517c6f5105856938d08ad378cc44a6fe6a59adef270","src/isa/x86/mod.rs":"01ef4e4d7437f938badbe2137892183c1ac684da0f68a5bec7e06aad34f43b9b","src/lib.rs":"91f26f998f11fb9cb74d2ec171424e29badd417beef023674850ace57149c656"},"package":null}

View File

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-codegen-shared"
version = "0.62.0"
version = "0.60.0"
description = "For code shared between cranelift-codegen-meta and cranelift-codegen"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/wasmtime"

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-codegen"
version = "0.62.0"
version = "0.60.0"
description = "Low-level code generator library"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://docs.rs/cranelift-codegen"
@ -13,9 +13,9 @@ build = "build.rs"
edition = "2018"
[dependencies]
cranelift-codegen-shared = { path = "./shared", version = "0.62.0" }
cranelift-entity = { path = "../entity", version = "0.62.0" }
cranelift-bforest = { path = "../bforest", version = "0.62.0" }
cranelift-codegen-shared = { path = "./shared", version = "0.60.0" }
cranelift-entity = { path = "../entity", version = "0.60.0" }
cranelift-bforest = { path = "../bforest", version = "0.60.0" }
hashbrown = { version = "0.7", optional = true }
target-lexicon = "0.10"
log = { version = "0.4.6", default-features = false }
@ -30,7 +30,7 @@ byteorder = { version = "1.3.2", default-features = false }
# accomodated in `tests`.
[build-dependencies]
cranelift-codegen-meta = { path = "meta", version = "0.62.0" }
cranelift-codegen-meta = { path = "meta", version = "0.60.0" }
[features]
default = ["std", "unwind"]

View File

@ -16,7 +16,7 @@
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
use crate::binemit::stackmap::Stackmap;
use crate::ir::entities::Value;
use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, Opcode, SourceLoc, TrapCode};
use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, SourceLoc, TrapCode};
use crate::isa::TargetIsa;
use core::ptr::write_unaligned;
@ -78,24 +78,13 @@ pub trait RelocSink {
fn reloc_block(&mut self, _: CodeOffset, _: Reloc, _: CodeOffset);
/// Add a relocation referencing an external symbol at the current offset.
fn reloc_external(
&mut self,
_: CodeOffset,
_: SourceLoc,
_: Reloc,
_: &ExternalName,
_: Addend,
);
fn reloc_external(&mut self, _: CodeOffset, _: Reloc, _: &ExternalName, _: Addend);
/// Add a relocation referencing a constant.
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset);
/// Add a relocation referencing a jump table.
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable);
/// Track a call site whose return address is the given CodeOffset, for the given opcode. Does
/// nothing in general, only useful for certain embedders (SpiderMonkey).
fn add_call_site(&mut self, _: Opcode, _: CodeOffset, _: SourceLoc) {}
}
/// A trait for receiving trap codes and offsets.
@ -143,15 +132,9 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
self.relocs.reloc_block(ofs, rel, block_offset);
}
fn reloc_external(
&mut self,
srcloc: SourceLoc,
rel: Reloc,
name: &ExternalName,
addend: Addend,
) {
fn reloc_external(&mut self, rel: Reloc, name: &ExternalName, addend: Addend) {
let ofs = self.offset();
self.relocs.reloc_external(ofs, srcloc, rel, name, addend);
self.relocs.reloc_external(ofs, rel, name, addend);
}
fn reloc_constant(&mut self, rel: Reloc, constant_offset: ConstantOffset) {
@ -187,15 +170,6 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
let stackmap = Stackmap::from_values(&val_list, func, isa);
self.stackmaps.add_stackmap(ofs, stackmap);
}
fn add_call_site(&mut self, opcode: Opcode, loc: SourceLoc) {
debug_assert!(
opcode.is_call(),
"adding call site info for a non-call instruction."
);
let ret_addr = self.offset();
self.relocs.add_call_site(opcode, ret_addr, loc);
}
}
/// A `RelocSink` implementation that does nothing, which is convenient when
@ -203,18 +177,10 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
pub struct NullRelocSink {}
impl RelocSink for NullRelocSink {
fn reloc_block(&mut self, _: CodeOffset, _: Reloc, _: CodeOffset) {}
fn reloc_external(
&mut self,
_: CodeOffset,
_: SourceLoc,
_: Reloc,
_: &ExternalName,
_: Addend,
) {
}
fn reloc_block(&mut self, _: u32, _: Reloc, _: u32) {}
fn reloc_external(&mut self, _: u32, _: Reloc, _: &ExternalName, _: i64) {}
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset) {}
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable) {}
fn reloc_jt(&mut self, _: u32, _: Reloc, _: JumpTable) {}
}
/// A `TrapSink` implementation that does nothing, which is convenient when

View File

@ -16,9 +16,7 @@ pub use self::relaxation::relax_branches;
pub use self::shrink::shrink_instructions;
pub use self::stackmap::Stackmap;
use crate::ir::entities::Value;
use crate::ir::{
ConstantOffset, ExternalName, Function, Inst, JumpTable, Opcode, SourceLoc, TrapCode,
};
use crate::ir::{ConstantOffset, ExternalName, Function, Inst, JumpTable, SourceLoc, TrapCode};
use crate::isa::TargetIsa;
pub use crate::regalloc::RegDiversions;
use core::fmt;
@ -142,7 +140,7 @@ pub trait CodeSink {
fn reloc_block(&mut self, _: Reloc, _: CodeOffset);
/// Add a relocation referencing an external symbol plus the addend at the current offset.
fn reloc_external(&mut self, _: SourceLoc, _: Reloc, _: &ExternalName, _: Addend);
fn reloc_external(&mut self, _: Reloc, _: &ExternalName, _: Addend);
/// Add a relocation referencing a constant.
fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset);
@ -164,11 +162,6 @@ pub trait CodeSink {
/// Add a stackmap at the current code offset.
fn add_stackmap(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa);
/// Add a call site for a call with the given opcode, returning at the current offset.
fn add_call_site(&mut self, _: Opcode, _: SourceLoc) {
// Default implementation doesn't need to do anything.
}
}
/// Type of the frame unwind information.

View File

@ -74,12 +74,6 @@ mod riscv;
#[cfg(feature = "x86")]
mod x86;
#[cfg(all(feature = "x86", feature = "unwind"))]
/// Expose the register-mapping functionality necessary for exception handling, debug, etc.
pub mod fde {
pub use super::x86::map_reg;
}
#[cfg(feature = "arm32")]
mod arm32;

View File

@ -74,15 +74,10 @@ fn evex2(rm: RegUnit, reg: RegUnit) -> u8 {
0x00 | r_ | (b << 1) | (x << 2) | (r << 3)
}
/// Determines whether a REX prefix should be emitted. A REX byte always has 0100 in bits 7:4; bits
/// 3:0 correspond to WRXB. W allows certain instructions to declare a 64-bit operand size; because
/// [needs_rex] is only used by [infer_rex] and we prevent [infer_rex] from using [w] in
/// [Template::build], we do not need to check again whether [w] forces an inferred REX prefix--it
/// always does and should be encoded like `.rex().w()`. The RXB are extension of ModR/M or SIB
/// fields; see section 2.2.1.2 in the Intel Software Development Manual.
/// Determines whether a REX prefix should be emitted.
#[inline]
fn needs_rex(rex: u8) -> bool {
rex != BASE_REX
fn needs_rex(bits: u16, rex: u8) -> bool {
rex != BASE_REX || EncodingBits::from(bits).rex_w() == 1
}
// Emit a REX prefix.
@ -112,7 +107,7 @@ fn put_rexop1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
/// Emit a single-byte opcode with inferred REX prefix.
fn put_dynrexop1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x0f00, 0, "Invalid encoding bits for DynRexOp1*");
if needs_rex(rex) {
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(bits as u8);
@ -141,7 +136,7 @@ fn put_dynrexop2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
0x0400,
"Invalid encoding bits for DynRexOp2*"
);
if needs_rex(rex) {
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(0x0f);
@ -195,7 +190,7 @@ fn put_dynrexmp2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
);
let enc = EncodingBits::from(bits);
sink.put1(PREFIX[(enc.pp() - 1) as usize]);
if needs_rex(rex) {
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(0x0f);
@ -233,7 +228,7 @@ fn put_dynrexmp3<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
);
let enc = EncodingBits::from(bits);
sink.put1(PREFIX[(enc.pp() - 1) as usize]);
if needs_rex(rex) {
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(0x0f);

View File

@ -16,6 +16,8 @@ use crate::isa::{self, TargetIsa};
use crate::predicates;
use crate::regalloc::RegDiversions;
use cranelift_codegen_shared::isa::x86::EncodingBits;
include!(concat!(env!("OUT_DIR"), "/encoding-x86.rs"));
include!(concat!(env!("OUT_DIR"), "/legalize-x86.rs"));
@ -130,28 +132,13 @@ fn size_plus_maybe_sib_or_offset_inreg1_plus_rex_prefix_for_inreg0_inreg1(
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg)
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg)
|| test_input(1, inst, divert, func, is_extended_reg);
size_plus_maybe_sib_or_offset_for_inreg_1(sizing, enc, inst, divert, func)
+ if needs_rex { 1 } else { 0 }
}
/// Calculates the size while inferring if the first and second input registers (inreg0, inreg1)
/// require a dynamic REX prefix and if the second input register (inreg1) requires a SIB.
fn size_plus_maybe_sib_inreg1_plus_rex_prefix_for_inreg0_inreg1(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg)
|| test_input(1, inst, divert, func, is_extended_reg);
size_plus_maybe_sib_for_inreg_1(sizing, enc, inst, divert, func) + if needs_rex { 1 } else { 0 }
}
/// Calculates the size while inferring if the first input register (inreg0) and first output
/// register (outreg0) require a dynamic REX and if the first input register (inreg0) requires a
/// SIB or offset.
@ -162,29 +149,13 @@ fn size_plus_maybe_sib_or_offset_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0(
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg)
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg)
|| test_result(0, inst, divert, func, is_extended_reg);
size_plus_maybe_sib_or_offset_for_inreg_0(sizing, enc, inst, divert, func)
+ if needs_rex { 1 } else { 0 }
}
/// Calculates the size while inferring if the first input register (inreg0) and first output
/// register (outreg0) require a dynamic REX and if the first input register (inreg0) requires a
/// SIB.
fn size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg)
|| test_result(0, inst, divert, func, is_extended_reg);
size_plus_maybe_sib_for_inreg_0(sizing, enc, inst, divert, func) + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, for use with one input reg.
///
/// A REX prefix is known to be emitted if either:
@ -192,39 +163,39 @@ fn size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0(
/// 2. Registers are used that require REX.R or REX.B bits for encoding.
fn size_with_inferred_rex_for_inreg0(
sizing: &RecipeSizing,
_enc: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg);
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, based on the second operand.
fn size_with_inferred_rex_for_inreg1(
sizing: &RecipeSizing,
_enc: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(1, inst, divert, func, is_extended_reg);
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(1, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, based on the third operand.
fn size_with_inferred_rex_for_inreg2(
sizing: &RecipeSizing,
_: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(2, inst, divert, func, is_extended_reg);
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(2, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
@ -235,13 +206,13 @@ fn size_with_inferred_rex_for_inreg2(
/// 2. Registers are used that require REX.R or REX.B bits for encoding.
fn size_with_inferred_rex_for_inreg0_inreg1(
sizing: &RecipeSizing,
_enc: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg)
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg)
|| test_input(1, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
@ -250,13 +221,13 @@ fn size_with_inferred_rex_for_inreg0_inreg1(
/// input register and a single output register.
fn size_with_inferred_rex_for_inreg0_outreg0(
sizing: &RecipeSizing,
_enc: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(0, inst, divert, func, is_extended_reg)
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg)
|| test_result(0, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
@ -264,13 +235,13 @@ fn size_with_inferred_rex_for_inreg0_outreg0(
/// Infers whether a dynamic REX prefix will be emitted, based on a single output register.
fn size_with_inferred_rex_for_outreg0(
sizing: &RecipeSizing,
_enc: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_result(0, inst, divert, func, is_extended_reg);
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_result(0, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
@ -279,13 +250,13 @@ fn size_with_inferred_rex_for_outreg0(
/// CMOV uses 3 inputs, with the REX is inferred from reg1 and reg2.
fn size_with_inferred_rex_for_cmov(
sizing: &RecipeSizing,
_enc: Encoding,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
// No need to check for REX.W in `needs_rex` because `infer_rex().w()` is not allowed.
let needs_rex = test_input(1, inst, divert, func, is_extended_reg)
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(1, inst, divert, func, is_extended_reg)
|| test_input(2, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}

View File

@ -10,7 +10,6 @@ use gimli::write::{
FrameDescriptionEntry, FrameTable, Result, Writer,
};
use gimli::{Encoding, Format, LittleEndian, Register, X86_64};
use thiserror::Error;
pub type FDERelocEntry = (FrameUnwindOffset, Reloc);
@ -75,15 +74,8 @@ fn return_address_reg(isa: &dyn TargetIsa) -> Register {
X86_64::RA
}
/// Map Cranelift registers to their corresponding Gimli registers.
pub fn map_reg(
isa: &dyn TargetIsa,
reg: RegUnit,
) -> core::result::Result<Register, RegisterMappingError> {
if isa.name() != "x86" || isa.pointer_bits() != 64 {
return Err(RegisterMappingError::UnsupportedArchitecture);
}
fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Register {
assert!(isa.name() == "x86" && isa.pointer_bits() == 64);
// Mapping from https://github.com/bytecodealliance/cranelift/pull/902 by @iximeow
const X86_GP_REG_MAP: [gimli::Register; 16] = [
X86_64::RAX,
@ -121,32 +113,21 @@ pub fn map_reg(
X86_64::XMM14,
X86_64::XMM15,
];
let reg_info = isa.register_info();
let bank = reg_info
.bank_containing_regunit(reg)
.ok_or_else(|| RegisterMappingError::MissingBank)?;
let bank = reg_info.bank_containing_regunit(reg).unwrap();
match bank.name {
"IntRegs" => {
// x86 GP registers have a weird mapping to DWARF registers, so we use a
// lookup table.
Ok(X86_GP_REG_MAP[(reg - bank.first_unit) as usize])
X86_GP_REG_MAP[(reg - bank.first_unit) as usize]
}
"FloatRegs" => X86_XMM_REG_MAP[(reg - bank.first_unit) as usize],
_ => {
panic!("unsupported register bank: {}", bank.name);
}
"FloatRegs" => Ok(X86_XMM_REG_MAP[(reg - bank.first_unit) as usize]),
_ => Err(RegisterMappingError::UnsupportedRegisterBank(bank.name)),
}
}
#[derive(Error, Debug)]
pub enum RegisterMappingError {
#[error("unable to find bank for register info")]
MissingBank,
#[error("register mapping is currently only implemented for x86_64")]
UnsupportedArchitecture,
#[error("unsupported register bank: {0}")]
UnsupportedRegisterBank(&'static str),
}
fn to_cfi(
isa: &dyn TargetIsa,
change: &FrameLayoutChange,
@ -155,7 +136,7 @@ fn to_cfi(
) -> Option<CallFrameInstruction> {
Some(match change {
FrameLayoutChange::CallFrameAddressAt { reg, offset } => {
let mapped = map_reg(isa, *reg).expect("a register mapping from cranelift to gimli");
let mapped = map_reg(isa, *reg);
let offset = (*offset) as i32;
if mapped != *cfa_def_reg && offset != *cfa_def_offset {
*cfa_def_reg = mapped;
@ -174,7 +155,7 @@ fn to_cfi(
FrameLayoutChange::RegAt { reg, cfa_offset } => {
assert!(cfa_offset % -8 == 0);
let cfa_offset = *cfa_offset as i32;
let mapped = map_reg(isa, *reg).expect("a register mapping from cranelift to gimli");
let mapped = map_reg(isa, *reg);
CallFrameInstruction::Offset(mapped, cfa_offset)
}
FrameLayoutChange::ReturnAddressAt { cfa_offset } => {

View File

@ -10,9 +10,6 @@ pub mod settings;
#[cfg(feature = "unwind")]
mod unwind;
#[cfg(feature = "unwind")]
pub use fde::map_reg;
use super::super::settings as shared_settings;
#[cfg(feature = "testing_hooks")]
use crate::binemit::CodeSink;

View File

@ -902,8 +902,8 @@ fn branch_order(pos: &mut FuncCursor, cfg: &mut ControlFlowGraph, block: Block,
_ => return,
};
let cond_args = cond_inst_args.as_slice(&pos.func.dfg.value_lists).to_vec();
let term_args = term_inst_args.as_slice(&pos.func.dfg.value_lists).to_vec();
let cond_args = { cond_inst_args.as_slice(&pos.func.dfg.value_lists).to_vec() };
let term_args = { term_inst_args.as_slice(&pos.func.dfg.value_lists).to_vec() };
match kind {
BranchOrderKind::BrnzToBrz(cond_arg) => {

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"b598da46e55aafd9d05c0d90bda8819edcb593141d1992c21b44639910d12981","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"69d539b72460c0aba1d30e0b72efb0c29d61558574d751c784794e14abf41352","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"f6d738a46f1dca8b0c82a5910d86cd572a3585ab7ef9f73dac96962529069190","src/list.rs":"4bf609eb7cc7c000c18da746596d5fcc67eece3f919ee2d76e19f6ac371640d1","src/map.rs":"546b36be4cbbd2423bacbed69cbe114c63538c3f635e15284ab8e4223e717705","src/packed_option.rs":"dccb3dd6fc87eba0101de56417f21cab67a4394831df9fa41e3bbddb70cdf694","src/primary.rs":"30d5e2ab8427fd2b2c29da395812766049e3c40845cc887af3ee233dba91a063","src/set.rs":"b040054b8baa0599e64df9ee841640688e2a73b6eabbdc5a4f15334412db052a","src/sparse.rs":"536e31fdcf64450526f5e5b85e97406c26b998bc7e0d8161b6b449c24265449f"},"package":null}
{"files":{"Cargo.toml":"0a7762f80abf6e2dbe73b7020fdbea138e6dab10809b15dc6a08249d58c3c422","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"69d539b72460c0aba1d30e0b72efb0c29d61558574d751c784794e14abf41352","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"f6d738a46f1dca8b0c82a5910d86cd572a3585ab7ef9f73dac96962529069190","src/list.rs":"4bf609eb7cc7c000c18da746596d5fcc67eece3f919ee2d76e19f6ac371640d1","src/map.rs":"546b36be4cbbd2423bacbed69cbe114c63538c3f635e15284ab8e4223e717705","src/packed_option.rs":"dccb3dd6fc87eba0101de56417f21cab67a4394831df9fa41e3bbddb70cdf694","src/primary.rs":"30d5e2ab8427fd2b2c29da395812766049e3c40845cc887af3ee233dba91a063","src/set.rs":"b040054b8baa0599e64df9ee841640688e2a73b6eabbdc5a4f15334412db052a","src/sparse.rs":"536e31fdcf64450526f5e5b85e97406c26b998bc7e0d8161b6b449c24265449f"},"package":null}

View File

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-entity"
version = "0.62.0"
version = "0.60.0"
description = "Data structures using entity references as mapping keys"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://docs.rs/cranelift-entity"

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"0773fd1bf0dd78967f755538d2c62279eae3ce4bc442e2a21b953d9ab039d0b9","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"579d9821aec76570b774c572e2ae0c1b8bc78f112ef2a83027051217f6bb31e4","src/lib.rs":"5197f467d1625ee2b117a168f4b1886b4b69d4250faea6618360a5adc70b4e0c","src/ssa.rs":"0cd620e4d9fbc5e249b782d8d22e8d112a70c0700b5dd312c92ef47a5c5280da","src/switch.rs":"6b7f97799e251f2b4ae6a9892fb911375e2dc9faa5d53ff93ba08988141f1f5b","src/variable.rs":"399437bd7d2ac11a7a748bad7dd1f6dac58824d374ec318f36367a9d077cc225"},"package":null}
{"files":{"Cargo.toml":"569136ca3728e465c6ea2d3e5d40226a6518566e17293d2e6f6194593ae3d783","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"af0955c23a5462cc6d4a94c61ac1af5b7546a3d560e91d448452fe5c454d5da6","src/lib.rs":"5197f467d1625ee2b117a168f4b1886b4b69d4250faea6618360a5adc70b4e0c","src/ssa.rs":"339421ee9427ee7017939ca53b7b357f82af79c8a929aeb26fb6165b95f47e93","src/switch.rs":"6b7f97799e251f2b4ae6a9892fb911375e2dc9faa5d53ff93ba08988141f1f5b","src/variable.rs":"399437bd7d2ac11a7a748bad7dd1f6dac58824d374ec318f36367a9d077cc225"},"package":null}

View File

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-frontend"
version = "0.62.0"
version = "0.60.0"
description = "Cranelift IR builder helper"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://docs.rs/cranelift-frontend"
@ -11,7 +11,7 @@ readme = "README.md"
edition = "2018"
[dependencies]
cranelift-codegen = { path = "../codegen", version = "0.62.0", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.60.0", default-features = false }
target-lexicon = "0.10"
log = { version = "0.4.6", default-features = false }
hashbrown = { version = "0.7", optional = true }

View File

@ -1229,53 +1229,6 @@ block0:
);
}
#[test]
fn undef_vector_vars() {
let mut sig = Signature::new(CallConv::SystemV);
sig.returns.push(AbiParam::new(I8X16));
sig.returns.push(AbiParam::new(B8X16));
sig.returns.push(AbiParam::new(F32X4));
let mut fn_ctx = FunctionBuilderContext::new();
let mut func = Function::with_name_signature(ExternalName::testcase("sample"), sig);
{
let mut builder = FunctionBuilder::new(&mut func, &mut fn_ctx);
let block0 = builder.create_block();
let a = Variable::new(0);
let b = Variable::new(1);
let c = Variable::new(2);
builder.declare_var(a, I8X16);
builder.declare_var(b, B8X16);
builder.declare_var(c, F32X4);
builder.switch_to_block(block0);
let a = builder.use_var(a);
let b = builder.use_var(b);
let c = builder.use_var(c);
builder.ins().return_(&[a, b, c]);
builder.seal_all_blocks();
builder.finalize();
}
assert_eq!(
func.display(None).to_string(),
"function %sample() -> i8x16, b8x16, f32x4 system_v {
block0:
v5 = f32const 0.0
v6 = splat.f32x4 v5
v2 -> v6
v4 = vconst.b8x16 0x00
v1 -> v4
v3 = vconst.i8x16 0x00
v0 -> v3
return v0, v1, v2
}
"
);
}
#[test]
fn test_greatest_divisible_power_of_two() {
assert_eq!(64, greatest_divisible_power_of_two(64));

View File

@ -9,7 +9,6 @@
use crate::Variable;
use alloc::vec::Vec;
use core::convert::TryInto;
use core::mem;
use cranelift_codegen::cursor::{Cursor, FuncCursor};
use cranelift_codegen::entity::SecondaryMap;
@ -186,13 +185,10 @@ fn emit_zero(ty: Type, mut cur: FuncCursor) -> Value {
cur.ins().null(ty)
} else if ty.is_vector() {
let scalar_ty = ty.lane_type();
if scalar_ty.is_int() || scalar_ty.is_bool() {
let zero = cur.func.dfg.constants.insert(
core::iter::repeat(0)
.take(ty.bytes().try_into().unwrap())
.collect(),
);
cur.ins().vconst(ty, zero)
if scalar_ty.is_int() {
cur.ins().iconst(ty, 0)
} else if scalar_ty.is_bool() {
cur.ins().bconst(ty, false)
} else if scalar_ty == F32 {
let scalar = cur.ins().f32const(Ieee32::with_bits(0));
cur.ins().splat(ty, scalar)

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"e927f5353af12ad52c5eb349db2a62c275ec49616c7109553258d367d8118ee1","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"cce724251d4abc08c6492e1e25c138ab5a0d11e9ac90bc573652b18e034f56ed","src/code_translator.rs":"575fe0fe427dcc5405faf449924fe457cd8a938f86d6fd853e1536427a096dfd","src/environ/dummy.rs":"49bce7a8eb9f21a61c12db537b51ab6bdb3d0e1eb6253084268256d96cae68a5","src/environ/mod.rs":"b6f33f619090ff497b4e22150d77a290f259716374ac2e377b73c47cd1dafe85","src/environ/spec.rs":"3a1543f99bff340c7f6bbe3f7cb8e8ec829e4139957f3c578d5b03e29df50f9e","src/func_translator.rs":"a165063eafedbb8e6b632996f747eeb49a3d6f8a70cab6d741abfc4fd9af892d","src/lib.rs":"05b9994c062faf2065046d1e4d7caffb26823816f367d77ede6918e24fcfa6b0","src/module_translator.rs":"bcdf5a84226b726a73f4be0acb0318ca89c82584460101378e73021d85bd4485","src/sections_translator.rs":"8c4c24308332c63d16fcf19693a7ecff2239e73b4752b0d3830b273fabcee9f1","src/state/func_state.rs":"b114522784984a7cc26a3549c7c17f842885e1232254de81d938f9d155f95aa6","src/state/mod.rs":"20014cb93615467b4d20321b52f67f66040417efcaa739a4804093bb559eed19","src/state/module_state.rs":"2f299b043deb806b48583fe54bbb46708f7d8a1454b7be0eb285568064e5a7f9","src/translation_utils.rs":"cd3ab5f994e02d49baa47148b66599d37f8156cd657b61ae68aefefa32a9d806","tests/wasm_testsuite.rs":"730304f139371e5ef3fd913ec271fc4db181869b447c6ed26c54313b5c31495c"},"package":null}
{"files":{"Cargo.toml":"fbabc7ff07bf6a0c7c4ea8b723ae2eb86ee78ce51aa37c41201b98d0064b7db2","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"cce724251d4abc08c6492e1e25c138ab5a0d11e9ac90bc573652b18e034f56ed","src/code_translator.rs":"984f937da07895b5a34106d78762c937879174c9c88105addbc68799211f6a34","src/environ/dummy.rs":"49bce7a8eb9f21a61c12db537b51ab6bdb3d0e1eb6253084268256d96cae68a5","src/environ/mod.rs":"b6f33f619090ff497b4e22150d77a290f259716374ac2e377b73c47cd1dafe85","src/environ/spec.rs":"3a1543f99bff340c7f6bbe3f7cb8e8ec829e4139957f3c578d5b03e29df50f9e","src/func_translator.rs":"a165063eafedbb8e6b632996f747eeb49a3d6f8a70cab6d741abfc4fd9af892d","src/lib.rs":"05b9994c062faf2065046d1e4d7caffb26823816f367d77ede6918e24fcfa6b0","src/module_translator.rs":"bcdf5a84226b726a73f4be0acb0318ca89c82584460101378e73021d85bd4485","src/sections_translator.rs":"8c4c24308332c63d16fcf19693a7ecff2239e73b4752b0d3830b273fabcee9f1","src/state/func_state.rs":"b114522784984a7cc26a3549c7c17f842885e1232254de81d938f9d155f95aa6","src/state/mod.rs":"20014cb93615467b4d20321b52f67f66040417efcaa739a4804093bb559eed19","src/state/module_state.rs":"2f299b043deb806b48583fe54bbb46708f7d8a1454b7be0eb285568064e5a7f9","src/translation_utils.rs":"cd3ab5f994e02d49baa47148b66599d37f8156cd657b61ae68aefefa32a9d806","tests/wasm_testsuite.rs":"730304f139371e5ef3fd913ec271fc4db181869b447c6ed26c54313b5c31495c"},"package":null}

View File

@ -1,9 +1,8 @@
[package]
name = "cranelift-wasm"
version = "0.62.0"
version = "0.60.0"
authors = ["The Cranelift Project Developers"]
description = "Translator from WebAssembly to Cranelift IR"
documentation = "https://docs.rs/cranelift-wasm"
repository = "https://github.com/bytecodealliance/wasmtime"
license = "Apache-2.0 WITH LLVM-exception"
categories = ["no-std", "wasm"]
@ -13,9 +12,9 @@ edition = "2018"
[dependencies]
wasmparser = { version = "0.51.0", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.62.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.62.0" }
cranelift-frontend = { path = "../frontend", version = "0.62.0", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.60.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.60.0" }
cranelift-frontend = { path = "../frontend", version = "0.60.0", default-features = false }
hashbrown = { version = "0.7", optional = true }
log = { version = "0.4.6", default-features = false }
serde = { version = "1.0.94", features = ["derive"], optional = true }

View File

@ -32,7 +32,6 @@ use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureInd
use crate::wasm_unsupported;
use core::{i32, u32};
use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
use cranelift_codegen::ir::immediates::Offset32;
use cranelift_codegen::ir::types::*;
use cranelift_codegen::ir::{
self, ConstantData, InstBuilder, JumpTableData, MemFlags, Value, ValueLabel,
@ -652,48 +651,6 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
} => {
translate_load(*offset, ir::Opcode::Load, I8X16, builder, state, environ)?;
}
Operator::I16x8Load8x8S {
memarg: MemoryImmediate { flags: _, offset },
} => {
let (flags, base, offset) = prepare_load(*offset, builder, state, environ)?;
let loaded = builder.ins().sload8x8(flags, base, offset);
state.push1(loaded);
}
Operator::I16x8Load8x8U {
memarg: MemoryImmediate { flags: _, offset },
} => {
let (flags, base, offset) = prepare_load(*offset, builder, state, environ)?;
let loaded = builder.ins().uload8x8(flags, base, offset);
state.push1(loaded);
}
Operator::I32x4Load16x4S {
memarg: MemoryImmediate { flags: _, offset },
} => {
let (flags, base, offset) = prepare_load(*offset, builder, state, environ)?;
let loaded = builder.ins().sload16x4(flags, base, offset);
state.push1(loaded);
}
Operator::I32x4Load16x4U {
memarg: MemoryImmediate { flags: _, offset },
} => {
let (flags, base, offset) = prepare_load(*offset, builder, state, environ)?;
let loaded = builder.ins().uload16x4(flags, base, offset);
state.push1(loaded);
}
Operator::I64x2Load32x2S {
memarg: MemoryImmediate { flags: _, offset },
} => {
let (flags, base, offset) = prepare_load(*offset, builder, state, environ)?;
let loaded = builder.ins().sload32x2(flags, base, offset);
state.push1(loaded);
}
Operator::I64x2Load32x2U {
memarg: MemoryImmediate { flags: _, offset },
} => {
let (flags, base, offset) = prepare_load(*offset, builder, state, environ)?;
let loaded = builder.ins().uload32x2(flags, base, offset);
state.push1(loaded);
}
/****************************** Store instructions ***********************************
* Wasm specifies an integer alignment flag but we drop it in Cranelift.
* The memory base address is provided by the environment.
@ -1561,7 +1518,13 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
| Operator::I32x4WidenLowI16x8S { .. }
| Operator::I32x4WidenHighI16x8S { .. }
| Operator::I32x4WidenLowI16x8U { .. }
| Operator::I32x4WidenHighI16x8U { .. } => {
| Operator::I32x4WidenHighI16x8U { .. }
| Operator::I16x8Load8x8S { .. }
| Operator::I16x8Load8x8U { .. }
| Operator::I32x4Load16x4S { .. }
| Operator::I32x4Load16x4U { .. }
| Operator::I64x2Load32x2S { .. }
| Operator::I64x2Load32x2U { .. } => {
return Err(wasm_unsupported!("proposed SIMD operator {:?}", op));
}
};
@ -1733,27 +1696,6 @@ fn get_heap_addr(
}
}
/// Prepare for a load; factors out common functionality between load and load_extend operations.
fn prepare_load<FE: FuncEnvironment + ?Sized>(
offset: u32,
builder: &mut FunctionBuilder,
state: &mut FuncTranslationState,
environ: &mut FE,
) -> WasmResult<(MemFlags, Value, Offset32)> {
let addr32 = state.pop1();
// We don't yet support multiple linear memories.
let heap = state.get_heap(builder.func, 0, environ)?;
let (base, offset) = get_heap_addr(heap, addr32, offset, environ.pointer_type(), builder);
// Note that we don't set `is_aligned` here, even if the load instruction's
// alignment immediate says it's aligned, because WebAssembly's immediate
// field is just a hint, while Cranelift's aligned flag needs a guarantee.
let flags = MemFlags::new();
Ok((flags, base, offset.into()))
}
/// Translate a load instruction.
fn translate_load<FE: FuncEnvironment + ?Sized>(
offset: u32,
@ -1763,8 +1705,17 @@ fn translate_load<FE: FuncEnvironment + ?Sized>(
state: &mut FuncTranslationState,
environ: &mut FE,
) -> WasmResult<()> {
let (flags, base, offset) = prepare_load(offset, builder, state, environ)?;
let (load, dfg) = builder.ins().Load(opcode, result_ty, flags, offset, base);
let addr32 = state.pop1();
// We don't yet support multiple linear memories.
let heap = state.get_heap(builder.func, 0, environ)?;
let (base, offset) = get_heap_addr(heap, addr32, offset, environ.pointer_type(), builder);
// Note that we don't set `is_aligned` here, even if the load instruction's
// alignment immediate says it's aligned, because WebAssembly's immediate
// field is just a hint, while Cranelift's aligned flag needs a guarantee.
let flags = MemFlags::new();
let (load, dfg) = builder
.ins()
.Load(opcode, result_ty, flags, offset.into(), base);
state.push1(dfg.first_result(load));
Ok(())
}