mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add i32 functions to wasm dialect.
This commit is contained in:
parent
7cca036f4c
commit
8f546849f2
@ -20,70 +20,86 @@
|
|||||||
|
|
||||||
#include <libyul/backends/wasm/WasmDialect.h>
|
#include <libyul/backends/wasm/WasmDialect.h>
|
||||||
|
|
||||||
|
#include <libyul/Exceptions.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
|
|
||||||
WasmDialect::WasmDialect()
|
WasmDialect::WasmDialect()
|
||||||
{
|
{
|
||||||
defaultType = "i64"_yulstring;
|
YulString i64 = "i64"_yulstring;
|
||||||
boolType = "i64"_yulstring;
|
YulString i32 = "i32"_yulstring;
|
||||||
types = {"i64"_yulstring, "i32"_yulstring};
|
defaultType = i64;
|
||||||
|
boolType = i32;
|
||||||
|
types = {i64, i32};
|
||||||
|
|
||||||
for (auto const& name: {
|
for (auto t: types)
|
||||||
"i64.add",
|
for (auto const& name: {
|
||||||
"i64.sub",
|
"add",
|
||||||
"i64.mul",
|
"sub",
|
||||||
"i64.div_u",
|
"mul",
|
||||||
"i64.rem_u",
|
"div_u",
|
||||||
"i64.and",
|
"rem_u",
|
||||||
"i64.or",
|
"and",
|
||||||
"i64.xor",
|
"or",
|
||||||
"i64.shl",
|
"xor",
|
||||||
"i64.shr_u",
|
"shl",
|
||||||
"i64.eq",
|
"shr_u",
|
||||||
"i64.ne",
|
})
|
||||||
"i64.lt_u",
|
addFunction(t.str() + "." + name, {t, t}, {t});
|
||||||
"i64.gt_u",
|
|
||||||
"i64.le_u",
|
|
||||||
"i64.ge_u"
|
|
||||||
})
|
|
||||||
addFunction(name, 2, 1);
|
|
||||||
|
|
||||||
m_functions["i64.lt_u"_yulstring].returns.front() = "i32"_yulstring;
|
for (auto t: types)
|
||||||
m_functions["i64.gt_u"_yulstring].returns.front() = "i32"_yulstring;
|
for (auto const& name: {
|
||||||
m_functions["i64.le_u"_yulstring].returns.front() = "i32"_yulstring;
|
"eq",
|
||||||
m_functions["i64.ge_u"_yulstring].returns.front() = "i32"_yulstring;
|
"ne",
|
||||||
m_functions["i64.eq"_yulstring].returns.front() = "i32"_yulstring;
|
"lt_u",
|
||||||
m_functions["i64.ne"_yulstring].returns.front() = "i32"_yulstring;
|
"gt_u",
|
||||||
|
"le_u",
|
||||||
|
"ge_u"
|
||||||
|
})
|
||||||
|
addFunction(t.str() + "." + name, {t, t}, {i32});
|
||||||
|
|
||||||
addFunction("i64.eqz", 1, 1);
|
addFunction("i32.eqz", {i32}, {i32});
|
||||||
m_functions["i64.eqz"_yulstring].returns.front() = "i32"_yulstring;
|
addFunction("i64.eqz", {i64}, {i32});
|
||||||
|
|
||||||
addFunction("i64.clz", 1, 1);
|
addFunction("i32.clz", {i32}, {i32});
|
||||||
|
addFunction("i64.clz", {i64}, {i64});
|
||||||
|
|
||||||
addFunction("i64.store", 2, 0, false);
|
addFunction("i32.wrap_i64", {i64}, {i32});
|
||||||
m_functions["i64.store"_yulstring].parameters.front() = "i32"_yulstring;
|
|
||||||
|
addFunction("i64.extend_i32_u", {i32}, {i64});
|
||||||
|
|
||||||
|
addFunction("i32.store", {i32, i32}, {}, false);
|
||||||
|
m_functions["i32.store"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
addFunction("i64.store", {i32, i64}, {}, false);
|
||||||
m_functions["i64.store"_yulstring].sideEffects.invalidatesStorage = false;
|
m_functions["i64.store"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
|
||||||
addFunction("i64.store8", 2, 0, false);
|
addFunction("i32.store8", {i32, i32}, {}, false);
|
||||||
m_functions["i64.store8"_yulstring].parameters.front() = "i32"_yulstring;
|
m_functions["i32.store8"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
addFunction("i64.store8", {i32, i64}, {}, false);
|
||||||
m_functions["i64.store8"_yulstring].sideEffects.invalidatesStorage = false;
|
m_functions["i64.store8"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
|
||||||
addFunction("i64.load", 1, 1, false);
|
addFunction("i32.load", {i32}, {i32}, false);
|
||||||
m_functions["i64.load"_yulstring].parameters.front() = "i32"_yulstring;
|
m_functions["i32.load"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
|
m_functions["i32.load"_yulstring].sideEffects.invalidatesMemory = false;
|
||||||
|
m_functions["i32.load"_yulstring].sideEffects.sideEffectFree = true;
|
||||||
|
m_functions["i32.load"_yulstring].sideEffects.sideEffectFreeIfNoMSize = true;
|
||||||
|
addFunction("i64.load", {i32}, {i64}, false);
|
||||||
m_functions["i64.load"_yulstring].sideEffects.invalidatesStorage = false;
|
m_functions["i64.load"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
m_functions["i64.load"_yulstring].sideEffects.invalidatesMemory = false;
|
m_functions["i64.load"_yulstring].sideEffects.invalidatesMemory = false;
|
||||||
m_functions["i64.load"_yulstring].sideEffects.sideEffectFree = true;
|
m_functions["i64.load"_yulstring].sideEffects.sideEffectFree = true;
|
||||||
m_functions["i64.load"_yulstring].sideEffects.sideEffectFreeIfNoMSize = true;
|
m_functions["i64.load"_yulstring].sideEffects.sideEffectFreeIfNoMSize = true;
|
||||||
|
|
||||||
addFunction("drop", 1, 0);
|
// Drop is actually overloaded for all types, but Yul does not support that.
|
||||||
|
// We could introduce "i32.drop".
|
||||||
|
addFunction("drop", {i64}, {});
|
||||||
|
|
||||||
addFunction("unreachable", 0, 0, false);
|
addFunction("unreachable", {}, {}, false);
|
||||||
m_functions["unreachable"_yulstring].sideEffects.invalidatesStorage = false;
|
m_functions["unreachable"_yulstring].sideEffects.invalidatesStorage = false;
|
||||||
m_functions["unreachable"_yulstring].sideEffects.invalidatesMemory = false;
|
m_functions["unreachable"_yulstring].sideEffects.invalidatesMemory = false;
|
||||||
|
|
||||||
addFunction("datasize", 1, 1, true, true);
|
addFunction("datasize", {i64}, {i64}, true, true);
|
||||||
addFunction("dataoffset", 1, 1, true, true);
|
addFunction("dataoffset", {i64}, {i64}, true, true);
|
||||||
|
|
||||||
addEthereumExternals();
|
addEthereumExternals();
|
||||||
}
|
}
|
||||||
@ -167,8 +183,8 @@ void WasmDialect::addEthereumExternals()
|
|||||||
|
|
||||||
void WasmDialect::addFunction(
|
void WasmDialect::addFunction(
|
||||||
string _name,
|
string _name,
|
||||||
size_t _params,
|
vector<YulString> _params,
|
||||||
size_t _returns,
|
vector<YulString> _returns,
|
||||||
bool _movable,
|
bool _movable,
|
||||||
bool _literalArguments
|
bool _literalArguments
|
||||||
)
|
)
|
||||||
@ -176,8 +192,9 @@ void WasmDialect::addFunction(
|
|||||||
YulString name{move(_name)};
|
YulString name{move(_name)};
|
||||||
BuiltinFunction& f = m_functions[name];
|
BuiltinFunction& f = m_functions[name];
|
||||||
f.name = name;
|
f.name = name;
|
||||||
f.parameters.resize(_params);
|
f.parameters = std::move(_params);
|
||||||
f.returns.resize(_returns);
|
yulAssert(_returns.size() <= 1, "The Wasm 1.0 specification only allows up to 1 return value.");
|
||||||
|
f.returns = std::move(_returns);
|
||||||
f.sideEffects = _movable ? SideEffects{} : SideEffects::worst();
|
f.sideEffects = _movable ? SideEffects{} : SideEffects::worst();
|
||||||
f.isMSize = false;
|
f.isMSize = false;
|
||||||
f.literalArguments = _literalArguments;
|
f.literalArguments = _literalArguments;
|
||||||
|
@ -56,7 +56,13 @@ struct WasmDialect: public Dialect
|
|||||||
private:
|
private:
|
||||||
void addEthereumExternals();
|
void addEthereumExternals();
|
||||||
|
|
||||||
void addFunction(std::string _name, size_t _params, size_t _returns, bool _movable = true, bool _literalArguments = false);
|
void addFunction(
|
||||||
|
std::string _name,
|
||||||
|
std::vector<YulString> _params,
|
||||||
|
std::vector<YulString> _returns,
|
||||||
|
bool _movable = true,
|
||||||
|
bool _literalArguments = false
|
||||||
|
);
|
||||||
|
|
||||||
std::map<YulString, BuiltinFunction> m_functions;
|
std::map<YulString, BuiltinFunction> m_functions;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user