Merge inbound to mozilla-central. a=merge

This commit is contained in:
shindli 2019-03-08 15:50:01 +02:00
Родитель c7b10d2a2a e84c6bd970
Коммит 6c4127e860
75 изменённых файлов: 1319 добавлений и 1072 удалений

46
Cargo.lock сгенерированный
Просмотреть файл

@ -166,8 +166,8 @@ name = "baldrdash"
version = "0.1.0"
dependencies = [
"bindgen 0.43.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-wasm 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-wasm 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -490,20 +490,20 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-entity 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-codegen"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-bforest 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen-meta 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-bforest 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen-meta 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -512,36 +512,36 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-entity 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-entity"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cranelift-frontend"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cranelift-codegen 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-wasm"
version = "0.28.0"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-frontend 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-entity 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-frontend 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3351,12 +3351,12 @@ dependencies = [
"checksum core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f46450d6f2397261af420b4ccce23807add2e45fa206410a03d66fb7f050ae"
"checksum cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"
"checksum cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"
"checksum cranelift-bforest 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c88db0c2fc38b2cedee1b94ee2dc7bf80e4ce31467c8005743f485af66e240d8"
"checksum cranelift-codegen 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ce2e412970cfda0fa11806758d79a46c02b8fa1b91c35a8d3e2b4c947ce0c35"
"checksum cranelift-codegen-meta 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43131e662da7e0243cff28edfbc094a62968a4b57849f77a6c1e3685e9e6e1e6"
"checksum cranelift-entity 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4ccc3743848cbb53e58b62685703dc12ea553c3bc8f21db76f23c68054eb69a"
"checksum cranelift-frontend 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89ecc8b49d4ab98f2c121832fee365da88b7b0ffad77d4e328015b1fd1f7f4b1"
"checksum cranelift-wasm 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7eccd196ecd01a2394ce05e2259afe5704874816b058541c7cce7794f0e835e"
"checksum cranelift-bforest 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3a25dfe4a54449df63d592f2f6346a80350ac835d4be4bacb73c20b034ef763"
"checksum cranelift-codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c3b15a20577e6c823475953a5e25e758d9d3a3148a937d686c09460e5f2f4a0"
"checksum cranelift-codegen-meta 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e60ce3551e8172c966fbc6d9bfb90111d5d1cf37306c37dd7527467afe317d1"
"checksum cranelift-entity 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e124e09cb7dc85fbe2162420aebbe8e9e3b8f9210901be7867416c5beec8226"
"checksum cranelift-frontend 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2833c6e1a93c524ce0c2ab31266cdc84d38c906349f79f19378a5e5995727b23"
"checksum cranelift-wasm 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e75efb45cd8d8700b4bdc225f0077bc7c615f84a5807ce001d59b4da48d85573"
"checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"

Просмотреть файл

@ -8,7 +8,7 @@ support-files =
offline/manifest.appcache
[browser_clearSiteData.js]
skip-if = os == 'mac' && !debug # bug 1436395
skip-if = true # bug 1436395
[browser_siteData.js]
skip-if = (os == 'linux') || (os == 'mac' && !debug) || verify # Bug 1439332, Bug 1436395, Bug 1415037
[browser_siteData2.js]

Просмотреть файл

@ -48,6 +48,7 @@ async function testSteps() {
for (let i = 0; i < data.urlCount; i++) {
storages[i].setItem(data.key, data.value);
await returnToEventLoop();
}
info("Verifying no more data can be written");

Просмотреть файл

@ -244,7 +244,10 @@ for (let op of undefinedOpcodes) {
// Prefixed opcodes
function checkIllegalPrefixed(prefix, opcode) {
let binary = moduleWithSections([v2vSigSection, declSection([0]), bodySection([funcBody({locals:[], body:[prefix, opcode]})])]);
let binary = moduleWithSections([v2vSigSection,
declSection([0]),
bodySection([funcBody({locals:[],
body:[prefix, ...varU32(opcode)]})])]);
assertErrorMessage(() => wasmEval(binary), CompileError, /unrecognized opcode/);
assertEq(WebAssembly.validate(binary), false);
}

Просмотреть файл

@ -11436,21 +11436,21 @@ bool BaseCompiler::emitBody() {
// "Miscellaneous" operations
case uint16_t(Op::MiscPrefix): {
switch (op.b1) {
case uint16_t(MiscOp::I32TruncSSatF32):
case uint32_t(MiscOp::I32TruncSSatF32):
CHECK_NEXT(emitConversionOOM(emitTruncateF32ToI32<TRUNC_SATURATING>,
ValType::F32, ValType::I32));
case uint16_t(MiscOp::I32TruncUSatF32):
case uint32_t(MiscOp::I32TruncUSatF32):
CHECK_NEXT(emitConversionOOM(
emitTruncateF32ToI32<TRUNC_UNSIGNED | TRUNC_SATURATING>,
ValType::F32, ValType::I32));
case uint16_t(MiscOp::I32TruncSSatF64):
case uint32_t(MiscOp::I32TruncSSatF64):
CHECK_NEXT(emitConversionOOM(emitTruncateF64ToI32<TRUNC_SATURATING>,
ValType::F64, ValType::I32));
case uint16_t(MiscOp::I32TruncUSatF64):
case uint32_t(MiscOp::I32TruncUSatF64):
CHECK_NEXT(emitConversionOOM(
emitTruncateF64ToI32<TRUNC_UNSIGNED | TRUNC_SATURATING>,
ValType::F64, ValType::I32));
case uint16_t(MiscOp::I64TruncSSatF32):
case uint32_t(MiscOp::I64TruncSSatF32):
#ifdef RABALDR_FLOAT_TO_I64_CALLOUT
CHECK_NEXT(emitCalloutConversionOOM(
emitConvertFloatingToInt64Callout,
@ -11460,7 +11460,7 @@ bool BaseCompiler::emitBody() {
CHECK_NEXT(emitConversionOOM(emitTruncateF32ToI64<TRUNC_SATURATING>,
ValType::F32, ValType::I64));
#endif
case uint16_t(MiscOp::I64TruncUSatF32):
case uint32_t(MiscOp::I64TruncUSatF32):
#ifdef RABALDR_FLOAT_TO_I64_CALLOUT
CHECK_NEXT(emitCalloutConversionOOM(
emitConvertFloatingToInt64Callout,
@ -11471,7 +11471,7 @@ bool BaseCompiler::emitBody() {
emitTruncateF32ToI64<TRUNC_UNSIGNED | TRUNC_SATURATING>,
ValType::F32, ValType::I64));
#endif
case uint16_t(MiscOp::I64TruncSSatF64):
case uint32_t(MiscOp::I64TruncSSatF64):
#ifdef RABALDR_FLOAT_TO_I64_CALLOUT
CHECK_NEXT(emitCalloutConversionOOM(
emitConvertFloatingToInt64Callout,
@ -11481,7 +11481,7 @@ bool BaseCompiler::emitBody() {
CHECK_NEXT(emitConversionOOM(emitTruncateF64ToI64<TRUNC_SATURATING>,
ValType::F64, ValType::I64));
#endif
case uint16_t(MiscOp::I64TruncUSatF64):
case uint32_t(MiscOp::I64TruncUSatF64):
#ifdef RABALDR_FLOAT_TO_I64_CALLOUT
CHECK_NEXT(emitCalloutConversionOOM(
emitConvertFloatingToInt64Callout,
@ -11493,44 +11493,44 @@ bool BaseCompiler::emitBody() {
ValType::F64, ValType::I64));
#endif
#ifdef ENABLE_WASM_BULKMEM_OPS
case uint16_t(MiscOp::MemCopy):
case uint32_t(MiscOp::MemCopy):
CHECK_NEXT(emitMemOrTableCopy(/*isMem=*/true));
case uint16_t(MiscOp::DataDrop):
case uint32_t(MiscOp::DataDrop):
CHECK_NEXT(emitDataOrElemDrop(/*isData=*/true));
case uint16_t(MiscOp::MemFill):
case uint32_t(MiscOp::MemFill):
CHECK_NEXT(emitMemFill());
case uint16_t(MiscOp::MemInit):
case uint32_t(MiscOp::MemInit):
CHECK_NEXT(emitMemOrTableInit(/*isMem=*/true));
case uint16_t(MiscOp::TableCopy):
case uint32_t(MiscOp::TableCopy):
CHECK_NEXT(emitMemOrTableCopy(/*isMem=*/false));
case uint16_t(MiscOp::ElemDrop):
case uint32_t(MiscOp::ElemDrop):
CHECK_NEXT(emitDataOrElemDrop(/*isData=*/false));
case uint16_t(MiscOp::TableInit):
case uint32_t(MiscOp::TableInit):
CHECK_NEXT(emitMemOrTableInit(/*isMem=*/false));
#endif // ENABLE_WASM_BULKMEM_OPS
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(MiscOp::TableGrow):
case uint32_t(MiscOp::TableGrow):
CHECK_NEXT(emitTableGrow());
case uint16_t(MiscOp::TableSize):
case uint32_t(MiscOp::TableSize):
CHECK_NEXT(emitTableSize());
#endif
#ifdef ENABLE_WASM_GC
case uint16_t(MiscOp::StructNew):
case uint32_t(MiscOp::StructNew):
if (!env_.gcTypesEnabled()) {
return iter_.unrecognizedOpcode(&op);
}
CHECK_NEXT(emitStructNew());
case uint16_t(MiscOp::StructGet):
case uint32_t(MiscOp::StructGet):
if (!env_.gcTypesEnabled()) {
return iter_.unrecognizedOpcode(&op);
}
CHECK_NEXT(emitStructGet());
case uint16_t(MiscOp::StructSet):
case uint32_t(MiscOp::StructSet):
if (!env_.gcTypesEnabled()) {
return iter_.unrecognizedOpcode(&op);
}
CHECK_NEXT(emitStructSet());
case uint16_t(MiscOp::StructNarrow):
case uint32_t(MiscOp::StructNarrow):
if (!env_.gcTypesEnabled()) {
return iter_.unrecognizedOpcode(&op);
}
@ -11545,182 +11545,182 @@ bool BaseCompiler::emitBody() {
// Thread operations
case uint16_t(Op::ThreadPrefix): {
switch (op.b1) {
case uint16_t(ThreadOp::Wake):
case uint32_t(ThreadOp::Wake):
CHECK_NEXT(emitWake());
case uint16_t(ThreadOp::I32Wait):
case uint32_t(ThreadOp::I32Wait):
CHECK_NEXT(emitWait(ValType::I32, 4));
case uint16_t(ThreadOp::I64Wait):
case uint32_t(ThreadOp::I64Wait):
CHECK_NEXT(emitWait(ValType::I64, 8));
case uint16_t(ThreadOp::I32AtomicLoad):
case uint32_t(ThreadOp::I32AtomicLoad):
CHECK_NEXT(emitAtomicLoad(ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicLoad):
case uint32_t(ThreadOp::I64AtomicLoad):
CHECK_NEXT(emitAtomicLoad(ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicLoad8U):
case uint32_t(ThreadOp::I32AtomicLoad8U):
CHECK_NEXT(emitAtomicLoad(ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicLoad16U):
case uint32_t(ThreadOp::I32AtomicLoad16U):
CHECK_NEXT(emitAtomicLoad(ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicLoad8U):
case uint32_t(ThreadOp::I64AtomicLoad8U):
CHECK_NEXT(emitAtomicLoad(ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicLoad16U):
case uint32_t(ThreadOp::I64AtomicLoad16U):
CHECK_NEXT(emitAtomicLoad(ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicLoad32U):
case uint32_t(ThreadOp::I64AtomicLoad32U):
CHECK_NEXT(emitAtomicLoad(ValType::I64, Scalar::Uint32));
case uint16_t(ThreadOp::I32AtomicStore):
case uint32_t(ThreadOp::I32AtomicStore):
CHECK_NEXT(emitAtomicStore(ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicStore):
case uint32_t(ThreadOp::I64AtomicStore):
CHECK_NEXT(emitAtomicStore(ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicStore8U):
case uint32_t(ThreadOp::I32AtomicStore8U):
CHECK_NEXT(emitAtomicStore(ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicStore16U):
case uint32_t(ThreadOp::I32AtomicStore16U):
CHECK_NEXT(emitAtomicStore(ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicStore8U):
case uint32_t(ThreadOp::I64AtomicStore8U):
CHECK_NEXT(emitAtomicStore(ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicStore16U):
case uint32_t(ThreadOp::I64AtomicStore16U):
CHECK_NEXT(emitAtomicStore(ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicStore32U):
case uint32_t(ThreadOp::I64AtomicStore32U):
CHECK_NEXT(emitAtomicStore(ValType::I64, Scalar::Uint32));
case uint16_t(ThreadOp::I32AtomicAdd):
case uint32_t(ThreadOp::I32AtomicAdd):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Int32, AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd):
case uint32_t(ThreadOp::I64AtomicAdd):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Int64, AtomicFetchAddOp));
case uint16_t(ThreadOp::I32AtomicAdd8U):
case uint32_t(ThreadOp::I32AtomicAdd8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint8, AtomicFetchAddOp));
case uint16_t(ThreadOp::I32AtomicAdd16U):
case uint32_t(ThreadOp::I32AtomicAdd16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint16, AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd8U):
case uint32_t(ThreadOp::I64AtomicAdd8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint8, AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd16U):
case uint32_t(ThreadOp::I64AtomicAdd16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint16, AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd32U):
case uint32_t(ThreadOp::I64AtomicAdd32U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint32, AtomicFetchAddOp));
case uint16_t(ThreadOp::I32AtomicSub):
case uint32_t(ThreadOp::I32AtomicSub):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Int32, AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub):
case uint32_t(ThreadOp::I64AtomicSub):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Int64, AtomicFetchSubOp));
case uint16_t(ThreadOp::I32AtomicSub8U):
case uint32_t(ThreadOp::I32AtomicSub8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint8, AtomicFetchSubOp));
case uint16_t(ThreadOp::I32AtomicSub16U):
case uint32_t(ThreadOp::I32AtomicSub16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint16, AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub8U):
case uint32_t(ThreadOp::I64AtomicSub8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint8, AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub16U):
case uint32_t(ThreadOp::I64AtomicSub16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint16, AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub32U):
case uint32_t(ThreadOp::I64AtomicSub32U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint32, AtomicFetchSubOp));
case uint16_t(ThreadOp::I32AtomicAnd):
case uint32_t(ThreadOp::I32AtomicAnd):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Int32, AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd):
case uint32_t(ThreadOp::I64AtomicAnd):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Int64, AtomicFetchAndOp));
case uint16_t(ThreadOp::I32AtomicAnd8U):
case uint32_t(ThreadOp::I32AtomicAnd8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint8, AtomicFetchAndOp));
case uint16_t(ThreadOp::I32AtomicAnd16U):
case uint32_t(ThreadOp::I32AtomicAnd16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint16, AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd8U):
case uint32_t(ThreadOp::I64AtomicAnd8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint8, AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd16U):
case uint32_t(ThreadOp::I64AtomicAnd16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint16, AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd32U):
case uint32_t(ThreadOp::I64AtomicAnd32U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint32, AtomicFetchAndOp));
case uint16_t(ThreadOp::I32AtomicOr):
case uint32_t(ThreadOp::I32AtomicOr):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Int32, AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr):
case uint32_t(ThreadOp::I64AtomicOr):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Int64, AtomicFetchOrOp));
case uint16_t(ThreadOp::I32AtomicOr8U):
case uint32_t(ThreadOp::I32AtomicOr8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint8, AtomicFetchOrOp));
case uint16_t(ThreadOp::I32AtomicOr16U):
case uint32_t(ThreadOp::I32AtomicOr16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint16, AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr8U):
case uint32_t(ThreadOp::I64AtomicOr8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint8, AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr16U):
case uint32_t(ThreadOp::I64AtomicOr16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint16, AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr32U):
case uint32_t(ThreadOp::I64AtomicOr32U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint32, AtomicFetchOrOp));
case uint16_t(ThreadOp::I32AtomicXor):
case uint32_t(ThreadOp::I32AtomicXor):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Int32, AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor):
case uint32_t(ThreadOp::I64AtomicXor):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Int64, AtomicFetchXorOp));
case uint16_t(ThreadOp::I32AtomicXor8U):
case uint32_t(ThreadOp::I32AtomicXor8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint8, AtomicFetchXorOp));
case uint16_t(ThreadOp::I32AtomicXor16U):
case uint32_t(ThreadOp::I32AtomicXor16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I32, Scalar::Uint16, AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor8U):
case uint32_t(ThreadOp::I64AtomicXor8U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint8, AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor16U):
case uint32_t(ThreadOp::I64AtomicXor16U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint16, AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor32U):
case uint32_t(ThreadOp::I64AtomicXor32U):
CHECK_NEXT(
emitAtomicRMW(ValType::I64, Scalar::Uint32, AtomicFetchXorOp));
case uint16_t(ThreadOp::I32AtomicXchg):
case uint32_t(ThreadOp::I32AtomicXchg):
CHECK_NEXT(emitAtomicXchg(ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicXchg):
case uint32_t(ThreadOp::I64AtomicXchg):
CHECK_NEXT(emitAtomicXchg(ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicXchg8U):
case uint32_t(ThreadOp::I32AtomicXchg8U):
CHECK_NEXT(emitAtomicXchg(ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicXchg16U):
case uint32_t(ThreadOp::I32AtomicXchg16U):
CHECK_NEXT(emitAtomicXchg(ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicXchg8U):
case uint32_t(ThreadOp::I64AtomicXchg8U):
CHECK_NEXT(emitAtomicXchg(ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicXchg16U):
case uint32_t(ThreadOp::I64AtomicXchg16U):
CHECK_NEXT(emitAtomicXchg(ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicXchg32U):
case uint32_t(ThreadOp::I64AtomicXchg32U):
CHECK_NEXT(emitAtomicXchg(ValType::I64, Scalar::Uint32));
case uint16_t(ThreadOp::I32AtomicCmpXchg):
case uint32_t(ThreadOp::I32AtomicCmpXchg):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicCmpXchg):
case uint32_t(ThreadOp::I64AtomicCmpXchg):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicCmpXchg8U):
case uint32_t(ThreadOp::I32AtomicCmpXchg8U):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicCmpXchg16U):
case uint32_t(ThreadOp::I32AtomicCmpXchg16U):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicCmpXchg8U):
case uint32_t(ThreadOp::I64AtomicCmpXchg8U):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicCmpXchg16U):
case uint32_t(ThreadOp::I64AtomicCmpXchg16U):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicCmpXchg32U):
case uint32_t(ThreadOp::I64AtomicCmpXchg32U):
CHECK_NEXT(emitAtomicCmpXchg(ValType::I64, Scalar::Uint32));
default:

Просмотреть файл

@ -480,16 +480,6 @@ enum class ThreadOp {
Limit
};
// Opcodes from Bulk Memory Operations proposal as at 2 Feb 2018. Note,
// the opcodes are not actually assigned in that proposal. This is just
// an interim assignment.
enum class CopyOrFillOp {
Copy = 0x01,
Fill = 0x02,
Limit
};
enum class MozOp {
// ------------------------------------------------------------------------
// These operators are emitted internally when compiling asm.js and are
@ -534,10 +524,11 @@ enum class MozOp {
};
struct OpBytes {
// The bytes of the opcode have 16-bit representations to allow for a full
// b0 is a byte value but has a 16-bit representation to allow for a full
// 256-value range plus a sentinel Limit value.
uint16_t b0;
uint16_t b1;
// b1 is a LEB128 value but 32 bits is enough for now.
uint32_t b1;
explicit OpBytes(Op x) {
b0 = uint16_t(x);

Просмотреть файл

@ -70,6 +70,7 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
const CraneliftCompiledFunc& func,
const FuncTypeIdDesc& funcTypeId,
uint32_t lineOrBytecode,
uint32_t funcBytecodeSize,
FuncOffsets* offsets) {
wasm::GenerateFunctionPrologue(masm, funcTypeId, mozilla::Nothing(), offsets);
@ -113,11 +114,19 @@ static bool GenerateCraneliftCode(WasmMacroAssembler& masm,
}
#ifdef DEBUG
CheckedInt<uint32_t> checkedBytecodeOffset = lineOrBytecode;
checkedBytecodeOffset += metadata.srcLoc;
MOZ_ASSERT(checkedBytecodeOffset.isValid());
// Check code offsets.
MOZ_ASSERT(offset.value() >= offsets->normalEntry);
MOZ_ASSERT(offset.value() < offsets->ret);
// Check bytecode offsets.
if (metadata.srcLoc > 0 && lineOrBytecode > 0) {
MOZ_ASSERT(metadata.srcLoc >= lineOrBytecode);
MOZ_ASSERT(metadata.srcLoc < lineOrBytecode + funcBytecodeSize);
}
#endif
uint32_t bytecodeOffset = lineOrBytecode + metadata.srcLoc;
// TODO(bug 1532716): Cranelift gives null bytecode offsets for symbolic
// accesses.
uint32_t bytecodeOffset = metadata.srcLoc ? metadata.srcLoc : lineOrBytecode;
switch (metadata.which) {
case CraneliftMetadataEntry::Which::DirectCall: {
@ -183,7 +192,9 @@ CraneliftFuncCompileInput::CraneliftFuncCompileInput(
const FuncCompileInput& func)
: bytecode(func.begin),
bytecodeSize(func.end - func.begin),
index(func.index) {}
index(func.index),
offset_in_module(func.lineOrBytecode)
{}
#ifndef WASM_HUGE_MEMORY
static_assert(offsetof(TlsData, boundsCheckLimit) == sizeof(size_t),
@ -247,40 +258,42 @@ static size_t globalToTlsOffset(size_t globalOffset) {
CraneliftModuleEnvironment::CraneliftModuleEnvironment(
const ModuleEnvironment& env)
: env(env), min_memory_length(env.minMemoryLength) {}
: env(&env),
min_memory_length(env.minMemoryLength)
{}
TypeCode env_unpack(BD_ValType valType) {
return TypeCode(UnpackTypeCodeType(PackedTypeCode(valType.packed)));
}
const FuncTypeWithId* env_function_signature(
const CraneliftModuleEnvironment* env, size_t funcIndex) {
return env->env.funcTypes[funcIndex];
const CraneliftModuleEnvironment* wrapper, size_t funcIndex) {
return wrapper->env->funcTypes[funcIndex];
}
size_t env_func_import_tls_offset(const CraneliftModuleEnvironment* env,
size_t env_func_import_tls_offset(const CraneliftModuleEnvironment* wrapper,
size_t funcIndex) {
return globalToTlsOffset(env->env.funcImportGlobalDataOffsets[funcIndex]);
return globalToTlsOffset(wrapper->env->funcImportGlobalDataOffsets[funcIndex]);
}
bool env_func_is_import(const CraneliftModuleEnvironment* env,
bool env_func_is_import(const CraneliftModuleEnvironment* wrapper,
size_t funcIndex) {
return env->env.funcIsImport(funcIndex);
return wrapper->env->funcIsImport(funcIndex);
}
const FuncTypeWithId* env_signature(const CraneliftModuleEnvironment* env,
const FuncTypeWithId* env_signature(const CraneliftModuleEnvironment* wrapper,
size_t funcTypeIndex) {
return &env->env.types[funcTypeIndex].funcType();
return &wrapper->env->types[funcTypeIndex].funcType();
}
const TableDesc* env_table(const CraneliftModuleEnvironment* env,
const TableDesc* env_table(const CraneliftModuleEnvironment* wrapper,
size_t tableIndex) {
return &env->env.tables[tableIndex];
return &wrapper->env->tables[tableIndex];
}
const GlobalDesc* env_global(const CraneliftModuleEnvironment* env,
const GlobalDesc* env_global(const CraneliftModuleEnvironment* wrapper,
size_t globalIndex) {
return &env->env.globals[globalIndex];
return &wrapper->env->globals[globalIndex];
}
bool wasm::CraneliftCompileFunctions(const ModuleEnvironment& env,
@ -311,7 +324,9 @@ bool wasm::CraneliftCompileFunctions(const ModuleEnvironment& env,
for (const FuncCompileInput& func : inputs) {
Decoder d(func.begin, func.end, func.lineOrBytecode, error);
if (!ValidateFunctionBody(env, func.index, func.end - func.begin, d)) {
size_t funcBytecodeSize = func.end - func.begin;
if (!ValidateFunctionBody(env, func.index, funcBytecodeSize, d)) {
return false;
}
@ -328,12 +343,11 @@ bool wasm::CraneliftCompileFunctions(const ModuleEnvironment& env,
FuncOffsets offsets;
if (!GenerateCraneliftCode(masm, clifFunc, funcTypeId, lineOrBytecode,
&offsets)) {
funcBytecodeSize, &offsets)) {
return false;
}
if (!code->codeRanges.emplaceBack(func.index, func.lineOrBytecode,
offsets)) {
if (!code->codeRanges.emplaceBack(func.index, lineOrBytecode, offsets)) {
return false;
}
}

Просмотреть файл

@ -3818,49 +3818,49 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
// Miscellaneous operations
case uint16_t(Op::MiscPrefix): {
switch (op.b1) {
case uint16_t(MiscOp::I32TruncSSatF32):
case uint16_t(MiscOp::I32TruncUSatF32):
case uint32_t(MiscOp::I32TruncSSatF32):
case uint32_t(MiscOp::I32TruncUSatF32):
CHECK(EmitTruncate(f, ValType::F32, ValType::I32,
MiscOp(op.b1) == MiscOp::I32TruncUSatF32, true));
case uint16_t(MiscOp::I32TruncSSatF64):
case uint16_t(MiscOp::I32TruncUSatF64):
case uint32_t(MiscOp::I32TruncSSatF64):
case uint32_t(MiscOp::I32TruncUSatF64):
CHECK(EmitTruncate(f, ValType::F64, ValType::I32,
MiscOp(op.b1) == MiscOp::I32TruncUSatF64, true));
case uint16_t(MiscOp::I64TruncSSatF32):
case uint16_t(MiscOp::I64TruncUSatF32):
case uint32_t(MiscOp::I64TruncSSatF32):
case uint32_t(MiscOp::I64TruncUSatF32):
CHECK(EmitTruncate(f, ValType::F32, ValType::I64,
MiscOp(op.b1) == MiscOp::I64TruncUSatF32, true));
case uint16_t(MiscOp::I64TruncSSatF64):
case uint16_t(MiscOp::I64TruncUSatF64):
case uint32_t(MiscOp::I64TruncSSatF64):
case uint32_t(MiscOp::I64TruncUSatF64):
CHECK(EmitTruncate(f, ValType::F64, ValType::I64,
MiscOp(op.b1) == MiscOp::I64TruncUSatF64, true));
#ifdef ENABLE_WASM_BULKMEM_OPS
case uint16_t(MiscOp::MemCopy):
case uint32_t(MiscOp::MemCopy):
CHECK(EmitMemOrTableCopy(f, /*isMem=*/true));
case uint16_t(MiscOp::DataDrop):
case uint32_t(MiscOp::DataDrop):
CHECK(EmitDataOrElemDrop(f, /*isData=*/true));
case uint16_t(MiscOp::MemFill):
case uint32_t(MiscOp::MemFill):
CHECK(EmitMemFill(f));
case uint16_t(MiscOp::MemInit):
case uint32_t(MiscOp::MemInit):
CHECK(EmitMemOrTableInit(f, /*isMem=*/true));
case uint16_t(MiscOp::TableCopy):
case uint32_t(MiscOp::TableCopy):
CHECK(EmitMemOrTableCopy(f, /*isMem=*/false));
case uint16_t(MiscOp::ElemDrop):
case uint32_t(MiscOp::ElemDrop):
CHECK(EmitDataOrElemDrop(f, /*isData=*/false));
case uint16_t(MiscOp::TableInit):
case uint32_t(MiscOp::TableInit):
CHECK(EmitMemOrTableInit(f, /*isMem=*/false));
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(MiscOp::TableGrow):
case uint32_t(MiscOp::TableGrow):
CHECK(EmitTableGrow(f));
case uint16_t(MiscOp::TableSize):
case uint32_t(MiscOp::TableSize):
CHECK(EmitTableSize(f));
#endif
#ifdef ENABLE_WASM_GC
case uint16_t(MiscOp::StructNew):
case uint16_t(MiscOp::StructGet):
case uint16_t(MiscOp::StructSet):
case uint16_t(MiscOp::StructNarrow):
case uint32_t(MiscOp::StructNew):
case uint32_t(MiscOp::StructGet):
case uint32_t(MiscOp::StructSet):
case uint32_t(MiscOp::StructNarrow):
// Not yet supported
return f.iter().unrecognizedOpcode(&op);
#endif
@ -3873,182 +3873,182 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
// Thread operations
case uint16_t(Op::ThreadPrefix): {
switch (op.b1) {
case uint16_t(ThreadOp::Wake):
case uint32_t(ThreadOp::Wake):
CHECK(EmitWake(f));
case uint16_t(ThreadOp::I32Wait):
case uint32_t(ThreadOp::I32Wait):
CHECK(EmitWait(f, ValType::I32, 4));
case uint16_t(ThreadOp::I64Wait):
case uint32_t(ThreadOp::I64Wait):
CHECK(EmitWait(f, ValType::I64, 8));
case uint16_t(ThreadOp::I32AtomicLoad):
case uint32_t(ThreadOp::I32AtomicLoad):
CHECK(EmitAtomicLoad(f, ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicLoad):
case uint32_t(ThreadOp::I64AtomicLoad):
CHECK(EmitAtomicLoad(f, ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicLoad8U):
case uint32_t(ThreadOp::I32AtomicLoad8U):
CHECK(EmitAtomicLoad(f, ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicLoad16U):
case uint32_t(ThreadOp::I32AtomicLoad16U):
CHECK(EmitAtomicLoad(f, ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicLoad8U):
case uint32_t(ThreadOp::I64AtomicLoad8U):
CHECK(EmitAtomicLoad(f, ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicLoad16U):
case uint32_t(ThreadOp::I64AtomicLoad16U):
CHECK(EmitAtomicLoad(f, ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicLoad32U):
case uint32_t(ThreadOp::I64AtomicLoad32U):
CHECK(EmitAtomicLoad(f, ValType::I64, Scalar::Uint32));
case uint16_t(ThreadOp::I32AtomicStore):
case uint32_t(ThreadOp::I32AtomicStore):
CHECK(EmitAtomicStore(f, ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicStore):
case uint32_t(ThreadOp::I64AtomicStore):
CHECK(EmitAtomicStore(f, ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicStore8U):
case uint32_t(ThreadOp::I32AtomicStore8U):
CHECK(EmitAtomicStore(f, ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicStore16U):
case uint32_t(ThreadOp::I32AtomicStore16U):
CHECK(EmitAtomicStore(f, ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicStore8U):
case uint32_t(ThreadOp::I64AtomicStore8U):
CHECK(EmitAtomicStore(f, ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicStore16U):
case uint32_t(ThreadOp::I64AtomicStore16U):
CHECK(EmitAtomicStore(f, ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicStore32U):
case uint32_t(ThreadOp::I64AtomicStore32U):
CHECK(EmitAtomicStore(f, ValType::I64, Scalar::Uint32));
case uint16_t(ThreadOp::I32AtomicAdd):
case uint32_t(ThreadOp::I32AtomicAdd):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Int32,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd):
case uint32_t(ThreadOp::I64AtomicAdd):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Int64,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I32AtomicAdd8U):
case uint32_t(ThreadOp::I32AtomicAdd8U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint8,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I32AtomicAdd16U):
case uint32_t(ThreadOp::I32AtomicAdd16U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint16,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd8U):
case uint32_t(ThreadOp::I64AtomicAdd8U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint8,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd16U):
case uint32_t(ThreadOp::I64AtomicAdd16U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint16,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I64AtomicAdd32U):
case uint32_t(ThreadOp::I64AtomicAdd32U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint32,
AtomicFetchAddOp));
case uint16_t(ThreadOp::I32AtomicSub):
case uint32_t(ThreadOp::I32AtomicSub):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Int32,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub):
case uint32_t(ThreadOp::I64AtomicSub):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Int64,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I32AtomicSub8U):
case uint32_t(ThreadOp::I32AtomicSub8U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint8,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I32AtomicSub16U):
case uint32_t(ThreadOp::I32AtomicSub16U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint16,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub8U):
case uint32_t(ThreadOp::I64AtomicSub8U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint8,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub16U):
case uint32_t(ThreadOp::I64AtomicSub16U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint16,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I64AtomicSub32U):
case uint32_t(ThreadOp::I64AtomicSub32U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint32,
AtomicFetchSubOp));
case uint16_t(ThreadOp::I32AtomicAnd):
case uint32_t(ThreadOp::I32AtomicAnd):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Int32,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd):
case uint32_t(ThreadOp::I64AtomicAnd):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Int64,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I32AtomicAnd8U):
case uint32_t(ThreadOp::I32AtomicAnd8U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint8,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I32AtomicAnd16U):
case uint32_t(ThreadOp::I32AtomicAnd16U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint16,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd8U):
case uint32_t(ThreadOp::I64AtomicAnd8U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint8,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd16U):
case uint32_t(ThreadOp::I64AtomicAnd16U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint16,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I64AtomicAnd32U):
case uint32_t(ThreadOp::I64AtomicAnd32U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint32,
AtomicFetchAndOp));
case uint16_t(ThreadOp::I32AtomicOr):
case uint32_t(ThreadOp::I32AtomicOr):
CHECK(
EmitAtomicRMW(f, ValType::I32, Scalar::Int32, AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr):
case uint32_t(ThreadOp::I64AtomicOr):
CHECK(
EmitAtomicRMW(f, ValType::I64, Scalar::Int64, AtomicFetchOrOp));
case uint16_t(ThreadOp::I32AtomicOr8U):
case uint32_t(ThreadOp::I32AtomicOr8U):
CHECK(
EmitAtomicRMW(f, ValType::I32, Scalar::Uint8, AtomicFetchOrOp));
case uint16_t(ThreadOp::I32AtomicOr16U):
case uint32_t(ThreadOp::I32AtomicOr16U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint16,
AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr8U):
case uint32_t(ThreadOp::I64AtomicOr8U):
CHECK(
EmitAtomicRMW(f, ValType::I64, Scalar::Uint8, AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr16U):
case uint32_t(ThreadOp::I64AtomicOr16U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint16,
AtomicFetchOrOp));
case uint16_t(ThreadOp::I64AtomicOr32U):
case uint32_t(ThreadOp::I64AtomicOr32U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint32,
AtomicFetchOrOp));
case uint16_t(ThreadOp::I32AtomicXor):
case uint32_t(ThreadOp::I32AtomicXor):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Int32,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor):
case uint32_t(ThreadOp::I64AtomicXor):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Int64,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I32AtomicXor8U):
case uint32_t(ThreadOp::I32AtomicXor8U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint8,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I32AtomicXor16U):
case uint32_t(ThreadOp::I32AtomicXor16U):
CHECK(EmitAtomicRMW(f, ValType::I32, Scalar::Uint16,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor8U):
case uint32_t(ThreadOp::I64AtomicXor8U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint8,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor16U):
case uint32_t(ThreadOp::I64AtomicXor16U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint16,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I64AtomicXor32U):
case uint32_t(ThreadOp::I64AtomicXor32U):
CHECK(EmitAtomicRMW(f, ValType::I64, Scalar::Uint32,
AtomicFetchXorOp));
case uint16_t(ThreadOp::I32AtomicXchg):
case uint32_t(ThreadOp::I32AtomicXchg):
CHECK(EmitAtomicXchg(f, ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicXchg):
case uint32_t(ThreadOp::I64AtomicXchg):
CHECK(EmitAtomicXchg(f, ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicXchg8U):
case uint32_t(ThreadOp::I32AtomicXchg8U):
CHECK(EmitAtomicXchg(f, ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicXchg16U):
case uint32_t(ThreadOp::I32AtomicXchg16U):
CHECK(EmitAtomicXchg(f, ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicXchg8U):
case uint32_t(ThreadOp::I64AtomicXchg8U):
CHECK(EmitAtomicXchg(f, ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicXchg16U):
case uint32_t(ThreadOp::I64AtomicXchg16U):
CHECK(EmitAtomicXchg(f, ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicXchg32U):
case uint32_t(ThreadOp::I64AtomicXchg32U):
CHECK(EmitAtomicXchg(f, ValType::I64, Scalar::Uint32));
case uint16_t(ThreadOp::I32AtomicCmpXchg):
case uint32_t(ThreadOp::I32AtomicCmpXchg):
CHECK(EmitAtomicCmpXchg(f, ValType::I32, Scalar::Int32));
case uint16_t(ThreadOp::I64AtomicCmpXchg):
case uint32_t(ThreadOp::I64AtomicCmpXchg):
CHECK(EmitAtomicCmpXchg(f, ValType::I64, Scalar::Int64));
case uint16_t(ThreadOp::I32AtomicCmpXchg8U):
case uint32_t(ThreadOp::I32AtomicCmpXchg8U):
CHECK(EmitAtomicCmpXchg(f, ValType::I32, Scalar::Uint8));
case uint16_t(ThreadOp::I32AtomicCmpXchg16U):
case uint32_t(ThreadOp::I32AtomicCmpXchg16U):
CHECK(EmitAtomicCmpXchg(f, ValType::I32, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicCmpXchg8U):
case uint32_t(ThreadOp::I64AtomicCmpXchg8U):
CHECK(EmitAtomicCmpXchg(f, ValType::I64, Scalar::Uint8));
case uint16_t(ThreadOp::I64AtomicCmpXchg16U):
case uint32_t(ThreadOp::I64AtomicCmpXchg16U):
CHECK(EmitAtomicCmpXchg(f, ValType::I64, Scalar::Uint16));
case uint16_t(ThreadOp::I64AtomicCmpXchg32U):
case uint32_t(ThreadOp::I64AtomicCmpXchg32U):
CHECK(EmitAtomicCmpXchg(f, ValType::I64, Scalar::Uint32));
default:
@ -4063,66 +4063,66 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
return f.iter().unrecognizedOpcode(&op);
}
switch (op.b1) {
case uint16_t(MozOp::TeeGlobal):
case uint32_t(MozOp::TeeGlobal):
CHECK(EmitTeeGlobal(f));
case uint16_t(MozOp::I32Min):
case uint16_t(MozOp::I32Max):
case uint32_t(MozOp::I32Min):
case uint32_t(MozOp::I32Max):
CHECK(EmitMinMax(f, ValType::I32, MIRType::Int32,
MozOp(op.b1) == MozOp::I32Max));
case uint16_t(MozOp::I32Neg):
case uint32_t(MozOp::I32Neg):
CHECK(EmitUnaryWithType<MWasmNeg>(f, ValType::I32, MIRType::Int32));
case uint16_t(MozOp::I32BitNot):
case uint32_t(MozOp::I32BitNot):
CHECK(EmitBitNot(f, ValType::I32));
case uint16_t(MozOp::I32Abs):
case uint32_t(MozOp::I32Abs):
CHECK(EmitUnaryWithType<MAbs>(f, ValType::I32, MIRType::Int32));
case uint16_t(MozOp::F32TeeStoreF64):
case uint32_t(MozOp::F32TeeStoreF64):
CHECK(EmitTeeStoreWithCoercion(f, ValType::F32, Scalar::Float64));
case uint16_t(MozOp::F64TeeStoreF32):
case uint32_t(MozOp::F64TeeStoreF32):
CHECK(EmitTeeStoreWithCoercion(f, ValType::F64, Scalar::Float32));
case uint16_t(MozOp::I32TeeStore8):
case uint32_t(MozOp::I32TeeStore8):
CHECK(EmitTeeStore(f, ValType::I32, Scalar::Int8));
case uint16_t(MozOp::I32TeeStore16):
case uint32_t(MozOp::I32TeeStore16):
CHECK(EmitTeeStore(f, ValType::I32, Scalar::Int16));
case uint16_t(MozOp::I64TeeStore8):
case uint32_t(MozOp::I64TeeStore8):
CHECK(EmitTeeStore(f, ValType::I64, Scalar::Int8));
case uint16_t(MozOp::I64TeeStore16):
case uint32_t(MozOp::I64TeeStore16):
CHECK(EmitTeeStore(f, ValType::I64, Scalar::Int16));
case uint16_t(MozOp::I64TeeStore32):
case uint32_t(MozOp::I64TeeStore32):
CHECK(EmitTeeStore(f, ValType::I64, Scalar::Int32));
case uint16_t(MozOp::I32TeeStore):
case uint32_t(MozOp::I32TeeStore):
CHECK(EmitTeeStore(f, ValType::I32, Scalar::Int32));
case uint16_t(MozOp::I64TeeStore):
case uint32_t(MozOp::I64TeeStore):
CHECK(EmitTeeStore(f, ValType::I64, Scalar::Int64));
case uint16_t(MozOp::F32TeeStore):
case uint32_t(MozOp::F32TeeStore):
CHECK(EmitTeeStore(f, ValType::F32, Scalar::Float32));
case uint16_t(MozOp::F64TeeStore):
case uint32_t(MozOp::F64TeeStore):
CHECK(EmitTeeStore(f, ValType::F64, Scalar::Float64));
case uint16_t(MozOp::F64Mod):
case uint32_t(MozOp::F64Mod):
CHECK(EmitRem(f, ValType::F64, MIRType::Double,
/* isUnsigned = */ false));
case uint16_t(MozOp::F64Sin):
case uint32_t(MozOp::F64Sin):
CHECK(EmitUnaryMathBuiltinCall(f, SASigSinD));
case uint16_t(MozOp::F64Cos):
case uint32_t(MozOp::F64Cos):
CHECK(EmitUnaryMathBuiltinCall(f, SASigCosD));
case uint16_t(MozOp::F64Tan):
case uint32_t(MozOp::F64Tan):
CHECK(EmitUnaryMathBuiltinCall(f, SASigTanD));
case uint16_t(MozOp::F64Asin):
case uint32_t(MozOp::F64Asin):
CHECK(EmitUnaryMathBuiltinCall(f, SASigASinD));
case uint16_t(MozOp::F64Acos):
case uint32_t(MozOp::F64Acos):
CHECK(EmitUnaryMathBuiltinCall(f, SASigACosD));
case uint16_t(MozOp::F64Atan):
case uint32_t(MozOp::F64Atan):
CHECK(EmitUnaryMathBuiltinCall(f, SASigATanD));
case uint16_t(MozOp::F64Exp):
case uint32_t(MozOp::F64Exp):
CHECK(EmitUnaryMathBuiltinCall(f, SASigExpD));
case uint16_t(MozOp::F64Log):
case uint32_t(MozOp::F64Log):
CHECK(EmitUnaryMathBuiltinCall(f, SASigLogD));
case uint16_t(MozOp::F64Pow):
case uint32_t(MozOp::F64Pow):
CHECK(EmitBinaryMathBuiltinCall(f, SASigPowD));
case uint16_t(MozOp::F64Atan2):
case uint32_t(MozOp::F64Atan2):
CHECK(EmitBinaryMathBuiltinCall(f, SASigATan2D));
case uint16_t(MozOp::OldCallDirect):
case uint32_t(MozOp::OldCallDirect):
CHECK(EmitCall(f, /* asmJSFuncDef = */ true));
case uint16_t(MozOp::OldCallIndirect):
case uint32_t(MozOp::OldCallIndirect):
CHECK(EmitCallIndirect(f, /* oldStyle = */ true));
default:

Просмотреть файл

@ -817,51 +817,51 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
CHECK(iter.readUnreachable());
case uint16_t(Op::MiscPrefix): {
switch (op.b1) {
case uint16_t(MiscOp::I32TruncSSatF32):
case uint16_t(MiscOp::I32TruncUSatF32):
case uint32_t(MiscOp::I32TruncSSatF32):
case uint32_t(MiscOp::I32TruncUSatF32):
CHECK(iter.readConversion(ValType::F32, ValType::I32, &nothing));
case uint16_t(MiscOp::I32TruncSSatF64):
case uint16_t(MiscOp::I32TruncUSatF64):
case uint32_t(MiscOp::I32TruncSSatF64):
case uint32_t(MiscOp::I32TruncUSatF64):
CHECK(iter.readConversion(ValType::F64, ValType::I32, &nothing));
case uint16_t(MiscOp::I64TruncSSatF32):
case uint16_t(MiscOp::I64TruncUSatF32):
case uint32_t(MiscOp::I64TruncSSatF32):
case uint32_t(MiscOp::I64TruncUSatF32):
CHECK(iter.readConversion(ValType::F32, ValType::I64, &nothing));
case uint16_t(MiscOp::I64TruncSSatF64):
case uint16_t(MiscOp::I64TruncUSatF64):
case uint32_t(MiscOp::I64TruncSSatF64):
case uint32_t(MiscOp::I64TruncUSatF64):
CHECK(iter.readConversion(ValType::F64, ValType::I64, &nothing));
#ifdef ENABLE_WASM_BULKMEM_OPS
case uint16_t(MiscOp::MemCopy): {
case uint32_t(MiscOp::MemCopy): {
uint32_t unusedDestMemIndex;
uint32_t unusedSrcMemIndex;
CHECK(iter.readMemOrTableCopy(/*isMem=*/true, &unusedDestMemIndex,
&nothing, &unusedSrcMemIndex,
&nothing, &nothing));
}
case uint16_t(MiscOp::DataDrop): {
case uint32_t(MiscOp::DataDrop): {
uint32_t unusedSegIndex;
CHECK(iter.readDataOrElemDrop(/*isData=*/true, &unusedSegIndex));
}
case uint16_t(MiscOp::MemFill):
case uint32_t(MiscOp::MemFill):
CHECK(iter.readMemFill(&nothing, &nothing, &nothing));
case uint16_t(MiscOp::MemInit): {
case uint32_t(MiscOp::MemInit): {
uint32_t unusedSegIndex;
uint32_t unusedTableIndex;
CHECK(iter.readMemOrTableInit(/*isMem=*/true, &unusedSegIndex,
&unusedTableIndex, &nothing, &nothing,
&nothing));
}
case uint16_t(MiscOp::TableCopy): {
case uint32_t(MiscOp::TableCopy): {
uint32_t unusedDestTableIndex;
uint32_t unusedSrcTableIndex;
CHECK(iter.readMemOrTableCopy(
/*isMem=*/false, &unusedDestTableIndex, &nothing,
&unusedSrcTableIndex, &nothing, &nothing));
}
case uint16_t(MiscOp::ElemDrop): {
case uint32_t(MiscOp::ElemDrop): {
uint32_t unusedSegIndex;
CHECK(iter.readDataOrElemDrop(/*isData=*/false, &unusedSegIndex));
}
case uint16_t(MiscOp::TableInit): {
case uint32_t(MiscOp::TableInit): {
uint32_t unusedSegIndex;
uint32_t unusedTableIndex;
CHECK(iter.readMemOrTableInit(/*isMem=*/false, &unusedSegIndex,
@ -870,17 +870,17 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
}
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint16_t(MiscOp::TableGrow): {
case uint32_t(MiscOp::TableGrow): {
uint32_t unusedTableIndex;
CHECK(iter.readTableGrow(&unusedTableIndex, &nothing, &nothing));
}
case uint16_t(MiscOp::TableSize): {
case uint32_t(MiscOp::TableSize): {
uint32_t unusedTableIndex;
CHECK(iter.readTableSize(&unusedTableIndex));
}
#endif
#ifdef ENABLE_WASM_GC
case uint16_t(MiscOp::StructNew): {
case uint32_t(MiscOp::StructNew): {
if (!env.gcTypesEnabled()) {
return iter.unrecognizedOpcode(&op);
}
@ -888,14 +888,14 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
ValidatingOpIter::ValueVector unusedArgs;
CHECK(iter.readStructNew(&unusedUint, &unusedArgs));
}
case uint16_t(MiscOp::StructGet): {
case uint32_t(MiscOp::StructGet): {
if (!env.gcTypesEnabled()) {
return iter.unrecognizedOpcode(&op);
}
uint32_t unusedUint1, unusedUint2;
CHECK(iter.readStructGet(&unusedUint1, &unusedUint2, &nothing));
}
case uint16_t(MiscOp::StructSet): {
case uint32_t(MiscOp::StructSet): {
if (!env.gcTypesEnabled()) {
return iter.unrecognizedOpcode(&op);
}
@ -903,7 +903,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
CHECK(iter.readStructSet(&unusedUint1, &unusedUint2, &nothing,
&nothing));
}
case uint16_t(MiscOp::StructNarrow): {
case uint32_t(MiscOp::StructNarrow): {
if (!env.gcTypesEnabled()) {
return iter.unrecognizedOpcode(&op);
}
@ -937,168 +937,168 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
#endif
case uint16_t(Op::ThreadPrefix): {
switch (op.b1) {
case uint16_t(ThreadOp::Wake): {
case uint32_t(ThreadOp::Wake): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readWake(&addr, &nothing));
}
case uint16_t(ThreadOp::I32Wait): {
case uint32_t(ThreadOp::I32Wait): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readWait(&addr, ValType::I32, 4, &nothing, &nothing));
}
case uint16_t(ThreadOp::I64Wait): {
case uint32_t(ThreadOp::I64Wait): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readWait(&addr, ValType::I64, 8, &nothing, &nothing));
}
case uint16_t(ThreadOp::I32AtomicLoad): {
case uint32_t(ThreadOp::I32AtomicLoad): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I32, 4));
}
case uint16_t(ThreadOp::I64AtomicLoad): {
case uint32_t(ThreadOp::I64AtomicLoad): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I64, 8));
}
case uint16_t(ThreadOp::I32AtomicLoad8U): {
case uint32_t(ThreadOp::I32AtomicLoad8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I32, 1));
}
case uint16_t(ThreadOp::I32AtomicLoad16U): {
case uint32_t(ThreadOp::I32AtomicLoad16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I32, 2));
}
case uint16_t(ThreadOp::I64AtomicLoad8U): {
case uint32_t(ThreadOp::I64AtomicLoad8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I64, 1));
}
case uint16_t(ThreadOp::I64AtomicLoad16U): {
case uint32_t(ThreadOp::I64AtomicLoad16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I64, 2));
}
case uint16_t(ThreadOp::I64AtomicLoad32U): {
case uint32_t(ThreadOp::I64AtomicLoad32U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicLoad(&addr, ValType::I64, 4));
}
case uint16_t(ThreadOp::I32AtomicStore): {
case uint32_t(ThreadOp::I32AtomicStore): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I32, 4, &nothing));
}
case uint16_t(ThreadOp::I64AtomicStore): {
case uint32_t(ThreadOp::I64AtomicStore): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I64, 8, &nothing));
}
case uint16_t(ThreadOp::I32AtomicStore8U): {
case uint32_t(ThreadOp::I32AtomicStore8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I32, 1, &nothing));
}
case uint16_t(ThreadOp::I32AtomicStore16U): {
case uint32_t(ThreadOp::I32AtomicStore16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I32, 2, &nothing));
}
case uint16_t(ThreadOp::I64AtomicStore8U): {
case uint32_t(ThreadOp::I64AtomicStore8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I64, 1, &nothing));
}
case uint16_t(ThreadOp::I64AtomicStore16U): {
case uint32_t(ThreadOp::I64AtomicStore16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I64, 2, &nothing));
}
case uint16_t(ThreadOp::I64AtomicStore32U): {
case uint32_t(ThreadOp::I64AtomicStore32U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicStore(&addr, ValType::I64, 4, &nothing));
}
case uint16_t(ThreadOp::I32AtomicAdd):
case uint16_t(ThreadOp::I32AtomicSub):
case uint16_t(ThreadOp::I32AtomicAnd):
case uint16_t(ThreadOp::I32AtomicOr):
case uint16_t(ThreadOp::I32AtomicXor):
case uint16_t(ThreadOp::I32AtomicXchg): {
case uint32_t(ThreadOp::I32AtomicAdd):
case uint32_t(ThreadOp::I32AtomicSub):
case uint32_t(ThreadOp::I32AtomicAnd):
case uint32_t(ThreadOp::I32AtomicOr):
case uint32_t(ThreadOp::I32AtomicXor):
case uint32_t(ThreadOp::I32AtomicXchg): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I32, 4, &nothing));
}
case uint16_t(ThreadOp::I64AtomicAdd):
case uint16_t(ThreadOp::I64AtomicSub):
case uint16_t(ThreadOp::I64AtomicAnd):
case uint16_t(ThreadOp::I64AtomicOr):
case uint16_t(ThreadOp::I64AtomicXor):
case uint16_t(ThreadOp::I64AtomicXchg): {
case uint32_t(ThreadOp::I64AtomicAdd):
case uint32_t(ThreadOp::I64AtomicSub):
case uint32_t(ThreadOp::I64AtomicAnd):
case uint32_t(ThreadOp::I64AtomicOr):
case uint32_t(ThreadOp::I64AtomicXor):
case uint32_t(ThreadOp::I64AtomicXchg): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I64, 8, &nothing));
}
case uint16_t(ThreadOp::I32AtomicAdd8U):
case uint16_t(ThreadOp::I32AtomicSub8U):
case uint16_t(ThreadOp::I32AtomicAnd8U):
case uint16_t(ThreadOp::I32AtomicOr8U):
case uint16_t(ThreadOp::I32AtomicXor8U):
case uint16_t(ThreadOp::I32AtomicXchg8U): {
case uint32_t(ThreadOp::I32AtomicAdd8U):
case uint32_t(ThreadOp::I32AtomicSub8U):
case uint32_t(ThreadOp::I32AtomicAnd8U):
case uint32_t(ThreadOp::I32AtomicOr8U):
case uint32_t(ThreadOp::I32AtomicXor8U):
case uint32_t(ThreadOp::I32AtomicXchg8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I32, 1, &nothing));
}
case uint16_t(ThreadOp::I32AtomicAdd16U):
case uint16_t(ThreadOp::I32AtomicSub16U):
case uint16_t(ThreadOp::I32AtomicAnd16U):
case uint16_t(ThreadOp::I32AtomicOr16U):
case uint16_t(ThreadOp::I32AtomicXor16U):
case uint16_t(ThreadOp::I32AtomicXchg16U): {
case uint32_t(ThreadOp::I32AtomicAdd16U):
case uint32_t(ThreadOp::I32AtomicSub16U):
case uint32_t(ThreadOp::I32AtomicAnd16U):
case uint32_t(ThreadOp::I32AtomicOr16U):
case uint32_t(ThreadOp::I32AtomicXor16U):
case uint32_t(ThreadOp::I32AtomicXchg16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I32, 2, &nothing));
}
case uint16_t(ThreadOp::I64AtomicAdd8U):
case uint16_t(ThreadOp::I64AtomicSub8U):
case uint16_t(ThreadOp::I64AtomicAnd8U):
case uint16_t(ThreadOp::I64AtomicOr8U):
case uint16_t(ThreadOp::I64AtomicXor8U):
case uint16_t(ThreadOp::I64AtomicXchg8U): {
case uint32_t(ThreadOp::I64AtomicAdd8U):
case uint32_t(ThreadOp::I64AtomicSub8U):
case uint32_t(ThreadOp::I64AtomicAnd8U):
case uint32_t(ThreadOp::I64AtomicOr8U):
case uint32_t(ThreadOp::I64AtomicXor8U):
case uint32_t(ThreadOp::I64AtomicXchg8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I64, 1, &nothing));
}
case uint16_t(ThreadOp::I64AtomicAdd16U):
case uint16_t(ThreadOp::I64AtomicSub16U):
case uint16_t(ThreadOp::I64AtomicAnd16U):
case uint16_t(ThreadOp::I64AtomicOr16U):
case uint16_t(ThreadOp::I64AtomicXor16U):
case uint16_t(ThreadOp::I64AtomicXchg16U): {
case uint32_t(ThreadOp::I64AtomicAdd16U):
case uint32_t(ThreadOp::I64AtomicSub16U):
case uint32_t(ThreadOp::I64AtomicAnd16U):
case uint32_t(ThreadOp::I64AtomicOr16U):
case uint32_t(ThreadOp::I64AtomicXor16U):
case uint32_t(ThreadOp::I64AtomicXchg16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I64, 2, &nothing));
}
case uint16_t(ThreadOp::I64AtomicAdd32U):
case uint16_t(ThreadOp::I64AtomicSub32U):
case uint16_t(ThreadOp::I64AtomicAnd32U):
case uint16_t(ThreadOp::I64AtomicOr32U):
case uint16_t(ThreadOp::I64AtomicXor32U):
case uint16_t(ThreadOp::I64AtomicXchg32U): {
case uint32_t(ThreadOp::I64AtomicAdd32U):
case uint32_t(ThreadOp::I64AtomicSub32U):
case uint32_t(ThreadOp::I64AtomicAnd32U):
case uint32_t(ThreadOp::I64AtomicOr32U):
case uint32_t(ThreadOp::I64AtomicXor32U):
case uint32_t(ThreadOp::I64AtomicXchg32U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicRMW(&addr, ValType::I64, 4, &nothing));
}
case uint16_t(ThreadOp::I32AtomicCmpXchg): {
case uint32_t(ThreadOp::I32AtomicCmpXchg): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I32, 4, &nothing,
&nothing));
}
case uint16_t(ThreadOp::I64AtomicCmpXchg): {
case uint32_t(ThreadOp::I64AtomicCmpXchg): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 8, &nothing,
&nothing));
}
case uint16_t(ThreadOp::I32AtomicCmpXchg8U): {
case uint32_t(ThreadOp::I32AtomicCmpXchg8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I32, 1, &nothing,
&nothing));
}
case uint16_t(ThreadOp::I32AtomicCmpXchg16U): {
case uint32_t(ThreadOp::I32AtomicCmpXchg16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I32, 2, &nothing,
&nothing));
}
case uint16_t(ThreadOp::I64AtomicCmpXchg8U): {
case uint32_t(ThreadOp::I64AtomicCmpXchg8U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 1, &nothing,
&nothing));
}
case uint16_t(ThreadOp::I64AtomicCmpXchg16U): {
case uint32_t(ThreadOp::I64AtomicCmpXchg16U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 2, &nothing,
&nothing));
}
case uint16_t(ThreadOp::I64AtomicCmpXchg32U): {
case uint32_t(ThreadOp::I64AtomicCmpXchg32U): {
LinearMemoryAddress<Nothing> addr;
CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 4, &nothing,
&nothing));

Просмотреть файл

@ -345,19 +345,16 @@ class Encoder {
return writeFixedU8(uint8_t(op));
}
MOZ_MUST_USE bool writeOp(MiscOp op) {
static_assert(size_t(MiscOp::Limit) <= 256, "fits");
MOZ_ASSERT(size_t(op) < size_t(MiscOp::Limit));
return writeFixedU8(uint8_t(Op::MiscPrefix)) && writeFixedU8(uint8_t(op));
return writeFixedU8(uint8_t(Op::MiscPrefix)) && writeVarU32(uint32_t(op));
}
MOZ_MUST_USE bool writeOp(ThreadOp op) {
static_assert(size_t(ThreadOp::Limit) <= 256, "fits");
MOZ_ASSERT(size_t(op) < size_t(ThreadOp::Limit));
return writeFixedU8(uint8_t(Op::ThreadPrefix)) && writeFixedU8(uint8_t(op));
return writeFixedU8(uint8_t(Op::ThreadPrefix)) && writeVarU32(uint32_t(op));
}
MOZ_MUST_USE bool writeOp(MozOp op) {
static_assert(size_t(MozOp::Limit) <= 256, "fits");
MOZ_ASSERT(size_t(op) < size_t(MozOp::Limit));
return writeFixedU8(uint8_t(Op::MozPrefix)) && writeFixedU8(uint8_t(op));
return writeFixedU8(uint8_t(Op::MozPrefix)) && writeVarU32(uint32_t(op));
}
// Fixed-length encodings that allow back-patching.

Просмотреть файл

@ -8,8 +8,8 @@ crate-type = ["rlib"]
name = "baldrdash"
[dependencies]
cranelift-codegen = "0.28.0"
cranelift-wasm = "0.28.0"
cranelift-codegen = "0.29.0"
cranelift-wasm = "0.29.0"
target-lexicon = "0.2.0"
log = { version = "0.4.6", default-features = false, features = ["release_max_level_info"] }
env_logger = "0.5.6"

Просмотреть файл

@ -83,7 +83,8 @@ struct CraneliftStaticEnvironment {
// contains.
struct CraneliftModuleEnvironment {
const js::wasm::ModuleEnvironment& env;
// This is a pointer and not a reference to work-around a bug in bindgen.
const js::wasm::ModuleEnvironment* env;
uint32_t min_memory_length;
// Not bindgen'd because it's inlined.
@ -99,6 +100,7 @@ struct CraneliftFuncCompileInput {
const uint8_t* bytecode;
size_t bytecodeSize;
uint32_t index;
uint32_t offset_in_module;
// Not bindgen'd because it's inlined.
explicit inline CraneliftFuncCompileInput(const js::wasm::FuncCompileInput&);
@ -119,8 +121,8 @@ struct CraneliftMetadataEntry {
MemoryAccess,
SymbolicAccess
} which;
uint32_t offset;
uint32_t srcLoc;
uint32_t offset; // relative to the beginning of the function generated code
uint32_t srcLoc; // relative to the beginning of the module bytecode
size_t extra;
};

Просмотреть файл

@ -106,8 +106,12 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
self.context.func.name = wasm_function_name(index);
let tenv = &mut TransEnv::new(&*self.isa, &self.environ, self.static_environ);
self.trans
.translate(func.bytecode(), &mut self.context.func, tenv)?;
self.trans.translate(
func.bytecode(),
func.offset_in_module as usize,
&mut self.context.func,
tenv,
)?;
info!("Translated wasm function {}.", func.index);
debug!("Content: {}", self.context.func.display(&*self.isa));

Просмотреть файл

@ -1301,9 +1301,9 @@ pref("dom.serviceWorkers.disable_open_click_delay", 1000);
pref("dom.storage.enabled", true);
// Whether or not LSNG (Next Generation Local Storage) is enabled.
// See bug 1510410 for enabling this on Nightly.
// See bug 1517090 for enabling this on Nightly.
#ifdef NIGHTLY_BUILD
pref("dom.storage.next_gen", false);
pref("dom.storage.next_gen", true);
#else
pref("dom.storage.next_gen", false);
#endif

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"71b82e879926d62dea538644a84ae5e6274f5a57dd7ef3edfc5ae95e2a804986","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"1b23abbfe5850a4cd77ae6ae5dcfc2f678ef36b4032fd7496f2b333c51e63301","src/map.rs":"5d891d62814941e19dfc88ff36538efa3da5479f3f97de8219a6f610c9a1ee32","src/node.rs":"e620c64e78488035f11723b14892c7986c06ad37dc5b115a35a453ff1ae66ca3","src/path.rs":"4868e59ff67db1c504747e4b7e202dd20c9da4cbd73d9fa82d53e5f3406dbb78","src/pool.rs":"6090f8c0e0da16ebee0e31bca66392d0075b3aff529d30d4e716fa20cd0aef99","src/set.rs":"b411158f813a310c7a6c337d4ada3bf0a021088c443875dc25233415dcbe0633"},"package":"c88db0c2fc38b2cedee1b94ee2dc7bf80e4ce31467c8005743f485af66e240d8"}
{"files":{"Cargo.toml":"d6c5cca60972e64e1abb435d2af6bf8af2fec2d5988d0fda9827f6bba1f6a47c","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"1b23abbfe5850a4cd77ae6ae5dcfc2f678ef36b4032fd7496f2b333c51e63301","src/map.rs":"5d891d62814941e19dfc88ff36538efa3da5479f3f97de8219a6f610c9a1ee32","src/node.rs":"e620c64e78488035f11723b14892c7986c06ad37dc5b115a35a453ff1ae66ca3","src/path.rs":"4868e59ff67db1c504747e4b7e202dd20c9da4cbd73d9fa82d53e5f3406dbb78","src/pool.rs":"6090f8c0e0da16ebee0e31bca66392d0075b3aff529d30d4e716fa20cd0aef99","src/set.rs":"b411158f813a310c7a6c337d4ada3bf0a021088c443875dc25233415dcbe0633"},"package":"a3a25dfe4a54449df63d592f2f6346a80350ac835d4be4bacb73c20b034ef763"}

Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "cranelift-bforest"
version = "0.28.0"
version = "0.29.0"
authors = ["The Cranelift Project Developers"]
description = "A forest of B+-trees"
documentation = "https://cranelift.readthedocs.io/"
@ -23,7 +23,7 @@ categories = ["no-std"]
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/CraneStation/cranelift"
[dependencies.cranelift-entity]
version = "0.28.0"
version = "0.29.0"
default-features = false
[features]

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"05bb65ad8427efad48f44eac2db25961e6b56374941edf54912469a7b1e7110e","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/base/mod.rs":"559075f0b76a744dd36224e06ff1c2e28ee70aaca9442fc724b116e37028ac52","src/base/settings.rs":"bc6a15221d688bf63114c53493d31070860eb7fae208596374488404a65ee41a","src/base/types.rs":"a3e449db1f515d268f3ad21301740ba415444d399f8433dbc48979f78557f66a","src/cdsl/isa.rs":"5c9a8173466e69d105245396abd342251eb00e704ab13f179ba1567b339f47e1","src/cdsl/mod.rs":"66ac1b5d095e431bcab88c4b9c5b1492a5d1ca87bcb9c9c3e544ede05b2ba925","src/cdsl/regs.rs":"c45809713e8bf9d097c75991ff8dd4ca215a97e9f83df6407dcc09d76e6fbddb","src/cdsl/settings.rs":"4ddeadf1542cc2ddec0f9e6c22d1637050da519586cd9fec0243c3eab9619f82","src/cdsl/types.rs":"82aff98c094a564ed1a11ca7628bfba66c363d5fff278babbf26a4252b3a5107","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_registers.rs":"cee8f9d4ad1d07e5bd59a9ca875ede3e4143ec4c97b5fd56c3e6f8b1dea64a53","src/gen_settings.rs":"c89aaecf6b6b53e229d052db90ffc43d11b5a69974961615437608ac705ae0dd","src/gen_types.rs":"9b8a06cd025fcb67e2f98f2b3c4697e551119997fd7254dc9ed2f9c5d2e2aa1c","src/isa/arm32/mod.rs":"741da8a24aa31919458349663e0a24e03727a7c2a72d5ebd813c2162cb19c65c","src/isa/arm64/mod.rs":"2b384d84fb2a1b53d6f3882ca18d8b9027161193493361a95406fa357a0822fa","src/isa/mod.rs":"c5ea6469fe770d49ceaa4b9c6370d8df2ac55fffc076fb3852fc5bbc8c096c2b","src/isa/riscv/mod.rs":"690a285d8185e38ad3134ac1dcd1e550e346ebb349f90c7b8b68b38ddd4b7a1f","src/isa/x86/mod.rs":"712a16bc2e0e50112f92bfbc5963e4548db5f701d5f14fd344df5fc76753f641","src/lib.rs":"995c6f1d6e8ca9dda8838b96c92f37f7c78d6d555e1f05b3700a1271760a161c","src/srcgen.rs":"a51b6f7b61110d958c541bc8de61592cb93cca0d6d46b2f5ffe47fca8feedae8","src/unique_table.rs":"f6041df1fa85f2a1ee914b84791e80165a0858a6253c212eaa99ff67cb56af26"},"package":"43131e662da7e0243cff28edfbc094a62968a4b57849f77a6c1e3685e9e6e1e6"}
{"files":{"Cargo.toml":"f5ea16920dd3c3f9c1ef903e26b10a913cafb5ac30eb36deabca977de04a62ae","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/isa.rs":"d3ddfc8bd3d691df034a1bacfa27b3e29eb2e7a30923508fa5c7af8d89e8a962","src/cdsl/mod.rs":"66ac1b5d095e431bcab88c4b9c5b1492a5d1ca87bcb9c9c3e544ede05b2ba925","src/cdsl/regs.rs":"b99f24c3ecb46691625dc177b4e18d53e02265bc85a2f827a8d18381fe8f39bb","src/cdsl/settings.rs":"4ddeadf1542cc2ddec0f9e6c22d1637050da519586cd9fec0243c3eab9619f82","src/cdsl/types.rs":"981ebe748973bdf2dee00fa71784f6dcaa6c7648442665f34a59ad97a05fe888","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_registers.rs":"75bbbc0f8dd546c88ed52f350175656300e35e871382a7508e7123e32d4bee1e","src/gen_settings.rs":"4689ede4e460bfcc19511c1055ba359b52f248f4a6d3afd62b1d23bc493b37a1","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"f5b0cbbb2f6c7f00bb9a9bc6f0b1120477ff7ff683a95a6cdbbeed1677b0c9c8","src/isa/arm64/mod.rs":"c234b0df3d36d6d8765ead548e43b5304480e79da9697e14f9d98525919921b3","src/isa/mod.rs":"7038e3aa629afc28707fea379237d3c161ab459d552160438ac75e1137c6246a","src/isa/riscv/mod.rs":"322220fa67cf8623eeb27c7d23f3cc34e05873860248ae99fd02af452c232383","src/isa/x86/mod.rs":"c9183448ffe378e599ec7dc6ae7180c97d3e11d15d7644b93eb1e4a3543222f2","src/lib.rs":"4c73b35cbd68aab9b9c8c86bb71f67555e0e15f36a22101e086a346b01ee8cfb","src/shared/mod.rs":"87b55c291c5e73a9d7cd9a0ebfc8e59501956195268673d0d980de58694f4741","src/shared/settings.rs":"bc6a15221d688bf63114c53493d31070860eb7fae208596374488404a65ee41a","src/shared/types.rs":"a3e449db1f515d268f3ad21301740ba415444d399f8433dbc48979f78557f66a","src/srcgen.rs":"72435db1e0c984d95c5c5aa758907ed79eaec41ca3203ac661c6acd64c19acce","src/unique_table.rs":"f6041df1fa85f2a1ee914b84791e80165a0858a6253c212eaa99ff67cb56af26"},"package":"3e60ce3551e8172c966fbc6d9bfb90111d5d1cf37306c37dd7527467afe317d1"}

Просмотреть файл

@ -13,14 +13,14 @@
[package]
edition = "2018"
name = "cranelift-codegen-meta"
version = "0.28.0"
version = "0.29.0"
authors = ["The Cranelift Project Developers"]
description = "Metaprogram for cranelift-codegen code generator library"
readme = "README.md"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/CraneStation/cranelift"
[dependencies.cranelift-entity]
version = "0.28.0"
version = "0.29.0"
[badges.maintenance]
status = "experimental"

Просмотреть файл

@ -1,4 +0,0 @@
//! Definitions for the base Cranelift language.
pub mod settings;
pub mod types;

Просмотреть файл

@ -1,192 +1,18 @@
use cranelift_entity::PrimaryMap;
use super::regs::{
RegBank, RegBankBuilder, RegBankIndex, RegClass, RegClassBuilder, RegClassIndex, RegClassProto,
};
use super::regs::IsaRegs;
use super::settings::SettingGroup;
pub struct TargetIsa {
pub name: &'static str,
pub reg_banks: PrimaryMap<RegBankIndex, RegBank>,
pub reg_classes: PrimaryMap<RegClassIndex, RegClass>,
pub settings: SettingGroup,
pub regs: IsaRegs,
}
impl TargetIsa {
pub fn new(name: &'static str, settings: SettingGroup) -> Self {
pub fn new(name: &'static str, settings: SettingGroup, regs: IsaRegs) -> Self {
Self {
name,
reg_banks: PrimaryMap::new(),
reg_classes: PrimaryMap::new(),
settings,
regs,
}
}
}
pub struct TargetIsaBuilder {
isa: TargetIsa,
}
impl TargetIsaBuilder {
pub fn new(name: &'static str, settings: SettingGroup) -> Self {
Self {
isa: TargetIsa::new(name, settings),
}
}
pub fn add_reg_bank(&mut self, builder: RegBankBuilder) -> RegBankIndex {
let first_unit = if self.isa.reg_banks.len() == 0 {
0
} else {
let last = &self.isa.reg_banks.last().unwrap();
let first_available_unit = (last.first_unit + last.units) as i8;
let units = builder.units;
let align = if units.is_power_of_two() {
units
} else {
units.next_power_of_two()
} as i8;
(first_available_unit + align - 1) & -align
} as u8;
self.isa.reg_banks.push(RegBank::new(
builder.name,
first_unit,
builder.units,
builder.names,
builder.prefix,
builder
.pressure_tracking
.expect("Pressure tracking must be explicitly set"),
))
}
pub fn add_reg_class(&mut self, builder: RegClassBuilder) -> RegClassIndex {
let class_index = self.isa.reg_classes.next_key();
// Finish delayed construction of RegClass.
let (bank, toprc, start, width) = match builder.proto {
RegClassProto::TopLevel(bank_index) => {
self.isa
.reg_banks
.get_mut(bank_index)
.unwrap()
.toprcs
.push(class_index);
(bank_index, class_index, builder.start, builder.width)
}
RegClassProto::SubClass(parent_class_index) => {
assert!(builder.width == 0);
let (bank, toprc, start, width) = {
let parent = self.isa.reg_classes.get(parent_class_index).unwrap();
(parent.bank, parent.toprc, parent.start, parent.width)
};
for reg_class in self.isa.reg_classes.values_mut() {
if reg_class.toprc == toprc {
reg_class.subclasses.push(class_index);
}
}
let subclass_start = start + builder.start * width;
(bank, toprc, subclass_start, width)
}
};
let reg_bank_units = self.isa.reg_banks.get(bank).unwrap().units;
assert!(start < reg_bank_units);
let count = if builder.count != 0 {
builder.count
} else {
reg_bank_units / width
};
let reg_class = RegClass::new(builder.name, class_index, width, bank, toprc, count, start);
self.isa.reg_classes.push(reg_class);
let reg_bank = self.isa.reg_banks.get_mut(bank).unwrap();
reg_bank.classes.push(class_index);
class_index
}
/// Checks that the set of register classes satisfies:
///
/// 1. Closed under intersection: The intersection of any two register
/// classes in the set is either empty or identical to a member of the
/// set.
/// 2. There are no identical classes under different names.
/// 3. Classes are sorted topologically such that all subclasses have a
/// higher index that the superclass.
pub fn finish(self) -> TargetIsa {
for reg_bank in self.isa.reg_banks.values() {
for i1 in reg_bank.classes.iter() {
for i2 in reg_bank.classes.iter() {
if i1 >= i2 {
continue;
}
let rc1 = self.isa.reg_classes.get(*i1).unwrap();
let rc2 = self.isa.reg_classes.get(*i2).unwrap();
let rc1_mask = rc1.mask(0);
let rc2_mask = rc2.mask(0);
assert!(
rc1.width != rc2.width || rc1_mask != rc2_mask,
"no duplicates"
);
if rc1.width != rc2.width {
continue;
}
let mut intersect = Vec::new();
for (a, b) in rc1_mask.iter().zip(rc2_mask.iter()) {
intersect.push(a & b);
}
if intersect == vec![0; intersect.len()] {
continue;
}
// Classes must be topologically ordered, so the intersection can't be the
// superclass.
assert!(intersect != rc1_mask);
// If the intersection is the second one, then it must be a subclass.
if intersect == rc2_mask {
assert!(self
.isa
.reg_classes
.get(*i1)
.unwrap()
.subclasses
.iter()
.find(|x| **x == *i2)
.is_some());
}
}
}
}
// This limit should be coordinated with the `RegClassMask` and `RegClassIndex` types in
// isa/registers.rs of the non-meta code.
assert!(
self.isa.reg_classes.len() <= 32,
"Too many register classes"
);
// The maximum number of top-level register classes which have pressure tracking should be
// kept in sync with the MAX_TRACKED_TOPRCS constant in isa/registers.rs of the non-meta
// code.
let num_toplevel = self
.isa
.reg_classes
.values()
.filter(|x| {
x.toprc == x.index && self.isa.reg_banks.get(x.bank).unwrap().pressure_tracking
})
.count();
assert!(num_toplevel <= 4, "Too many top-level register classes");
self.isa
}
}

Просмотреть файл

@ -1,5 +1,4 @@
use cranelift_entity::entity_impl;
use cranelift_entity::EntityRef;
use cranelift_entity::{entity_impl, EntityRef, PrimaryMap};
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct RegBankIndex(u32);
@ -178,3 +177,179 @@ impl RegBankBuilder {
self
}
}
pub struct IsaRegsBuilder {
pub banks: PrimaryMap<RegBankIndex, RegBank>,
pub classes: PrimaryMap<RegClassIndex, RegClass>,
}
impl IsaRegsBuilder {
pub fn new() -> Self {
Self {
banks: PrimaryMap::new(),
classes: PrimaryMap::new(),
}
}
pub fn add_bank(&mut self, builder: RegBankBuilder) -> RegBankIndex {
let first_unit = if self.banks.len() == 0 {
0
} else {
let last = &self.banks.last().unwrap();
let first_available_unit = (last.first_unit + last.units) as i8;
let units = builder.units;
let align = if units.is_power_of_two() {
units
} else {
units.next_power_of_two()
} as i8;
(first_available_unit + align - 1) & -align
} as u8;
self.banks.push(RegBank::new(
builder.name,
first_unit,
builder.units,
builder.names,
builder.prefix,
builder
.pressure_tracking
.expect("Pressure tracking must be explicitly set"),
))
}
pub fn add_class(&mut self, builder: RegClassBuilder) -> RegClassIndex {
let class_index = self.classes.next_key();
// Finish delayed construction of RegClass.
let (bank, toprc, start, width) = match builder.proto {
RegClassProto::TopLevel(bank_index) => {
self.banks
.get_mut(bank_index)
.unwrap()
.toprcs
.push(class_index);
(bank_index, class_index, builder.start, builder.width)
}
RegClassProto::SubClass(parent_class_index) => {
assert!(builder.width == 0);
let (bank, toprc, start, width) = {
let parent = self.classes.get(parent_class_index).unwrap();
(parent.bank, parent.toprc, parent.start, parent.width)
};
for reg_class in self.classes.values_mut() {
if reg_class.toprc == toprc {
reg_class.subclasses.push(class_index);
}
}
let subclass_start = start + builder.start * width;
(bank, toprc, subclass_start, width)
}
};
let reg_bank_units = self.banks.get(bank).unwrap().units;
assert!(start < reg_bank_units);
let count = if builder.count != 0 {
builder.count
} else {
reg_bank_units / width
};
let reg_class = RegClass::new(builder.name, class_index, width, bank, toprc, count, start);
self.classes.push(reg_class);
let reg_bank = self.banks.get_mut(bank).unwrap();
reg_bank.classes.push(class_index);
class_index
}
/// Checks that the set of register classes satisfies:
///
/// 1. Closed under intersection: The intersection of any two register
/// classes in the set is either empty or identical to a member of the
/// set.
/// 2. There are no identical classes under different names.
/// 3. Classes are sorted topologically such that all subclasses have a
/// higher index that the superclass.
pub fn finish(self) -> IsaRegs {
for reg_bank in self.banks.values() {
for i1 in reg_bank.classes.iter() {
for i2 in reg_bank.classes.iter() {
if i1 >= i2 {
continue;
}
let rc1 = self.classes.get(*i1).unwrap();
let rc2 = self.classes.get(*i2).unwrap();
let rc1_mask = rc1.mask(0);
let rc2_mask = rc2.mask(0);
assert!(
rc1.width != rc2.width || rc1_mask != rc2_mask,
"no duplicates"
);
if rc1.width != rc2.width {
continue;
}
let mut intersect = Vec::new();
for (a, b) in rc1_mask.iter().zip(rc2_mask.iter()) {
intersect.push(a & b);
}
if intersect == vec![0; intersect.len()] {
continue;
}
// Classes must be topologically ordered, so the intersection can't be the
// superclass.
assert!(intersect != rc1_mask);
// If the intersection is the second one, then it must be a subclass.
if intersect == rc2_mask {
assert!(self
.classes
.get(*i1)
.unwrap()
.subclasses
.iter()
.find(|x| **x == *i2)
.is_some());
}
}
}
}
// This limit should be coordinated with the `RegClassMask` and `RegClassIndex` types in
// isa/registers.rs of the non-meta code.
assert!(self.classes.len() <= 32, "Too many register classes");
// The maximum number of top-level register classes which have pressure tracking should be
// kept in sync with the MAX_TRACKED_TOPRCS constant in isa/registers.rs of the non-meta
// code.
let num_toplevel = self
.classes
.values()
.filter(|x| x.toprc == x.index && self.banks.get(x.bank).unwrap().pressure_tracking)
.count();
assert!(num_toplevel <= 4, "Too many top-level register classes");
IsaRegs::new(self.banks, self.classes)
}
}
pub struct IsaRegs {
pub banks: PrimaryMap<RegBankIndex, RegBank>,
pub classes: PrimaryMap<RegClassIndex, RegClass>,
}
impl IsaRegs {
fn new(
banks: PrimaryMap<RegBankIndex, RegBank>,
classes: PrimaryMap<RegClassIndex, RegClass>,
) -> Self {
Self { banks, classes }
}
}

Просмотреть файл

@ -5,7 +5,7 @@
use std::fmt;
use crate::base::types as base_types;
use crate::shared::types as shared_types;
// Numbering scheme for value types:
//
@ -149,9 +149,9 @@ impl From<VectorType> for ValueType {
/// A concrete scalar type that can appear as a vector lane too.
#[derive(Clone, Copy)]
pub enum LaneType {
BoolType(base_types::Bool),
FloatType(base_types::Float),
IntType(base_types::Int),
BoolType(shared_types::Bool),
FloatType(shared_types::Float),
IntType(shared_types::Int),
}
impl LaneType {
@ -159,12 +159,12 @@ impl LaneType {
pub fn doc(self) -> String {
match self {
LaneType::BoolType(_) => format!("A boolean type with {} bits.", self.lane_bits()),
LaneType::FloatType(base_types::Float::F32) => String::from(
LaneType::FloatType(shared_types::Float::F32) => String::from(
"A 32-bit floating point type represented in the IEEE 754-2008
*binary32* interchange format. This corresponds to the :c:type:`float`
type in most C implementations.",
),
LaneType::FloatType(base_types::Float::F64) => String::from(
LaneType::FloatType(shared_types::Float::F64) => String::from(
"A 64-bit floating point type represented in the IEEE 754-2008
*binary64* interchange format. This corresponds to the :c:type:`double`
type in most C implementations.",
@ -192,17 +192,17 @@ impl LaneType {
pub fn number(self) -> u8 {
LANE_BASE
+ match self {
LaneType::BoolType(base_types::Bool::B1) => 0,
LaneType::BoolType(base_types::Bool::B8) => 1,
LaneType::BoolType(base_types::Bool::B16) => 2,
LaneType::BoolType(base_types::Bool::B32) => 3,
LaneType::BoolType(base_types::Bool::B64) => 4,
LaneType::IntType(base_types::Int::I8) => 5,
LaneType::IntType(base_types::Int::I16) => 6,
LaneType::IntType(base_types::Int::I32) => 7,
LaneType::IntType(base_types::Int::I64) => 8,
LaneType::FloatType(base_types::Float::F32) => 9,
LaneType::FloatType(base_types::Float::F64) => 10,
LaneType::BoolType(shared_types::Bool::B1) => 0,
LaneType::BoolType(shared_types::Bool::B8) => 1,
LaneType::BoolType(shared_types::Bool::B16) => 2,
LaneType::BoolType(shared_types::Bool::B32) => 3,
LaneType::BoolType(shared_types::Bool::B64) => 4,
LaneType::IntType(shared_types::Int::I8) => 5,
LaneType::IntType(shared_types::Int::I16) => 6,
LaneType::IntType(shared_types::Int::I32) => 7,
LaneType::IntType(shared_types::Int::I64) => 8,
LaneType::FloatType(shared_types::Float::F32) => 9,
LaneType::FloatType(shared_types::Float::F64) => 10,
}
}
}
@ -233,40 +233,40 @@ impl fmt::Debug for LaneType {
}
/// Create a LaneType from a given bool variant.
impl From<base_types::Bool> for LaneType {
fn from(b: base_types::Bool) -> Self {
impl From<shared_types::Bool> for LaneType {
fn from(b: shared_types::Bool) -> Self {
LaneType::BoolType(b)
}
}
/// Create a LaneType from a given float variant.
impl From<base_types::Float> for LaneType {
fn from(f: base_types::Float) -> Self {
impl From<shared_types::Float> for LaneType {
fn from(f: shared_types::Float) -> Self {
LaneType::FloatType(f)
}
}
/// Create a LaneType from a given int variant.
impl From<base_types::Int> for LaneType {
fn from(i: base_types::Int) -> Self {
impl From<shared_types::Int> for LaneType {
fn from(i: shared_types::Int) -> Self {
LaneType::IntType(i)
}
}
/// An iterator for different lane types.
pub struct LaneTypeIterator {
bool_iter: base_types::BoolIterator,
int_iter: base_types::IntIterator,
float_iter: base_types::FloatIterator,
bool_iter: shared_types::BoolIterator,
int_iter: shared_types::IntIterator,
float_iter: shared_types::FloatIterator,
}
impl LaneTypeIterator {
/// Create a new lane type iterator.
fn new() -> Self {
Self {
bool_iter: base_types::BoolIterator::new(),
int_iter: base_types::IntIterator::new(),
float_iter: base_types::FloatIterator::new(),
bool_iter: shared_types::BoolIterator::new(),
int_iter: shared_types::IntIterator::new(),
float_iter: shared_types::FloatIterator::new(),
}
}
}
@ -388,18 +388,18 @@ impl fmt::Debug for BVType {
/// Special types cannot be used to form vectors.
#[derive(Clone, Copy)]
pub enum SpecialType {
Flag(base_types::Flag),
Flag(shared_types::Flag),
}
impl SpecialType {
/// Return a string containing the documentation comment for this special type.
pub fn doc(self) -> String {
match self {
SpecialType::Flag(base_types::Flag::IFlags) => String::from(
SpecialType::Flag(shared_types::Flag::IFlags) => String::from(
"CPU flags representing the result of an integer comparison. These flags
can be tested with an :type:`intcc` condition code.",
),
SpecialType::Flag(base_types::Flag::FFlags) => String::from(
SpecialType::Flag(shared_types::Flag::FFlags) => String::from(
"CPU flags representing the result of a floating point comparison. These
flags can be tested with a :type:`floatcc` condition code.",
),
@ -416,8 +416,8 @@ impl SpecialType {
/// Find the unique number associated with this special type.
pub fn number(self) -> u8 {
match self {
SpecialType::Flag(base_types::Flag::IFlags) => 1,
SpecialType::Flag(base_types::Flag::FFlags) => 2,
SpecialType::Flag(shared_types::Flag::IFlags) => 1,
SpecialType::Flag(shared_types::Flag::FFlags) => 2,
}
}
}
@ -425,8 +425,8 @@ impl SpecialType {
impl fmt::Display for SpecialType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SpecialType::Flag(base_types::Flag::IFlags) => write!(f, "iflags"),
SpecialType::Flag(base_types::Flag::FFlags) => write!(f, "fflags"),
SpecialType::Flag(shared_types::Flag::IFlags) => write!(f, "iflags"),
SpecialType::Flag(shared_types::Flag::FFlags) => write!(f, "fflags"),
}
}
}
@ -443,20 +443,20 @@ impl fmt::Debug for SpecialType {
}
}
impl From<base_types::Flag> for SpecialType {
fn from(f: base_types::Flag) -> Self {
impl From<shared_types::Flag> for SpecialType {
fn from(f: shared_types::Flag) -> Self {
SpecialType::Flag(f)
}
}
pub struct SpecialTypeIterator {
flag_iter: base_types::FlagIterator,
flag_iter: shared_types::FlagIterator,
}
impl SpecialTypeIterator {
fn new() -> Self {
Self {
flag_iter: base_types::FlagIterator::new(),
flag_iter: shared_types::FlagIterator::new(),
}
}
}

Просмотреть файл

@ -10,29 +10,30 @@ fn gen_regbank(fmt: &mut Formatter, reg_bank: &RegBank) {
} else {
"".to_string()
};
fmt.line("RegBank {");
fmtln!(fmt, "RegBank {");
fmt.indent(|fmt| {
fmt.line(&format!(r#"name: "{}","#, reg_bank.name));
fmt.line(&format!("first_unit: {},", reg_bank.first_unit));
fmt.line(&format!("units: {},", reg_bank.units));
fmt.line(&format!("names: &[{}],", names));
fmt.line(&format!(r#"prefix: "{}","#, reg_bank.prefix));
fmt.line(&format!("first_toprc: {},", reg_bank.toprcs[0].index()));
fmt.line(&format!("num_toprcs: {},", reg_bank.toprcs.len()));
fmt.line(&format!(
fmtln!(fmt, r#"name: "{}","#, reg_bank.name);
fmtln!(fmt, "first_unit: {},", reg_bank.first_unit);
fmtln!(fmt, "units: {},", reg_bank.units);
fmtln!(fmt, "names: &[{}],", names);
fmtln!(fmt, r#"prefix: "{}","#, reg_bank.prefix);
fmtln!(fmt, "first_toprc: {},", reg_bank.toprcs[0].index());
fmtln!(fmt, "num_toprcs: {},", reg_bank.toprcs.len());
fmtln!(
fmt,
"pressure_tracking: {},",
if reg_bank.pressure_tracking {
"true"
} else {
"false"
}
));
);
});
fmt.line("},");
fmtln!(fmt, "},");
}
fn gen_regclass(isa: &TargetIsa, reg_class: &RegClass, fmt: &mut Formatter) {
let reg_bank = isa.reg_banks.get(reg_class.bank).unwrap();
let reg_bank = isa.regs.banks.get(reg_class.bank).unwrap();
let mask: Vec<String> = reg_class
.mask(reg_bank.first_unit)
@ -41,98 +42,99 @@ fn gen_regclass(isa: &TargetIsa, reg_class: &RegClass, fmt: &mut Formatter) {
.collect();
let mask = mask.join(", ");
fmt.line(&format!(
fmtln!(
fmt,
"pub static {}_DATA: RegClassData = RegClassData {{",
reg_class.name
));
);
fmt.indent(|fmt| {
fmt.line(&format!(r#"name: "{}","#, reg_class.name));
fmt.line(&format!("index: {},", reg_class.index.index()));
fmt.line(&format!("width: {},", reg_class.width));
fmt.line(&format!("bank: {},", reg_class.bank.index()));
fmt.line(&format!("toprc: {},", reg_class.toprc.index()));
fmt.line(&format!(
"first: {},",
reg_bank.first_unit + reg_class.start
));
fmt.line(&format!("subclasses: {:#x},", reg_class.subclass_mask()));
fmt.line(&format!("mask: [{}],", mask));
fmt.line("info: &INFO,");
fmtln!(fmt, r#"name: "{}","#, reg_class.name);
fmtln!(fmt, "index: {},", reg_class.index.index());
fmtln!(fmt, "width: {},", reg_class.width);
fmtln!(fmt, "bank: {},", reg_class.bank.index());
fmtln!(fmt, "toprc: {},", reg_class.toprc.index());
fmtln!(fmt, "first: {},", reg_bank.first_unit + reg_class.start);
fmtln!(fmt, "subclasses: {:#x},", reg_class.subclass_mask());
fmtln!(fmt, "mask: [{}],", mask);
fmtln!(fmt, "info: &INFO,");
});
fmt.line("};");
fmt.line("#[allow(dead_code)]");
fmt.line(&format!(
fmtln!(fmt, "};");
fmtln!(fmt, "#[allow(dead_code)]");
fmtln!(
fmt,
"pub static {}: RegClass = &{}_DATA;",
reg_class.name, reg_class.name
));
reg_class.name,
reg_class.name
);
}
fn gen_regbank_units(reg_bank: &RegBank, fmt: &mut Formatter) {
for unit in 0..reg_bank.units {
let v = unit + reg_bank.first_unit;
if (unit as usize) < reg_bank.names.len() {
fmt.line(&format!("{} = {},", reg_bank.names[unit as usize], v));
fmtln!(fmt, "{} = {},", reg_bank.names[unit as usize], v);
continue;
}
fmt.line(&format!("{}{} = {},", reg_bank.prefix, unit, v));
fmtln!(fmt, "{}{} = {},", reg_bank.prefix, unit, v);
}
}
fn gen_isa(isa: &TargetIsa, fmt: &mut Formatter) {
// Emit RegInfo.
fmt.line("pub static INFO: RegInfo = RegInfo {");
fmtln!(fmt, "pub static INFO: RegInfo = RegInfo {");
fmt.indent(|fmt| {
fmt.line("banks: &[");
fmtln!(fmt, "banks: &[");
// Bank descriptors.
fmt.indent(|fmt| {
for reg_bank in isa.reg_banks.values() {
for reg_bank in isa.regs.banks.values() {
gen_regbank(fmt, &reg_bank);
}
});
fmt.line("],");
fmtln!(fmt, "],");
// References to register classes.
fmt.line("classes: &[");
fmtln!(fmt, "classes: &[");
fmt.indent(|fmt| {
for reg_class in isa.reg_classes.values() {
fmt.line(&format!("&{}_DATA,", reg_class.name));
for reg_class in isa.regs.classes.values() {
fmtln!(fmt, "&{}_DATA,", reg_class.name);
}
});
fmt.line("],");
fmtln!(fmt, "],");
});
fmt.line("};");
fmtln!(fmt, "};");
// Register class descriptors.
for rc in isa.reg_classes.values() {
for rc in isa.regs.classes.values() {
gen_regclass(&isa, rc, fmt);
}
// Emit constants for all the register units.
fmt.line("#[allow(dead_code, non_camel_case_types)]");
fmt.line("#[derive(Clone, Copy)]");
fmt.line("pub enum RU {");
fmtln!(fmt, "#[allow(dead_code, non_camel_case_types)]");
fmtln!(fmt, "#[derive(Clone, Copy)]");
fmtln!(fmt, "pub enum RU {");
fmt.indent(|fmt| {
for reg_bank in isa.reg_banks.values() {
for reg_bank in isa.regs.banks.values() {
gen_regbank_units(reg_bank, fmt);
}
});
fmt.line("}");
fmtln!(fmt, "}");
// Emit Into conversion for the RU class.
fmt.line("impl Into<RegUnit> for RU {");
fmtln!(fmt, "impl Into<RegUnit> for RU {");
fmt.indent(|fmt| {
fmt.line("fn into(self) -> RegUnit {");
fmtln!(fmt, "fn into(self) -> RegUnit {");
fmt.indent(|fmt| {
fmt.line("self as RegUnit");
fmtln!(fmt, "self as RegUnit");
});
fmt.line("}")
fmtln!(fmt, "}");
});
fmt.line("}");
fmtln!(fmt, "}");
}
pub fn generate(isa: &TargetIsa, base_filename: &str, out_dir: &str) -> Result<(), error::Error> {
let mut fmt = Formatter::new();
gen_isa(&isa, &mut fmt);
fmt.update_file(&format!("{}-{}.rs", base_filename, isa.name), out_dir)?;
fmt.update_file(format!("{}-{}.rs", base_filename, isa.name), out_dir)?;
Ok(())
}

Просмотреть файл

@ -1,4 +1,3 @@
use crate::base;
use crate::cdsl::camel_case;
use crate::cdsl::isa::TargetIsa;
use crate::cdsl::settings::{
@ -6,6 +5,7 @@ use crate::cdsl::settings::{
};
use crate::constant_hash::{generate_table, simple_hash};
use crate::error;
use crate::shared;
use crate::srcgen::{Formatter, Match};
use crate::unique_table::UniqueTable;
use std::collections::HashMap;
@ -21,87 +21,92 @@ fn gen_constructor(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatte
ParentGroup::None => "builder: Builder",
ParentGroup::Shared => "shared: &settings::Flags, builder: Builder",
};
fmt.line("impl Flags {");
fmtln!(fmt, "impl Flags {");
fmt.indent(|fmt| {
fmt.doc_comment(&format!("Create flags {} settings group.", group.name));
fmt.line("#[allow(unused_variables)]");
fmt.line(&format!("pub fn new({}) -> Self {{", args));
fmt.doc_comment(format!("Create flags {} settings group.", group.name));
fmtln!(fmt, "#[allow(unused_variables)]");
fmtln!(fmt, "pub fn new({}) -> Self {{", args);
fmt.indent(|fmt| {
fmt.line(&format!(
"let bvec = builder.state_for(\"{}\");",
group.name
));
fmt.line(&format!(
fmtln!(fmt, "let bvec = builder.state_for(\"{}\");", group.name);
fmtln!(
fmt,
"let mut {} = Self {{ bytes: [0; {}] }};",
group.name,
group.byte_size()
));
fmt.line(&format!(
);
fmtln!(
fmt,
"debug_assert_eq!(bvec.len(), {});",
group.settings_size
));
fmt.line(&format!(
);
fmtln!(
fmt,
"{}.bytes[0..{}].copy_from_slice(&bvec);",
group.name, group.settings_size
));
group.name,
group.settings_size
);
// Now compute the predicates.
for p in &group.predicates {
fmt.comment(&format!("Precompute #{}.", p.number));
fmt.line(&format!("if {} {{", p.render(group)));
fmt.comment(format!("Precompute #{}.", p.number));
fmtln!(fmt, "if {} {{", p.render(group));
fmt.indent(|fmt| {
fmt.line(&format!(
fmtln!(
fmt,
"{}.bytes[{}] |= 1 << {};",
group.name,
group.bool_start_byte_offset + p.number / 8,
p.number % 8
));
);
});
fmt.line("}");
fmtln!(fmt, "}");
}
fmt.line(group.name);
fmtln!(fmt, group.name);
});
fmt.line("}");
fmtln!(fmt, "}");
});
fmt.line("}");
fmtln!(fmt, "}");
}
/// Emit Display and FromStr implementations for enum settings.
fn gen_to_and_from_str(name: &str, values: &[&'static str], fmt: &mut Formatter) {
fmt.line(&format!("impl fmt::Display for {} {{", name));
fmtln!(fmt, "impl fmt::Display for {} {{", name);
fmt.indent(|fmt| {
fmt.line("fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {");
fmtln!(
fmt,
"fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {"
);
fmt.indent(|fmt| {
fmt.line("f.write_str(match *self {");
fmtln!(fmt, "f.write_str(match *self {");
fmt.indent(|fmt| {
for v in values.iter() {
fmt.line(&format!("{}::{} => \"{}\",", name, camel_case(v), v));
fmtln!(fmt, "{}::{} => \"{}\",", name, camel_case(v), v);
}
});
fmt.line("})");
fmtln!(fmt, "})");
});
fmt.line("}");
fmtln!(fmt, "}");
});
fmt.line("}");
fmtln!(fmt, "}");
fmt.line(&format!("impl str::FromStr for {} {{", name));
fmtln!(fmt, "impl str::FromStr for {} {{", name);
fmt.indent(|fmt| {
fmt.line("type Err = ();");
fmt.line("fn from_str(s: &str) -> Result<Self, Self::Err> {");
fmtln!(fmt, "type Err = ();");
fmtln!(fmt, "fn from_str(s: &str) -> Result<Self, Self::Err> {");
fmt.indent(|fmt| {
fmt.line("match s {");
fmtln!(fmt, "match s {");
fmt.indent(|fmt| {
for v in values.iter() {
fmt.line(&format!("\"{}\" => Ok({}::{}),", v, name, camel_case(v)));
fmtln!(fmt, "\"{}\" => Ok({}::{}),", v, name, camel_case(v));
}
fmt.line("_ => Err(()),");
fmtln!(fmt, "_ => Err(()),");
});
fmt.line("}");
fmtln!(fmt, "}");
});
fmt.line("}");
fmtln!(fmt, "}");
});
fmt.line("}");
fmtln!(fmt, "}");
}
/// Emit real enum for the Enum settings.
@ -113,16 +118,16 @@ fn gen_enum_types(group: &SettingGroup, fmt: &mut Formatter) {
};
let name = camel_case(setting.name);
fmt.doc_comment(&format!("Values for `{}.{}`.", group.name, setting.name));
fmt.line("#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]");
fmt.line(&format!("pub enum {} {{", name));
fmt.doc_comment(format!("Values for `{}.{}`.", group.name, setting.name));
fmtln!(fmt, "#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]");
fmtln!(fmt, "pub enum {} {{", name);
fmt.indent(|fmt| {
for v in values.iter() {
fmt.doc_comment(&format!("`{}`.", v));
fmt.line(&format!("{},", camel_case(v)));
fmt.doc_comment(format!("`{}`.", v));
fmtln!(fmt, "{},", camel_case(v));
}
});
fmt.line("}");
fmtln!(fmt, "}");
gen_to_and_from_str(&name, values, fmt);
}
@ -135,15 +140,15 @@ fn gen_getter(setting: &Setting, fmt: &mut Formatter) {
SpecificSetting::Bool(BoolSetting {
predicate_number, ..
}) => {
fmt.line(&format!("pub fn {}(&self) -> bool {{", setting.name));
fmtln!(fmt, "pub fn {}(&self) -> bool {{", setting.name);
fmt.indent(|fmt| {
fmt.line(&format!("self.numbered_predicate({})", predicate_number));
fmtln!(fmt, "self.numbered_predicate({})", predicate_number);
});
fmt.line("}");
fmtln!(fmt, "}");
}
SpecificSetting::Enum(ref values) => {
let ty = camel_case(setting.name);
fmt.line(&format!("pub fn {}(&self) -> {} {{", setting.name, ty));
fmtln!(fmt, "pub fn {}(&self) -> {} {{", setting.name, ty);
fmt.indent(|fmt| {
let mut m = Match::new(format!("self.bytes[{}]", setting.byte_offset));
for (i, v) in values.iter().enumerate() {
@ -156,56 +161,58 @@ fn gen_getter(setting: &Setting, fmt: &mut Formatter) {
m.arm("_", vec![], "panic!(\"Invalid enum value\")");
fmt.add_match(m);
});
fmt.line("}");
fmtln!(fmt, "}");
}
SpecificSetting::Num(_) => {
fmt.line(&format!("pub fn {}(&self) -> u8 {{", setting.name));
fmtln!(fmt, "pub fn {}(&self) -> u8 {{", setting.name);
fmt.indent(|fmt| {
fmt.line(&format!("self.bytes[{}]", setting.byte_offset));
fmtln!(fmt, "self.bytes[{}]", setting.byte_offset);
});
fmt.line("}");
fmtln!(fmt, "}");
}
}
}
fn gen_pred_getter(predicate: &Predicate, group: &SettingGroup, fmt: &mut Formatter) {
fmt.doc_comment(&format!(
"Computed predicate `{}`.",
predicate.render(group)
));
fmt.line(&format!("pub fn {}(&self) -> bool {{", predicate.name));
fmt.doc_comment(format!("Computed predicate `{}`.", predicate.render(group)));
fmtln!(fmt, "pub fn {}(&self) -> bool {{", predicate.name);
fmt.indent(|fmt| {
fmt.line(&format!("self.numbered_predicate({})", predicate.number));
fmtln!(fmt, "self.numbered_predicate({})", predicate.number);
});
fmt.line("}");
fmtln!(fmt, "}");
}
/// Emits getters for each setting value.
fn gen_getters(group: &SettingGroup, fmt: &mut Formatter) {
fmt.doc_comment("User-defined settings.");
fmt.line("#[allow(dead_code)]");
fmt.line("impl Flags {");
fmtln!(fmt, "#[allow(dead_code)]");
fmtln!(fmt, "impl Flags {");
fmt.indent(|fmt| {
fmt.doc_comment("Get a view of the boolean predicates.");
fmt.line("pub fn predicate_view(&self) -> ::settings::PredicateView {");
fmtln!(
fmt,
"pub fn predicate_view(&self) -> ::settings::PredicateView {"
);
fmt.indent(|fmt| {
fmt.line(&format!(
fmtln!(
fmt,
"::settings::PredicateView::new(&self.bytes[{}..])",
group.bool_start_byte_offset
));
);
});
fmt.line("}");
fmtln!(fmt, "}");
if group.settings.len() > 0 {
fmt.doc_comment("Dynamic numbered predicate getter.");
fmt.line("fn numbered_predicate(&self, p: usize) -> bool {");
fmtln!(fmt, "fn numbered_predicate(&self, p: usize) -> bool {");
fmt.indent(|fmt| {
fmt.line(&format!(
fmtln!(
fmt,
"self.bytes[{} + p / 8] & (1 << (p % 8)) != 0",
group.bool_start_byte_offset
));
);
});
fmt.line("}");
fmtln!(fmt, "}");
}
for setting in &group.settings {
@ -215,7 +222,7 @@ fn gen_getters(group: &SettingGroup, fmt: &mut Formatter) {
gen_pred_getter(&predicate, &group, fmt);
}
});
fmt.line("}");
fmtln!(fmt, "}");
}
#[derive(Hash, PartialEq, Eq)]
@ -240,66 +247,66 @@ fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) {
let mut descriptor_index_map: HashMap<SettingOrPreset, usize> = HashMap::new();
// Generate descriptors.
fmt.line(&format!(
fmtln!(
fmt,
"static DESCRIPTORS: [detail::Descriptor; {}] = [",
group.settings.len() + group.presets.len()
));
);
fmt.indent(|fmt| {
for (idx, setting) in group.settings.iter().enumerate() {
fmt.line("detail::Descriptor {");
fmtln!(fmt, "detail::Descriptor {");
fmt.indent(|fmt| {
fmt.line(&format!("name: \"{}\",", setting.name));
fmt.line(&format!("offset: {},", setting.byte_offset));
fmtln!(fmt, "name: \"{}\",", setting.name);
fmtln!(fmt, "offset: {},", setting.byte_offset);
match setting.specific {
SpecificSetting::Bool(BoolSetting { bit_offset, .. }) => {
fmt.line(&format!(
fmtln!(
fmt,
"detail: detail::Detail::Bool {{ bit: {} }},",
bit_offset
));
);
}
SpecificSetting::Enum(ref values) => {
let offset = enum_table.add(values);
fmt.line(&format!(
fmtln!(
fmt,
"detail: detail::Detail::Enum {{ last: {}, enumerators: {} }},",
values.len() - 1,
offset
));
);
}
SpecificSetting::Num(_) => {
fmt.line("detail: detail::Detail::Num,");
fmtln!(fmt, "detail: detail::Detail::Num,");
}
}
descriptor_index_map.insert(SettingOrPreset::Setting(setting), idx);
});
fmt.line("},");
fmtln!(fmt, "},");
}
for (idx, preset) in group.presets.iter().enumerate() {
fmt.line("detail::Descriptor {");
fmtln!(fmt, "detail::Descriptor {");
fmt.indent(|fmt| {
fmt.line(&format!("name: \"{}\",", preset.name));
fmt.line(&format!("offset: {},", (idx as u8) * group.settings_size));
fmt.line("detail: detail::Detail::Preset,");
fmtln!(fmt, "name: \"{}\",", preset.name);
fmtln!(fmt, "offset: {},", (idx as u8) * group.settings_size);
fmtln!(fmt, "detail: detail::Detail::Preset,");
});
fmt.line("},");
fmtln!(fmt, "},");
descriptor_index_map.insert(SettingOrPreset::Preset(preset), idx);
}
});
fmt.line("];");
fmtln!(fmt, "];");
// Generate enumerators.
fmt.line(&format!(
"static ENUMERATORS: [&str; {}] = [",
enum_table.len()
));
fmtln!(fmt, "static ENUMERATORS: [&str; {}] = [", enum_table.len());
fmt.indent(|fmt| {
for enum_val in enum_table.iter() {
fmt.line(&format!("\"{}\",", enum_val));
fmtln!(fmt, "\"{}\",", enum_val);
}
});
fmt.line("];");
fmtln!(fmt, "];");
// Generate hash table.
let mut hash_entries: Vec<SettingOrPreset> = Vec::new();
@ -318,40 +325,39 @@ fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) {
.collect::<Vec<SettingOrPreset>>(),
);
let hash_table = generate_table(&hash_entries, |entry| simple_hash(entry.name()));
fmt.line(&format!(
"static HASH_TABLE: [u16; {}] = [",
hash_table.len()
));
fmtln!(fmt, "static HASH_TABLE: [u16; {}] = [", hash_table.len());
fmt.indent(|fmt| {
for h in &hash_table {
match *h {
Some(setting_or_preset) => fmt.line(&format!(
Some(setting_or_preset) => fmtln!(
fmt,
"{},",
&descriptor_index_map
.get(setting_or_preset)
.unwrap()
.to_string()
)),
None => fmt.line("0xffff,"),
),
None => fmtln!(fmt, "0xffff,"),
}
}
});
fmt.line("];");
fmtln!(fmt, "];");
// Generate presets.
fmt.line(&format!(
fmtln!(
fmt,
"static PRESETS: [(u8, u8); {}] = [",
group.presets.len()
));
);
fmt.indent(|fmt| {
for preset in &group.presets {
fmt.comment(preset.name);
for (mask, value) in preset.layout(&group) {
fmt.line(&format!("(0b{:08b}, 0b{:08b}),", mask, value));
fmtln!(fmt, "(0b{:08b}, 0b{:08b}),", mask, value);
}
}
});
fmt.line("];");
fmtln!(fmt, "];");
}
fn gen_template(group: &SettingGroup, fmt: &mut Formatter) {
@ -366,63 +372,70 @@ fn gen_template(group: &SettingGroup, fmt: &mut Formatter) {
.collect();
let default_bytes_str = default_bytes.join(", ");
fmt.line("static TEMPLATE: detail::Template = detail::Template {");
fmtln!(
fmt,
"static TEMPLATE: detail::Template = detail::Template {"
);
fmt.indent(|fmt| {
fmt.line(&format!("name: \"{}\",", group.name));
fmt.line("descriptors: &DESCRIPTORS,");
fmt.line("enumerators: &ENUMERATORS,");
fmt.line("hash_table: &HASH_TABLE,");
fmt.line(&format!("defaults: &[{}],", default_bytes_str));
fmt.line("presets: &PRESETS,");
fmtln!(fmt, "name: \"{}\",", group.name);
fmtln!(fmt, "descriptors: &DESCRIPTORS,");
fmtln!(fmt, "enumerators: &ENUMERATORS,");
fmtln!(fmt, "hash_table: &HASH_TABLE,");
fmtln!(fmt, "defaults: &[{}],", default_bytes_str);
fmtln!(fmt, "presets: &PRESETS,");
});
fmt.line("};");
fmtln!(fmt, "};");
fmt.doc_comment(&format!(
fmt.doc_comment(format!(
"Create a `settings::Builder` for the {} settings group.",
group.name
));
fmt.line("pub fn builder() -> Builder {");
fmtln!(fmt, "pub fn builder() -> Builder {");
fmt.indent(|fmt| {
fmt.line("Builder::new(&TEMPLATE)");
fmtln!(fmt, "Builder::new(&TEMPLATE)");
});
fmt.line("}");
fmtln!(fmt, "}");
}
fn gen_display(group: &SettingGroup, fmt: &mut Formatter) {
fmt.line("impl fmt::Display for Flags {");
fmtln!(fmt, "impl fmt::Display for Flags {");
fmt.indent(|fmt| {
fmt.line("fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {");
fmtln!(
fmt,
"fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {"
);
fmt.indent(|fmt| {
fmt.line(&format!("writeln!(f, \"[{}]\")?;", group.name));
fmt.line("for d in &DESCRIPTORS {");
fmtln!(fmt, "writeln!(f, \"[{}]\")?;", group.name);
fmtln!(fmt, "for d in &DESCRIPTORS {");
fmt.indent(|fmt| {
fmt.line("if !d.detail.is_preset() {");
fmtln!(fmt, "if !d.detail.is_preset() {");
fmt.indent(|fmt| {
fmt.line("write!(f, \"{} = \", d.name)?;");
fmt.line(
fmtln!(fmt, "write!(f, \"{} = \", d.name)?;");
fmtln!(
fmt,
"TEMPLATE.format_toml_value(d.detail, self.bytes[d.offset as usize], f)?;",
);
fmt.line("writeln!(f)?;");
fmtln!(fmt, "writeln!(f)?;");
});
fmt.line("}");
fmtln!(fmt, "}");
});
fmt.line("}");
fmt.line("Ok(())");
fmtln!(fmt, "}");
fmtln!(fmt, "Ok(())");
});
fmt.line("}")
fmtln!(fmt, "}")
});
fmt.line("}");
fmtln!(fmt, "}");
}
fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
// Generate struct.
fmt.line("#[derive(Clone)]");
fmt.doc_comment(&format!("Flags group `{}`.", group.name));
fmt.line("pub struct Flags {");
fmtln!(fmt, "#[derive(Clone)]");
fmt.doc_comment(format!("Flags group `{}`.", group.name));
fmtln!(fmt, "pub struct Flags {");
fmt.indent(|fmt| {
fmt.line(&format!("bytes: [u8; {}],", group.byte_size()));
fmtln!(fmt, "bytes: [u8; {}],", group.byte_size());
});
fmt.line("}");
fmtln!(fmt, "}");
gen_constructor(group, parent, fmt);
gen_enum_types(group, fmt);
@ -433,7 +446,7 @@ fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
}
pub fn generate_common(filename: &str, out_dir: &str) -> Result<SettingGroup, error::Error> {
let settings = base::settings::generate();
let settings = shared::settings::generate();
let mut fmt = Formatter::new();
gen_group(&settings, ParentGroup::None, &mut fmt);
fmt.update_file(filename, out_dir)?;
@ -443,6 +456,6 @@ pub fn generate_common(filename: &str, out_dir: &str) -> Result<SettingGroup, er
pub fn generate(isa: &TargetIsa, prefix: &str, out_dir: &str) -> Result<(), error::Error> {
let mut fmt = Formatter::new();
gen_group(&isa.settings, ParentGroup::Shared, &mut fmt);
fmt.update_file(&format!("{}-{}.rs", prefix, isa.name), out_dir)?;
fmt.update_file(format!("{}-{}.rs", prefix, isa.name), out_dir)?;
Ok(())
}

Просмотреть файл

@ -1,7 +1,7 @@
//! Generate sources with type info.
//!
//! This generates a `types.rs` file which is included in
//! `lib/codegen/ir/types.rs`. The file provides constant definitions for the
//! `cranelift-codegen/ir/types.rs`. The file provides constant definitions for the
//! most commonly used types, including all of the scalar types.
//!
//! This ensures that the metaprogram and the generated program see the same
@ -21,10 +21,8 @@ fn emit_type(ty: &cdsl_types::ValueType, fmt: &mut srcgen::Formatter) -> Result<
))
})?;
let definition = format!("pub const {}: Type = Type({:#x});\n", name, number);
fmt.doc_comment(&ty.doc());
fmt.line(&definition);
fmtln!(fmt, "pub const {}: Type = Type({:#x});\n", name, number);
Ok(())
}

Просмотреть файл

@ -1,5 +1,5 @@
use crate::cdsl::isa::{TargetIsa, TargetIsaBuilder};
use crate::cdsl::regs::{RegBankBuilder, RegClassBuilder};
use crate::cdsl::isa::TargetIsa;
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
@ -7,39 +7,45 @@ fn define_settings(_shared: &SettingGroup) -> SettingGroup {
setting.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let mut isa = TargetIsaBuilder::new("arm32", define_settings(shared_settings));
fn define_regs() -> IsaRegs {
let mut regs = IsaRegsBuilder::new();
let builder = RegBankBuilder::new("FloatRegs", "s")
.units(64)
.track_pressure(true);
let float_regs = isa.add_reg_bank(builder);
let float_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("IntRegs", "r")
.units(16)
.track_pressure(true);
let int_regs = isa.add_reg_bank(builder);
let int_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("FlagRegs", "")
.units(1)
.names(vec!["nzcv"])
.track_pressure(false);
let flag_reg = isa.add_reg_bank(builder);
let flag_reg = regs.add_bank(builder);
let builder = RegClassBuilder::new_toplevel("S", float_regs).count(32);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("D", float_regs).width(2);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("Q", float_regs).width(4);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg);
isa.add_reg_class(builder);
regs.add_class(builder);
isa.finish()
regs.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let settings = define_settings(shared_settings);
let regs = define_regs();
TargetIsa::new("arm32", settings, regs)
}

Просмотреть файл

@ -1,5 +1,5 @@
use crate::cdsl::isa::{TargetIsa, TargetIsaBuilder};
use crate::cdsl::regs::{RegBankBuilder, RegClassBuilder};
use crate::cdsl::isa::TargetIsa;
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
@ -7,35 +7,41 @@ fn define_settings(_shared: &SettingGroup) -> SettingGroup {
setting.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let mut isa = TargetIsaBuilder::new("arm64", define_settings(shared_settings));
fn define_registers() -> IsaRegs {
let mut regs = IsaRegsBuilder::new();
// The `x31` regunit serves as the stack pointer / zero register depending on context. We
// reserve it and don't model the difference.
let builder = RegBankBuilder::new("IntRegs", "x")
.units(32)
.track_pressure(true);
let int_regs = isa.add_reg_bank(builder);
let int_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("FloatRegs", "v")
.units(32)
.track_pressure(true);
let float_regs = isa.add_reg_bank(builder);
let float_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("FlagRegs", "")
.units(1)
.names(vec!["nzcv"])
.track_pressure(false);
let flag_reg = isa.add_reg_bank(builder);
let flag_reg = regs.add_bank(builder);
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("FPR", float_regs);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg);
isa.add_reg_class(builder);
regs.add_class(builder);
isa.finish()
regs.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let settings = define_settings(shared_settings);
let regs = define_registers();
TargetIsa::new("arm64", settings, regs)
}

Просмотреть файл

@ -18,7 +18,7 @@ pub enum Isa {
impl Isa {
/// Creates isa target using name.
pub fn new(name: &str) -> Option<Self> {
pub fn from_name(name: &str) -> Option<Self> {
Isa::all()
.iter()
.cloned()
@ -27,31 +27,24 @@ impl Isa {
}
/// Creates isa target from arch.
pub fn from_arch(arch: &str) -> Option<Isa> {
Isa::all()
.iter()
.cloned()
.filter(|isa| isa.is_arch_applicable(arch))
.next()
pub fn from_arch(arch: &str) -> Option<Self> {
match arch {
"riscv" => Some(Isa::Riscv),
"aarch64" => Some(Isa::Arm64),
x if ["x86_64", "i386", "i586", "i686"].contains(&x) => Some(Isa::X86),
x if x.starts_with("arm") || arch.starts_with("thumb") => Some(Isa::Arm32),
_ => None,
}
}
/// Returns all supported isa targets.
pub fn all() -> [Isa; 4] {
[Isa::Riscv, Isa::X86, Isa::Arm32, Isa::Arm64]
}
/// Checks if arch is applicable for the isa target.
fn is_arch_applicable(&self, arch: &str) -> bool {
match *self {
Isa::Riscv => arch == "riscv",
Isa::X86 => ["x86_64", "i386", "i586", "i686"].contains(&arch),
Isa::Arm32 => arch.starts_with("arm") || arch.starts_with("thumb"),
Isa::Arm64 => arch == "aarch64",
}
}
}
impl fmt::Display for Isa {
// These names should be kept in sync with the crate features.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Isa::Riscv => write!(f, "riscv"),
@ -62,11 +55,13 @@ impl fmt::Display for Isa {
}
}
pub fn define_all(shared_settings: &SettingGroup) -> Vec<TargetIsa> {
vec![
riscv::define(shared_settings),
arm32::define(shared_settings),
arm64::define(shared_settings),
x86::define(shared_settings),
]
pub fn define(isas: &Vec<Isa>, shared_settings: &SettingGroup) -> Vec<TargetIsa> {
isas.iter()
.map(|isa| match isa {
Isa::Riscv => riscv::define(shared_settings),
Isa::X86 => x86::define(shared_settings),
Isa::Arm32 => arm32::define(shared_settings),
Isa::Arm64 => arm64::define(shared_settings),
})
.collect()
}

Просмотреть файл

@ -1,5 +1,5 @@
use crate::cdsl::isa::{TargetIsa, TargetIsaBuilder};
use crate::cdsl::regs::{RegBankBuilder, RegClassBuilder};
use crate::cdsl::isa::TargetIsa;
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
fn define_settings(shared: &SettingGroup) -> SettingGroup {
@ -54,24 +54,30 @@ fn define_settings(shared: &SettingGroup) -> SettingGroup {
setting.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let mut isa = TargetIsaBuilder::new("riscv", define_settings(shared_settings));
fn define_registers() -> IsaRegs {
let mut regs = IsaRegsBuilder::new();
let builder = RegBankBuilder::new("IntRegs", "x")
.units(32)
.track_pressure(true);
let int_regs = isa.add_reg_bank(builder);
let int_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("FloatRegs", "f")
.units(32)
.track_pressure(true);
let float_regs = isa.add_reg_bank(builder);
let float_regs = regs.add_bank(builder);
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("FPR", float_regs);
isa.add_reg_class(builder);
regs.add_class(builder);
isa.finish()
regs.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let settings = define_settings(shared_settings);
let regs = define_registers();
TargetIsa::new("riscv", settings, regs)
}

Просмотреть файл

@ -1,8 +1,8 @@
use crate::cdsl::isa::{TargetIsa, TargetIsaBuilder};
use crate::cdsl::regs::{RegBankBuilder, RegClassBuilder};
use crate::cdsl::isa::TargetIsa;
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
pub fn define_settings(_shared: &SettingGroup) -> SettingGroup {
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
let mut settings = SettingGroupBuilder::new("x86");
// CPUID.01H:ECX
@ -68,49 +68,49 @@ pub fn define_settings(_shared: &SettingGroup) -> SettingGroup {
settings.finish()
}
fn define_registers(isa: &mut TargetIsaBuilder) {
fn define_registers() -> IsaRegs {
let mut regs = IsaRegsBuilder::new();
let builder = RegBankBuilder::new("IntRegs", "r")
.units(16)
.names(vec!["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"])
.track_pressure(true);
let int_regs = isa.add_reg_bank(builder);
let int_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("FloatRegs", "xmm")
.units(16)
.track_pressure(true);
let float_regs = isa.add_reg_bank(builder);
let float_regs = regs.add_bank(builder);
let builder = RegBankBuilder::new("FlagRegs", "")
.units(1)
.names(vec!["rflags"])
.track_pressure(false);
let flag_reg = isa.add_reg_bank(builder);
let flag_reg = regs.add_bank(builder);
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
let gpr = isa.add_reg_class(builder);
let gpr = regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("FPR", float_regs);
let fpr = isa.add_reg_class(builder);
let fpr = regs.add_class(builder);
let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::subclass_of("GPR8", gpr, 0, 8);
let gpr8 = isa.add_reg_class(builder);
let gpr8 = regs.add_class(builder);
let builder = RegClassBuilder::subclass_of("ABCD", gpr8, 0, 4);
isa.add_reg_class(builder);
regs.add_class(builder);
let builder = RegClassBuilder::subclass_of("FPR8", fpr, 0, 8);
isa.add_reg_class(builder);
regs.add_class(builder);
regs.finish()
}
pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
let settings = define_settings(shared_settings);
let mut isa = TargetIsaBuilder::new("x86", settings);
define_registers(&mut isa);
isa.finish()
let regs = define_registers();
TargetIsa::new("x86", settings, regs)
}

Просмотреть файл

@ -1,13 +1,36 @@
#[macro_use]
mod cdsl;
mod srcgen;
pub mod error;
pub mod gen_registers;
pub mod gen_settings;
pub mod gen_types;
pub mod isa;
mod base;
mod gen_registers;
mod gen_settings;
mod gen_types;
mod constant_hash;
mod srcgen;
mod shared;
mod unique_table;
pub fn isa_from_arch(arch: &str) -> Result<isa::Isa, String> {
isa::Isa::from_arch(arch).ok_or_else(|| format!("no supported isa found for arch `{}`", arch))
}
/// Generates all the Rust source files used in Cranelift from the meta-language.
pub fn generate(isas: &Vec<isa::Isa>, out_dir: &str) -> Result<(), error::Error> {
// Common definitions.
let shared_settings = gen_settings::generate_common("new_settings.rs", &out_dir)?;
gen_types::generate("types.rs", &out_dir)?;
// Per ISA definitions.
let isas = isa::define(isas, &shared_settings);
for isa in isas {
gen_registers::generate(&isa, "registers", &out_dir)?;
gen_settings::generate(&isa, "new_settings", &out_dir)?;
}
Ok(())
}

4
third_party/rust/cranelift-codegen-meta/src/shared/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
//! Shared definitions for the Cranelift intermediate language.
pub mod settings;
pub mod types;

Просмотреть файл

@ -3,6 +3,8 @@
//! The `srcgen` module contains generic helper routines and classes for
//! generating source code.
#![macro_use]
use std::cmp;
use std::collections::{BTreeMap, BTreeSet};
use std::fs;
@ -13,6 +15,18 @@ use crate::error;
static SHIFTWIDTH: usize = 4;
/// A macro that simplifies the usage of the Formatter by allowing format
/// strings.
macro_rules! fmtln {
($fmt:ident, $fmtstring:expr, $($fmtargs:expr),*) => {
$fmt.line(format!($fmtstring, $($fmtargs),*));
};
($fmt:ident, $arg:expr) => {
$fmt.line($arg);
};
}
pub struct Formatter {
indent: usize,
lines: Vec<String>,
@ -65,8 +79,8 @@ impl Formatter {
}
/// Add an indented line.
pub fn line(&mut self, contents: &str) {
let indented_line = format!("{}{}\n", self.get_indent(), contents);
pub fn line(&mut self, contents: impl AsRef<str>) {
let indented_line = format!("{}{}\n", self.get_indent(), contents.as_ref());
self.lines.push(indented_line);
}
@ -77,11 +91,15 @@ impl Formatter {
}
/// Write `self.lines` to a file.
pub fn update_file(&self, filename: &str, directory: &str) -> Result<(), error::Error> {
pub fn update_file(
&self,
filename: impl AsRef<str>,
directory: &str,
) -> Result<(), error::Error> {
#[cfg(target_family = "windows")]
let path_str = format!("{}\\{}", directory, filename);
let path_str = format!("{}\\{}", directory, filename.as_ref());
#[cfg(not(target_family = "windows"))]
let path_str = format!("{}/{}", directory, filename);
let path_str = format!("{}/{}", directory, filename.as_ref());
let path = path::Path::new(&path_str);
let mut f = fs::File::create(path)?;
@ -99,14 +117,13 @@ impl Formatter {
}
/// Add a comment line.
pub fn comment(&mut self, s: &str) {
let commented_line = format!("// {}", s);
self.line(&commented_line);
pub fn comment(&mut self, s: impl AsRef<str>) {
fmtln!(self, "// {}", s.as_ref());
}
/// Add a (multi-line) documentation comment.
pub fn doc_comment(&mut self, contents: &str) {
parse_multiline(contents)
pub fn doc_comment(&mut self, contents: impl AsRef<str>) {
parse_multiline(contents.as_ref())
.iter()
.map(|l| {
if l.len() == 0 {
@ -120,7 +137,7 @@ impl Formatter {
/// Add a match expression.
pub fn add_match(&mut self, m: Match) {
self.line(&format!("match {} {{", m.expr));
fmtln!(self, "match {} {{", m.expr);
self.indent(|fmt| {
for (&(ref fields, ref body), ref names) in m.arms.iter() {
// name { fields } | name { fields } => { body }
@ -135,7 +152,7 @@ impl Formatter {
})
.collect();
let lhs = conditions.join(" | ");
fmt.line(&format!("{} => {{", lhs));
fmtln!(fmt, "{} => {{", lhs);
fmt.indent(|fmt| {
fmt.line(body);
});
@ -337,7 +354,7 @@ match x {
#[test]
fn fmt_can_add_type_to_lines() {
let mut fmt = Formatter::new();
fmt.line(&format!("pub const {}: Type = Type({:#x});", "example", 0,));
fmt.line(format!("pub const {}: Type = Type({:#x});", "example", 0,));
let expected_lines = vec!["pub const example: Type = Type(0x0);\n"];
assert_eq!(fmt.lines, expected_lines);
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

14
third_party/rust/cranelift-codegen/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "cranelift-codegen"
version = "0.28.0"
version = "0.29.0"
authors = ["The Cranelift Project Developers"]
build = "build.rs"
description = "Low-level code generator library"
@ -24,11 +24,11 @@ categories = ["no-std"]
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/CraneStation/cranelift"
[dependencies.cranelift-bforest]
version = "0.28.0"
version = "0.29.0"
default-features = false
[dependencies.cranelift-entity]
version = "0.28.0"
version = "0.29.0"
default-features = false
[dependencies.failure]
@ -52,13 +52,17 @@ default-features = false
version = "0.2.0"
default-features = false
[build-dependencies.cranelift-codegen-meta]
version = "0.28.0"
version = "0.29.0"
[features]
arm32 = []
arm64 = []
core = ["hashmap_core"]
default = ["std"]
default = ["std", "x86", "arm32", "arm64", "riscv"]
riscv = []
std = ["cranelift-entity/std", "cranelift-bforest/std", "target-lexicon/std"]
testing_hooks = []
x86 = []
[badges.maintenance]
status = "experimental"

97
third_party/rust/cranelift-codegen/build.rs поставляемый
Просмотреть файл

@ -1,7 +1,7 @@
// Build script.
//
// This program is run by Cargo when building lib/codegen. It is used to generate Rust code from
// the language definitions in the lib/codegen/meta directory.
// This program is run by Cargo when building cranelift-codegen. It is used to generate Rust code from
// the language definitions in the cranelift-codegen/meta directory.
//
// Environment:
//
@ -11,16 +11,11 @@
// TARGET
// Target triple provided by Cargo.
//
// CRANELIFT_TARGETS (Optional)
// A setting for conditional compilation of isa targets. Possible values can be "native" or
// known isa targets separated by ','.
//
// The build script expects to be run from the directory where this build.rs file lives. The
// current directory is used to find the sources.
use cranelift_codegen_meta as meta;
use crate::meta::isa::Isa;
use std::env;
use std::process;
use std::time::Instant;
@ -30,29 +25,33 @@ fn main() {
let out_dir = env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set");
let target_triple = env::var("TARGET").expect("The TARGET environment variable must be set");
let cranelift_targets = env::var("CRANELIFT_TARGETS").ok();
let cranelift_targets = cranelift_targets.as_ref().map(|s| s.as_ref());
let python = identify_python();
// Configure isa targets cfg.
match isa_targets(cranelift_targets, &target_triple) {
Ok(isa_targets) => {
for isa in &isa_targets {
println!("cargo:rustc-cfg=build_{}", isa.to_string());
}
}
Err(err) => {
eprintln!("Error: {}", err);
process::exit(1);
}
}
let isa_targets = meta::isa::Isa::all()
.into_iter()
.cloned()
.filter(|isa| {
let env_key = format!("CARGO_FEATURE_{}", isa.to_string().to_uppercase());
env::var(env_key).is_ok()
})
.collect::<Vec<_>>();
let isas = if isa_targets.is_empty() {
// Try to match native target.
let target_name = target_triple.split('-').next().unwrap();
let isa = meta::isa_from_arch(&target_name).expect("error when identifying target");
println!("cargo:rustc-cfg=feature=\"{}\"", isa);
vec![isa]
} else {
isa_targets
};
let cur_dir = env::current_dir().expect("Can't access current working directory");
let crate_dir = cur_dir.as_path();
// Make sure we rebuild if this build script changes.
// I guess that won't happen if you have non-UTF8 bytes in your path names.
// The `build.py` script prints out its own dependencies.
// Make sure we rebuild if this build script changes (will not happen with
// if the path to this file contains non-UTF8 bytes). The `build.py` script
// prints out its own dependencies.
println!(
"cargo:rerun-if-changed={}",
crate_dir.join("build.rs").to_str().unwrap()
@ -65,6 +64,7 @@ fn main() {
// Launch build script with Python. We'll just find python in the path.
// Use -B to disable .pyc files, because they cause trouble for vendoring
// scripts, and this is a build step that isn't run very often anyway.
let python = identify_python();
let status = process::Command::new(python)
.current_dir(crate_dir)
.arg("-B")
@ -83,12 +83,15 @@ fn main() {
// emitted by the `meta` crate.
// ------------------------------------------------------------------------
if let Err(err) = generate_meta(&out_dir) {
if let Err(err) = meta::generate(&isas, &out_dir) {
eprintln!("Error: {}", err);
process::exit(1);
}
if let Ok(_) = env::var("CRANELIFT_VERBOSE") {
for isa in &isas {
println!("cargo:warning=Includes support for {} ISA", isa.to_string());
}
println!(
"cargo:warning=Build step took {:?}.",
Instant::now() - start_time
@ -97,20 +100,6 @@ fn main() {
}
}
fn generate_meta(out_dir: &str) -> Result<(), meta::error::Error> {
let shared_settings = meta::gen_settings::generate_common("new_settings.rs", &out_dir)?;
let isas = meta::isa::define_all(&shared_settings);
meta::gen_types::generate("types.rs", &out_dir)?;
for isa in &isas {
meta::gen_registers::generate(&isa, "registers", &out_dir)?;
meta::gen_settings::generate(&isa, "new_settings", &out_dir)?;
}
Ok(())
}
fn identify_python() -> &'static str {
for python in &["python", "python3", "python2.7"] {
if process::Command::new(python)
@ -123,33 +112,3 @@ fn identify_python() -> &'static str {
}
panic!("The Cranelift build requires Python (version 2.7 or version 3)");
}
/// Returns isa targets to configure conditional compilation.
fn isa_targets(cranelift_targets: Option<&str>, target_triple: &str) -> Result<Vec<Isa>, String> {
match cranelift_targets {
Some("native") => Isa::from_arch(target_triple.split('-').next().unwrap())
.map(|isa| vec![isa])
.ok_or_else(|| {
format!(
"no supported isa found for target triple `{}`",
target_triple
)
}),
Some(targets) => {
let unknown_isa_targets = targets
.split(',')
.filter(|target| Isa::new(target).is_none())
.collect::<Vec<_>>();
let isa_targets = targets.split(',').flat_map(Isa::new).collect::<Vec<_>>();
match (unknown_isa_targets.is_empty(), isa_targets.is_empty()) {
(true, true) => Ok(Isa::all().to_vec()),
(true, _) => Ok(isa_targets),
(_, _) => Err(format!(
"unknown isa targets: `{}`",
unknown_isa_targets.join(", ")
)),
}
}
None => Ok(Isa::all().to_vec()),
}
}

Просмотреть файл

@ -143,6 +143,12 @@ br_table = Instruction(
Note that this branch instruction can't pass arguments to the targeted
blocks. Split critical edges as needed to work around this.
Do not confuse this with "tables" in WebAssembly. ``br_table`` is for
jump tables with destinations within the current function only -- think
of a ``match`` in Rust or a ``switch`` in C. If you want to call a
function in a dynamic library, that will typically use
``call_indirect``.
""",
ins=(x, EBB, JT), is_branch=True, is_terminator=True)

Просмотреть файл

@ -375,7 +375,7 @@ for int_ty in [types.i8, types.i16]:
)
for int_ty in [types.i8, types.i16]:
for op in [ushr_imm, ishl_imm]:
for op in [ishl, ishl_imm, ushr, ushr_imm]:
widen.legalize(
a << op.bind(int_ty)(b, c),
Rtl(
@ -384,29 +384,14 @@ for int_ty in [types.i8, types.i16]:
a << ireduce.bind(int_ty)(z)
))
widen.legalize(
a << ishl.bind(int_ty)(b, c),
Rtl(
x << uextend.i32(b),
z << ishl.i32(x, c),
a << ireduce.bind(int_ty)(z)
))
widen.legalize(
a << ushr.bind(int_ty)(b, c),
Rtl(
x << uextend.i32(b),
z << ushr.i32(x, c),
a << ireduce.bind(int_ty)(z)
))
widen.legalize(
a << sshr.bind(int_ty)(b, c),
Rtl(
x << sextend.i32(b),
z << sshr.i32(x, c),
a << ireduce.bind(int_ty)(z)
))
for op in [sshr, sshr_imm]:
widen.legalize(
a << op.bind(int_ty)(b, c),
Rtl(
x << sextend.i32(b),
z << op.i32(x, c),
a << ireduce.bind(int_ty)(z)
))
for w_cc in [
intcc.eq, intcc.ne, intcc.ugt, intcc.ult, intcc.uge, intcc.ule
@ -570,7 +555,7 @@ widen.legalize(
b1 << band_imm(b, imm64(0xcc)),
b2 << ushr_imm(b1, imm64(2)),
b3 << band_imm(b, imm64(0x33)),
b4 << ushr_imm(b3, imm64(2)),
b4 << ishl_imm(b3, imm64(2)),
c << bor(b2, b4),
c1 << band_imm(c, imm64(0xf0)),
c2 << ushr_imm(c1, imm64(4)),
@ -590,7 +575,7 @@ widen.legalize(
b1 << band_imm(b, imm64(0xcccc)),
b2 << ushr_imm(b1, imm64(2)),
b3 << band_imm(b, imm64(0x3333)),
b4 << ushr_imm(b3, imm64(2)),
b4 << ishl_imm(b3, imm64(2)),
c << bor(b2, b4),
c1 << band_imm(c, imm64(0xf0f0)),
c2 << ushr_imm(c1, imm64(4)),
@ -615,7 +600,7 @@ expand.legalize(
b1 << band_imm(b, imm64(0xcccccccc)),
b2 << ushr_imm(b1, imm64(2)),
b3 << band_imm(b, imm64(0x33333333)),
b4 << ushr_imm(b3, imm64(2)),
b4 << ishl_imm(b3, imm64(2)),
c << bor(b2, b4),
c1 << band_imm(c, imm64(0xf0f0f0f0)),
c2 << ushr_imm(c1, imm64(4)),
@ -643,7 +628,7 @@ expand.legalize(
b1 << band_imm(b, imm64(0xcccccccccccccccc)),
b2 << ushr_imm(b1, imm64(2)),
b3 << band_imm(b, imm64(0x3333333333333333)),
b4 << ushr_imm(b3, imm64(2)),
b4 << ishl_imm(b3, imm64(2)),
c << bor(b2, b4),
c1 << band_imm(c, imm64(0xf0f0f0f0f0f0f0f0)),
c2 << ushr_imm(c1, imm64(4)),

Просмотреть файл

@ -1,6 +1,6 @@
# Second-level build script.
#
# This script is run from lib/codegen/build.rs to generate Rust files.
# This script is run from cranelift-codegen/build.rs to generate Rust files.
from __future__ import absolute_import
import argparse

Просмотреть файл

@ -1,7 +1,7 @@
"""
Generate build dependencies for Cargo.
The `build.py` script is invoked by cargo when building lib/codegen to
The `build.py` script is invoked by cargo when building cranelift-codegen to
generate Rust code from the instruction descriptions. Cargo needs to know when
it is necessary to rerun the build script.

Просмотреть файл

@ -48,8 +48,8 @@ def verify_semantics(inst, src, xforms):
arg = rtl_var.rtl[0].expr.args[i]
assert isinstance(arg, Var)
for val in op.kind.possible_values():
s[arg] = val
new_variants.append(rtl_var.copy(s))
s[arg] = val
new_variants.append(rtl_var.copy(s))
variants = new_variants
# For any possible version of the src with concrete enumerated immediates
@ -65,7 +65,7 @@ def verify_semantics(inst, src, xforms):
matching_xforms = [] # type: List[XForm]
for x in xforms:
if src.substitution(x.src, {}) is None:
continue
continue
# Translate t using x.symtab
t = {x.symtab[str(v)]: tv for (v, tv) in t.items()}

Просмотреть файл

@ -55,13 +55,26 @@ pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> CodegenResult<Cod
let mut offset = 0;
let mut divert = RegDiversions::new();
// The relaxation algorithm iterates to convergence.
// First, compute initial offsets for every EBB.
{
let mut cur = FuncCursor::new(func);
while let Some(ebb) = cur.next_ebb() {
divert.clear();
cur.func.offsets[ebb] = offset;
while let Some(inst) = cur.next_inst() {
let enc = cur.func.encodings[inst];
offset += encinfo.byte_size(enc, inst, &divert, &cur.func);
}
}
}
// Then, run the relaxation algorithm until it converges.
let mut go_again = true;
while go_again {
go_again = false;
offset = 0;
// Visit all instructions in layout order
// Visit all instructions in layout order.
let mut cur = FuncCursor::new(func);
while let Some(ebb) = cur.next_ebb() {
divert.clear();
@ -81,15 +94,12 @@ pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> CodegenResult<Cod
let enc = cur.func.encodings[inst];
// See if this might be a branch that is out of range.
// See if this is a branch has a range and a destination, and if the target is in
// range.
if let Some(range) = encinfo.branch_range(enc) {
if let Some(dest) = cur.func.dfg[inst].branch_destination() {
let dest_offset = cur.func.offsets[dest];
// This could be an out-of-range branch.
// Relax it unless the destination offset has not been computed yet.
if !range.contains(offset, dest_offset)
&& (dest_offset != 0 || Some(dest) == cur.func.layout.entry_block())
{
if !range.contains(offset, dest_offset) {
offset +=
relax_branch(&mut cur, &divert, offset, dest_offset, &encinfo, isa);
continue;

Просмотреть файл

@ -1,6 +1,6 @@
//! Runtime support for precomputed constant hash tables.
//!
//! The `lib/codegen/meta-python/constant_hash.py` Python module can generate constant hash tables
//! The `cranelift-codegen/meta-python/constant_hash.py` Python module can generate constant hash tables
//! using open addressing and quadratic probing. The hash tables are arrays that are guaranteed to:
//!
//! - Have a power-of-two size.
@ -56,7 +56,7 @@ pub fn probe<K: Copy + Eq, T: Table<K> + ?Sized>(
}
/// A primitive hash function for matching opcodes.
/// Must match `lib/codegen/meta-python/constant_hash.py` and `lib/codegen/meta/constant_hash.rs`.
/// Must match `cranelift-codegen/meta-python/constant_hash.py` and `cranelift-codegen/meta/constant_hash.rs`.
pub fn simple_hash(s: &str) -> usize {
let mut h: u32 = 5381;
for c in s.chars() {

Просмотреть файл

@ -32,7 +32,7 @@ pub trait InstBuilderBase<'f>: Sized {
fn build(self, data: InstructionData, ctrl_typevar: Type) -> (Inst, &'f mut DataFlowGraph);
}
// Include trait code generated by `lib/codegen/meta-python/gen_instr.py`.
// Include trait code generated by `cranelift-codegen/meta-python/gen_instr.py`.
//
// This file defines the `InstBuilder` trait as an extension of `InstBuilderBase` with methods per
// instruction format and per opcode.

Просмотреть файл

@ -114,10 +114,12 @@ impl fmt::Display for GlobalValueData {
offset,
colocated,
} => {
if colocated {
write!(f, "colocated ")?;
}
write!(f, "symbol {}", name)?;
write!(
f,
"symbol {}{}",
if colocated { "colocated " } else { "" },
name
)?;
let offset_val: i64 = offset.into();
if offset_val > 0 {
write!(f, "+")?;

Просмотреть файл

@ -665,6 +665,12 @@ impl FromStr for Ieee32 {
}
}
impl From<f32> for Ieee32 {
fn from(x: f32) -> Self {
Ieee32::with_float(x)
}
}
impl Ieee64 {
/// Create a new `Ieee64` containing the bits of `x`.
pub fn with_bits(x: u64) -> Self {
@ -726,6 +732,12 @@ impl FromStr for Ieee64 {
}
}
impl From<f64> for Ieee64 {
fn from(x: f64) -> Self {
Ieee64::with_float(x)
}
}
#[cfg(test)]
mod tests {
use super::*;

Просмотреть файл

@ -28,7 +28,7 @@ pub type ValueList = entity::EntityList<Value>;
/// Memory pool for holding value lists. See `ValueList`.
pub type ValueListPool = entity::ListPool<Value>;
// Include code generated by `lib/codegen/meta-python/gen_instr.py`. This file contains:
// Include code generated by `cranelift-codegen/meta-python/gen_instr.py`. This file contains:
//
// - The `pub enum InstructionFormat` enum with all the instruction formats.
// - The `pub enum InstructionData` enum with all the instruction data fields.
@ -64,7 +64,7 @@ impl Opcode {
}
}
// This trait really belongs in lib/reader where it is used by the `.clif` file parser, but since
// This trait really belongs in cranelift-reader where it is used by the `.clif` file parser, but since
// it critically depends on the `opcode_name()` function which is needed here anyway, it lives in
// this module. This also saves us from running the build script twice to generate code for the two
// separate crates.

Просмотреть файл

@ -31,7 +31,7 @@ const LANE_BASE: u8 = 0x70;
/// Start of the 2-lane vector types.
const VECTOR_BASE: u8 = LANE_BASE + 16;
// Include code generated by `lib/codegen/meta/gen_types.rs`. This file contains constant
// Include code generated by `cranelift-codegen/meta/gen_types.rs`. This file contains constant
// definitions for all the scalar types as well as common vector types for 64, 128, 256, and
// 512-bit SIMD vectors.
include!(concat!(env!("OUT_DIR"), "/types.rs"));

Просмотреть файл

@ -3,7 +3,7 @@
use crate::settings::{self, detail, Builder};
use core::fmt;
// Include code generated by `lib/codegen/meta-python/gen_settings.py`. This file contains a public
// Include code generated by `cranelift-codegen/meta-python/gen_settings.py`. This file contains a public
// `Flags` struct with an impl for all of the settings defined in
// `lib/codegen/meta-python/isa/arm32/settings.py`.
// `cranelift-codegen/meta-python/isa/arm32/settings.py`.
include!(concat!(env!("OUT_DIR"), "/settings-arm32.rs"));

Просмотреть файл

@ -3,7 +3,7 @@
use crate::settings::{self, detail, Builder};
use core::fmt;
// Include code generated by `lib/codegen/meta-python/gen_settings.py`. This file contains a public
// Include code generated by `cranelift-codegen/meta-python/gen_settings.py`. This file contains a public
// `Flags` struct with an impl for all of the settings defined in
// `lib/codegen/meta-python/isa/arm64/settings.py`.
// `cranelift-codegen/meta-python/isa/arm64/settings.py`.
include!(concat!(env!("OUT_DIR"), "/settings-arm64.rs"));

Просмотреть файл

@ -1,7 +1,7 @@
//! Support types for generated encoding tables.
//!
//! This module contains types and functions for working with the encoding tables generated by
//! `lib/codegen/meta-python/gen_encoding.py`.
//! `cranelift-codegen/meta-python/gen_encoding.py`.
use crate::constant_hash::{probe, Table};
use crate::ir::{Function, InstructionData, Opcode, Type};

Просмотреть файл

@ -68,16 +68,16 @@ use failure_derive::Fail;
use std::boxed::Box;
use target_lexicon::{Architecture, PointerWidth, Triple};
#[cfg(build_riscv)]
#[cfg(feature = "riscv")]
mod riscv;
#[cfg(build_x86)]
#[cfg(feature = "x86")]
mod x86;
#[cfg(build_arm32)]
#[cfg(feature = "arm32")]
mod arm32;
#[cfg(build_arm64)]
#[cfg(feature = "arm64")]
mod arm64;
mod call_conv;
@ -90,12 +90,12 @@ mod stack;
/// Returns a builder that can create a corresponding `TargetIsa`
/// or `Err(LookupError::Unsupported)` if not enabled.
macro_rules! isa_builder {
($module:ident, $name:ident) => {{
#[cfg($name)]
($name:ident, $feature:tt) => {{
#[cfg(feature = $feature)]
fn $name(triple: Triple) -> Result<Builder, LookupError> {
Ok($module::isa_builder(triple))
Ok($name::isa_builder(triple))
};
#[cfg(not($name))]
#[cfg(not(feature = $feature))]
fn $name(_triple: Triple) -> Result<Builder, LookupError> {
Err(LookupError::Unsupported)
}
@ -107,9 +107,9 @@ macro_rules! isa_builder {
/// Return a builder that can create a corresponding `TargetIsa`.
pub fn lookup(triple: Triple) -> Result<Builder, LookupError> {
match triple.architecture {
Architecture::Riscv32 | Architecture::Riscv64 => isa_builder!(riscv, build_riscv)(triple),
Architecture::Riscv32 | Architecture::Riscv64 => isa_builder!(riscv, "riscv")(triple),
Architecture::I386 | Architecture::I586 | Architecture::I686 | Architecture::X86_64 => {
isa_builder!(x86, build_x86)(triple)
isa_builder!(x86, "x86")(triple)
}
Architecture::Thumbv6m
| Architecture::Thumbv7em
@ -118,8 +118,8 @@ pub fn lookup(triple: Triple) -> Result<Builder, LookupError> {
| Architecture::Armv4t
| Architecture::Armv5te
| Architecture::Armv7
| Architecture::Armv7s => isa_builder!(arm32, build_arm32)(triple),
Architecture::Aarch64 => isa_builder!(arm64, build_arm64)(triple),
| Architecture::Armv7s => isa_builder!(arm32, "arm32")(triple),
Architecture::Aarch64 => isa_builder!(arm64, "arm64")(triple),
_ => Err(LookupError::Unsupported),
}
}

Просмотреть файл

@ -3,9 +3,9 @@
use crate::settings::{self, detail, Builder};
use core::fmt;
// Include code generated by `lib/codegen/meta-python/gen_settings.py`. This file contains a public
// Include code generated by `cranelift-codegen/meta-python/gen_settings.py`. This file contains a public
// `Flags` struct with an impl for all of the settings defined in
// `lib/codegen/meta-python/isa/riscv/settings.py`.
// `cranelift-codegen/meta-python/isa/riscv/settings.py`.
include!(concat!(env!("OUT_DIR"), "/settings-riscv.rs"));
#[cfg(test)]

Просмотреть файл

@ -115,9 +115,18 @@ impl ArgAssigner for Args {
}
// Try to use an FPR.
if ty.is_float() && self.fpr_used < self.fpr_limit {
let reg = FPR.unit(self.fpr_used);
self.fpr_used += 1;
let fpr_offset = if self.call_conv == CallConv::WindowsFastcall {
// Float and general registers on windows share the same parameter index.
// The used register depends entirely on the parameter index: Even if XMM0
// is not used for the first parameter, it cannot be used for the second parameter.
debug_assert_eq!(self.fpr_limit, self.gpr.len());
&mut self.gpr_used
} else {
&mut self.fpr_used
};
if ty.is_float() && *fpr_offset < self.fpr_limit {
let reg = FPR.unit(*fpr_offset);
*fpr_offset += 1;
return ArgumentLoc::Reg(reg).into();
}

Просмотреть файл

@ -3,9 +3,9 @@
use crate::settings::{self, detail, Builder};
use core::fmt;
// Include code generated by `lib/codegen/meta-python/gen_settings.py`. This file contains a public
// Include code generated by `cranelift-codegen/meta-python/gen_settings.py`. This file contains a public
// `Flags` struct with an impl for all of the settings defined in
// `lib/codegen/meta-python/isa/x86/settings.py`.
// `cranelift-codegen/meta-python/isa/x86/settings.py`.
include!(concat!(env!("OUT_DIR"), "/settings-x86.rs"));
#[cfg(test)]

Просмотреть файл

@ -118,7 +118,7 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is
}
// Include legalization patterns that were generated by `gen_legalizer.py` from the `XForms` in
// `lib/codegen/meta-python/base/legalize.py`.
// `cranelift-codegen/meta-python/base/legalize.py`.
//
// Concretely, this defines private functions `narrow()`, and `expand()`.
include!(concat!(env!("OUT_DIR"), "/legalizer.rs"));

Просмотреть файл

@ -1,7 +1,7 @@
//! Predicate functions for testing instruction fields.
//!
//! This module defines functions that are used by the instruction predicates defined by
//! `lib/codegen/meta-python/cdsl/predicates.py` classes.
//! `cranelift-codegen/meta-python/cdsl/predicates.py` classes.
//!
//! The predicates the operate on integer fields use `Into<i64>` as a shared trait bound. This
//! bound is implemented by all the native integer types as well as `Imm64`.

Просмотреть файл

@ -270,7 +270,7 @@ impl fmt::Display for Pressure {
}
#[cfg(test)]
#[cfg(build_arm32)]
#[cfg(feature = "arm32")]
mod tests {
use super::Pressure;
use crate::isa::{RegClass, TargetIsa};

Просмотреть файл

@ -1127,7 +1127,7 @@ impl fmt::Display for Solver {
}
#[cfg(test)]
#[cfg(build_arm32)]
#[cfg(feature = "arm32")]
mod tests {
use super::{Move, Solver};
use crate::entity::EntityRef;

Просмотреть файл

@ -333,7 +333,7 @@ pub mod detail {
// Include code generated by `meta-python/gen_settings.py`. This file contains a public `Flags`
// struct with an impl for all of the settings defined in
// `lib/codegen/meta-python/base/settings.py`.
// `cranelift-codegen/meta-python/base/settings.py`.
include!(concat!(env!("OUT_DIR"), "/settings.rs"));
/// Wrapper containing flags and optionally a `TargetIsa` trait object.

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"5cf393cd6f9778b92793bce26ed00834913064d7a69f99632cd3703b198a1298","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"687428ee0442013c0d5962dd78d0964830233bc4cb19aa530d30da0f1dc437a9","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"139fc0eeed2e8cde2b82b8b7402e8c7cd079a9fbbf1ec692622e5ad0c10d9faf","src/list.rs":"fc3decc81bcef92e106aae53e586a0ef21d70916fa53a48f7b813c5da44b8dc2","src/map.rs":"f35031459aca446734726c132c0a571482f1ec2ca8221b352d2e18c74950e977","src/packed_option.rs":"9d47f5b8302ee685c096817e376144e363507d1c77ef562d3ae4dbddae568195","src/primary.rs":"e95e4b2ed36413d80c4c0dcfc19dcf8a9f52e34467aaec196c774fd639747028","src/set.rs":"ec0ff7a9ee674c90ff9d06ea1fd4ab05039369146c2d259f476c6f612417933f","src/sparse.rs":"cf345a81d69a5dddaed4778b6aaaf06c70da2c1fd4cd21e366ed6ca5906ffdab"},"package":"c4ccc3743848cbb53e58b62685703dc12ea553c3bc8f21db76f23c68054eb69a"}
{"files":{"Cargo.toml":"bdfb55271249705ca4f66080d59757b97af8872bcd0080c858780d472d6094bc","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"687428ee0442013c0d5962dd78d0964830233bc4cb19aa530d30da0f1dc437a9","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"139fc0eeed2e8cde2b82b8b7402e8c7cd079a9fbbf1ec692622e5ad0c10d9faf","src/list.rs":"fc3decc81bcef92e106aae53e586a0ef21d70916fa53a48f7b813c5da44b8dc2","src/map.rs":"f35031459aca446734726c132c0a571482f1ec2ca8221b352d2e18c74950e977","src/packed_option.rs":"9d47f5b8302ee685c096817e376144e363507d1c77ef562d3ae4dbddae568195","src/primary.rs":"e95e4b2ed36413d80c4c0dcfc19dcf8a9f52e34467aaec196c774fd639747028","src/set.rs":"ec0ff7a9ee674c90ff9d06ea1fd4ab05039369146c2d259f476c6f612417933f","src/sparse.rs":"cf345a81d69a5dddaed4778b6aaaf06c70da2c1fd4cd21e366ed6ca5906ffdab"},"package":"4e124e09cb7dc85fbe2162420aebbe8e9e3b8f9210901be7867416c5beec8226"}

Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "cranelift-entity"
version = "0.28.0"
version = "0.29.0"
authors = ["The Cranelift Project Developers"]
description = "Data structures using entity references as mapping keys"
documentation = "https://cranelift.readthedocs.io/"

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"ad90f0d52f7e2a3c93100a0ce05c76cb424933153726c6496185e099dadd0ade","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"59033d83472a657704eb0fc2c882c28f8a673156f8371c909a4875451649780e","src/lib.rs":"ca09a18819b35ba4c95ab7ad05f708a16fa059378e948b9f6b9c5af87baeb47b","src/ssa.rs":"88cb07071943f3e72a91c91afb58960689b4d9c56352b3bb7cd5d69288066190","src/switch.rs":"1afa11f037c91d6c87f8c6b88cddddc5f22c2b6ee9d0f05382ed05d0c4f29135","src/variable.rs":"f082efaa4b2d3c5eb48f6344149408074e1e15cb581f7a63f549313c7a1037be"},"package":"89ecc8b49d4ab98f2c121832fee365da88b7b0ffad77d4e328015b1fd1f7f4b1"}
{"files":{"Cargo.toml":"b5d70a2290241ca933b8bc6530f92f784c508d34448f86516ce3ddbdd62c1ba7","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"f3ad024e4895eddf83c8fe19c93ae37709a6bf27db2e1beef153fd742d99defa","src/lib.rs":"1cc2e7aaffa45bccea9e59fcc9d9c5d295a9f7adacd6bd55933834e20e969aef","src/ssa.rs":"88cb07071943f3e72a91c91afb58960689b4d9c56352b3bb7cd5d69288066190","src/switch.rs":"1afa11f037c91d6c87f8c6b88cddddc5f22c2b6ee9d0f05382ed05d0c4f29135","src/variable.rs":"f082efaa4b2d3c5eb48f6344149408074e1e15cb581f7a63f549313c7a1037be"},"package":"2833c6e1a93c524ce0c2ab31266cdc84d38c906349f79f19378a5e5995727b23"}

Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "cranelift-frontend"
version = "0.28.0"
version = "0.29.0"
authors = ["The Cranelift Project Developers"]
description = "Cranelift IR builder helper"
documentation = "https://cranelift.readthedocs.io/"
@ -22,7 +22,7 @@ categories = ["no-std"]
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/CraneStation/cranelift"
[dependencies.cranelift-codegen]
version = "0.28.0"
version = "0.29.0"
default-features = false
[dependencies.hashmap_core]

Просмотреть файл

@ -638,7 +638,7 @@ impl<'a> FunctionBuilder<'a> {
/// Calls libc.memset
///
/// Writes `size` bytes of value `ch` to memory starting at `buffer`.
/// Writes `size` bytes of i8 value `ch` to memory starting at `buffer`.
pub fn call_memset(
&mut self,
config: TargetFrontendConfig,
@ -672,7 +672,7 @@ impl<'a> FunctionBuilder<'a> {
&mut self,
config: TargetFrontendConfig,
buffer: Value,
ch: u32,
ch: u8,
size: u64,
buffer_align: u8,
) {
@ -702,7 +702,7 @@ impl<'a> FunctionBuilder<'a> {
let load_and_store_amount = size / access_size;
if load_and_store_amount > THRESHOLD {
let ch = self.ins().iconst(types::I32, i64::from(ch));
let ch = self.ins().iconst(types::I8, i64::from(ch));
let size = self.ins().iconst(config.pointer_type(), size as i64);
self.call_memset(config, buffer, ch, size);
} else {
@ -1078,6 +1078,175 @@ ebb0:
);
}
#[test]
fn not_so_small_memcpy() {
use core::str::FromStr;
use cranelift_codegen::{isa, settings};
let shared_builder = settings::builder();
let shared_flags = settings::Flags::new(shared_builder);
let triple = ::target_lexicon::Triple::from_str("arm").expect("Couldn't create arm triple");
let target = isa::lookup(triple)
.ok()
.map(|b| b.finish(shared_flags))
.expect("This test requires arm support.");
let mut sig = Signature::new(target.default_call_conv());
sig.returns.push(AbiParam::new(I32));
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_ebb();
let x = Variable::new(0);
let y = Variable::new(16);
builder.declare_var(x, target.pointer_type());
builder.declare_var(y, target.pointer_type());
builder.append_ebb_params_for_function_params(block0);
builder.switch_to_block(block0);
let src = builder.use_var(x);
let dest = builder.use_var(y);
let size = 8192;
builder.emit_small_memcpy(target.frontend_config(), dest, src, size, 8, 8);
builder.ins().return_(&[dest]);
builder.seal_all_blocks();
builder.finalize();
}
assert_eq!(
func.display(None).to_string(),
"function %sample() -> i32 system_v {
sig0 = (i32, i32, i32) system_v
fn0 = %Memcpy sig0
ebb0:
v4 = iconst.i32 0
v1 -> v4
v3 = iconst.i32 0
v0 -> v3
v2 = iconst.i32 8192
call fn0(v1, v0, v2)
return v1
}
"
);
}
#[test]
fn small_memset() {
use core::str::FromStr;
use cranelift_codegen::{isa, settings};
let shared_builder = settings::builder();
let shared_flags = settings::Flags::new(shared_builder);
let triple = ::target_lexicon::Triple::from_str("arm").expect("Couldn't create arm triple");
let target = isa::lookup(triple)
.ok()
.map(|b| b.finish(shared_flags))
.expect("This test requires arm support.");
let mut sig = Signature::new(target.default_call_conv());
sig.returns.push(AbiParam::new(I32));
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_ebb();
let y = Variable::new(16);
builder.declare_var(y, target.pointer_type());
builder.append_ebb_params_for_function_params(block0);
builder.switch_to_block(block0);
let dest = builder.use_var(y);
let size = 8;
builder.emit_small_memset(target.frontend_config(), dest, 1, size, 8);
builder.ins().return_(&[dest]);
builder.seal_all_blocks();
builder.finalize();
}
assert_eq!(
func.display(None).to_string(),
"function %sample() -> i32 system_v {
ebb0:
v2 = iconst.i32 0
v0 -> v2
v1 = iconst.i64 0x0001_0001_0101
store aligned v1, v0
return v0
}
"
);
}
#[test]
fn not_so_small_memset() {
use core::str::FromStr;
use cranelift_codegen::{isa, settings};
let shared_builder = settings::builder();
let shared_flags = settings::Flags::new(shared_builder);
let triple = ::target_lexicon::Triple::from_str("arm").expect("Couldn't create arm triple");
let target = isa::lookup(triple)
.ok()
.map(|b| b.finish(shared_flags))
.expect("This test requires arm support.");
let mut sig = Signature::new(target.default_call_conv());
sig.returns.push(AbiParam::new(I32));
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_ebb();
let y = Variable::new(16);
builder.declare_var(y, target.pointer_type());
builder.append_ebb_params_for_function_params(block0);
builder.switch_to_block(block0);
let dest = builder.use_var(y);
let size = 8192;
builder.emit_small_memset(target.frontend_config(), dest, 1, size, 8);
builder.ins().return_(&[dest]);
builder.seal_all_blocks();
builder.finalize();
}
assert_eq!(
func.display(None).to_string(),
"function %sample() -> i32 system_v {
sig0 = (i32, i32, i32) system_v
fn0 = %Memset sig0
ebb0:
v4 = iconst.i32 0
v0 -> v4
v1 = iconst.i8 1
v2 = iconst.i32 8192
v3 = uextend.i32 v1
call fn0(v0, v3, v2)
return v0
}
"
);
}
#[test]
fn test_greatest_divisible_power_of_two() {
assert_eq!(64, greatest_divisible_power_of_two(64));

Просмотреть файл

@ -20,8 +20,8 @@
//!
//! This API has been designed to help you translate your mutable variables into
//! [`SSA`](https://en.wikipedia.org/wiki/Static_single_assignment_form) form.
//! [`use_var`](struct.FunctionBuilder.html#method.use_var) will returns the Cranelift IR value
//! that corresponds to your mutable variable at a precise point in the program. However, you know
//! [`use_var`](struct.FunctionBuilder.html#method.use_var) will return the Cranelift IR value
//! that corresponds to your mutable variable at a precise point in the program. However, if you know
//! beforehand that one of your variables is defined only once, for instance if it is the result
//! of an intermediate expression in an expression-based language, then you can translate it
//! directly by the Cranelift IR value returned by the instruction builder. Using the
@ -30,7 +30,7 @@
//! beforehand if a variable is immutable or not).
//!
//! The moral is that you should use these three functions to handle all your mutable variables,
//! even those that are not present in the source code but artefacts of the translation. It is up
//! even those that are not present in the source code but artifacts of the translation. It is up
//! to you to keep a mapping between the mutable variables of your language and their `Variable`
//! index that is used by Cranelift. Caution: as the `Variable` is used by Cranelift to index an
//! array containing information about your mutable variables, when you create a new `Variable`

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"084b95108fcb6c72313a0fe318293c573b8141debf8d7523030eff79169369c8","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"00740be2943fe96d8588d15ec3b812b997f41e4bc9cd27510173889172aff8bc","src/environ/dummy.rs":"caf4468c264720474c65bd7463c7e6c4f54076e05bc034875d44f4da3205c81e","src/environ/mod.rs":"617c147485038dfd797ab0ea71b4cfa9574d95d5d5b1ca362c6b7b6a462cf577","src/environ/spec.rs":"2b1cbb0992d31755c19673de36e2c54df1fd9096f72693ec35de96e8f085c9b8","src/func_translator.rs":"45dfb6b5f642c8c464bd2f75d423e50bc981ccfeae5db52daaa43d3368fac1ec","src/lib.rs":"95183fc86a20687e547d2edbd9868681005f0c3a2ca1ae1471e2ae38098f85c6","src/module_translator.rs":"ac54c24aaa3775f72ccd16d1781be648bb0e83ea83909f933d07e86ef1879213","src/sections_translator.rs":"1fc27a5263effce461d33df837985ec5d59bb719c143d3db6124217befb8735e","src/state.rs":"1b1fa08736702d062c49118fba67f0a13752b4d863c1d11abd90eeb219777a23","src/translation_utils.rs":"50b45794018e1c471694f4f60707329213c9fb4153798a879953a479213b8a56","tests/wasm_testsuite.rs":"217d1f6508e9e0b4e364a8db94164d45b60557e6d9f21776998d32fd51eac06c"},"package":"c7eccd196ecd01a2394ce05e2259afe5704874816b058541c7cce7794f0e835e"}
{"files":{"Cargo.toml":"ed12a641047878536a2be05241a6a59b30e029584168d15fe8dff9ef4e226cf7","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"00740be2943fe96d8588d15ec3b812b997f41e4bc9cd27510173889172aff8bc","src/environ/dummy.rs":"42df6db37892ea28e9a004934599d8bbcbd62db52f787486cd81a23f1a563613","src/environ/mod.rs":"617c147485038dfd797ab0ea71b4cfa9574d95d5d5b1ca362c6b7b6a462cf577","src/environ/spec.rs":"1c22dfbf956d80cbf34a6b8087dfb38b1f73a5cf010c341b673dba4286468bfe","src/func_translator.rs":"b27debdc0d17f30ecfa7a9bf4bdeea6054966507b5d398ccd4165574da4f674a","src/lib.rs":"95183fc86a20687e547d2edbd9868681005f0c3a2ca1ae1471e2ae38098f85c6","src/module_translator.rs":"ac54c24aaa3775f72ccd16d1781be648bb0e83ea83909f933d07e86ef1879213","src/sections_translator.rs":"499f6d1ca8a4151dab891d14bb901c292adea13b1daccdd6e2b104fb9f5a49a7","src/state.rs":"1b1fa08736702d062c49118fba67f0a13752b4d863c1d11abd90eeb219777a23","src/translation_utils.rs":"50b45794018e1c471694f4f60707329213c9fb4153798a879953a479213b8a56","tests/wasm_testsuite.rs":"c6eac90ebdb6b58d8247c22e04454d95943c5ab0621084b624eb20c0ce2a96a3"},"package":"e75efb45cd8d8700b4bdc225f0077bc7c615f84a5807ce001d59b4da48d85573"}

8
third_party/rust/cranelift-wasm/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "cranelift-wasm"
version = "0.28.0"
version = "0.29.0"
authors = ["The Cranelift Project Developers"]
description = "Translator from WebAssembly to Cranelift IR"
readme = "README.md"
@ -26,15 +26,15 @@ version = "0.2.2"
default-features = false
[dependencies.cranelift-codegen]
version = "0.28.0"
version = "0.29.0"
default-features = false
[dependencies.cranelift-entity]
version = "0.28.0"
version = "0.29.0"
default-features = false
[dependencies.cranelift-frontend]
version = "0.28.0"
version = "0.29.0"
default-features = false
[dependencies.failure]

Просмотреть файл

@ -458,7 +458,11 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
self.info.start_func = Some(func_index);
}
fn define_function_body(&mut self, body_bytes: &'data [u8]) -> WasmResult<()> {
fn define_function_body(
&mut self,
body_bytes: &'data [u8],
body_offset: usize,
) -> WasmResult<()> {
let func = {
let mut func_environ = DummyFuncEnvironment::new(&self.info, self.return_mode);
let func_index =
@ -467,7 +471,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
let sig = func_environ.vmctx_sig(self.get_func_type(func_index));
let mut func = ir::Function::with_name_signature(name, sig);
self.trans
.translate(body_bytes, &mut func, &mut func_environ)?;
.translate(body_bytes, body_offset, &mut func, &mut func_environ)?;
func
};
self.func_bytecode_sizes.push(body_bytes.len());

Просмотреть файл

@ -343,7 +343,11 @@ pub trait ModuleEnvironment<'data> {
///
/// Note there's no `reserve_function_bodies` function because the number of
/// functions is already provided by `reserve_func_types`.
fn define_function_body(&mut self, body_bytes: &'data [u8]) -> WasmResult<()>;
fn define_function_body(
&mut self,
body_bytes: &'data [u8],
body_offset: usize,
) -> WasmResult<()>;
/// Provides the number of data initializers up front. By default this does nothing, but
/// implementations can use this to preallocate memory if desired.

Просмотреть файл

@ -54,10 +54,15 @@ impl FuncTranslator {
pub fn translate<FE: FuncEnvironment + ?Sized>(
&mut self,
code: &[u8],
code_offset: usize,
func: &mut ir::Function,
environ: &mut FE,
) -> WasmResult<()> {
self.translate_from_reader(BinaryReader::new(code), func, environ)
self.translate_from_reader(
BinaryReader::new_with_offset(code, code_offset),
func,
environ,
)
}
/// Translate a binary WebAssembly function from a `BinaryReader`.
@ -222,11 +227,9 @@ fn parse_function_body<FE: FuncEnvironment + ?Sized>(
/// Get the current source location from a reader.
fn cur_srcloc(reader: &BinaryReader) -> ir::SourceLoc {
// We record source locations as byte code offsets relative to the beginning of the function.
// This will wrap around of a single function's byte code is larger than 4 GB, but a) the
// WebAssembly format doesn't allow for that, and b) that would hit other Cranelift
// implementation limits anyway.
ir::SourceLoc::new(reader.current_position() as u32)
// We record source locations as byte code offsets relative to the beginning of the file.
// This will wrap around if byte code is larger than 4 GB.
ir::SourceLoc::new(reader.original_position() as u32)
}
#[cfg(test)]
@ -270,7 +273,7 @@ mod tests {
ctx.func.signature.returns.push(ir::AbiParam::new(I32));
trans
.translate(&BODY, &mut ctx.func, &mut runtime.func_env())
.translate(&BODY, 0, &mut ctx.func, &mut runtime.func_env())
.unwrap();
debug!("{}", ctx.func.display(None));
ctx.verify(&flags).unwrap();
@ -308,7 +311,7 @@ mod tests {
ctx.func.signature.returns.push(ir::AbiParam::new(I32));
trans
.translate(&BODY, &mut ctx.func, &mut runtime.func_env())
.translate(&BODY, 0, &mut ctx.func, &mut runtime.func_env())
.unwrap();
debug!("{}", ctx.func.display(None));
ctx.verify(&flags).unwrap();
@ -354,7 +357,7 @@ mod tests {
ctx.func.signature.returns.push(ir::AbiParam::new(I32));
trans
.translate(&BODY, &mut ctx.func, &mut runtime.func_env())
.translate(&BODY, 0, &mut ctx.func, &mut runtime.func_env())
.unwrap();
debug!("{}", ctx.func.display(None));
ctx.verify(&flags).unwrap();

Просмотреть файл

@ -295,7 +295,8 @@ pub fn parse_code_section<'data>(
for body in code {
let mut reader = body?.get_binary_reader();
let size = reader.bytes_remaining();
environ.define_function_body(reader.read_bytes(size)?)?;
let offset = reader.original_position();
environ.define_function_body(reader.read_bytes(size)?, offset)?;
}
Ok(())
}

Просмотреть файл

@ -14,7 +14,7 @@ use wabt::wat2wasm;
#[test]
fn testsuite() {
let mut paths: Vec<_> = fs::read_dir("../../wasmtests")
let mut paths: Vec<_> = fs::read_dir("../wasmtests")
.unwrap()
.map(|r| r.unwrap())
.filter(|p| {
@ -39,7 +39,7 @@ fn testsuite() {
fn use_fallthrough_return() {
let flags = Flags::new(settings::builder());
handle_module(
Path::new("../../wasmtests/use_fallthrough_return.wat"),
Path::new("../wasmtests/use_fallthrough_return.wat"),
&flags,
ReturnMode::FallthroughReturn,
);