diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-01-25 16:43:23 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-01-25 16:43:23 -0800 |
commit | 513cfdc94d0b2e99c48fda4dbbbdfcff0aa97a0b (patch) | |
tree | 4c13bade4227d1a6d199076c51bca79550772c26 /src | |
parent | da726f060373d957704c51cdb019026e6c3c0a41 (diff) | |
parent | c0c72f2fed5cd7ef4512cffa8c18152658f20e2c (diff) | |
download | binaryen-513cfdc94d0b2e99c48fda4dbbbdfcff0aa97a0b.tar.gz binaryen-513cfdc94d0b2e99c48fda4dbbbdfcff0aa97a0b.tar.bz2 binaryen-513cfdc94d0b2e99c48fda4dbbbdfcff0aa97a0b.zip |
Merge pull request #140 from WebAssembly/alignment
Latest LLVM + http://reviews.llvm.org/D16534
Diffstat (limited to 'src')
-rw-r--r-- | src/s2wasm.h | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h index 8b34d6b03..13f424f7c 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -159,6 +159,7 @@ private: return cashew::IString(str.c_str(), false); } + // get an int int32_t getInt() { const char* loc = s; uint32_t value = 0; @@ -192,6 +193,15 @@ private: return value; } + // get an int from an arbitrary string, with our full error handling + int32_t getInt(const char *from) { + const char *before = s; + s = from; + auto ret = getInt(); + s = before; + return ret; + } + // gets a constant, which may be a relocation for later. // returns whether this is a relocation bool getConst(uint32_t* target) { @@ -492,6 +502,10 @@ private: inputs[i] = curr; } if (*s == ')') s++; // tolerate 0(argument) syntax, where we started at the 'a' + if (*s == ':') { // tolerate :attribute=value syntax (see getAttributes) + s++; + skipToSep(); + } if (i < num - 1) skipComma(); } for (int i = num-1; i >= 0; i--) { @@ -515,6 +529,24 @@ private: addToBlock(set); } }; + auto getAttributes = [&](int num) { + const char *before = s; + std::vector<const char*> attributes; // TODO: optimize (if .s format doesn't change) + attributes.resize(num); + for (int i = 0; i < num; i++) { + skipToSep(); + if (*s == ')') s++; // tolerate 0(argument) syntax, where we started at the 'a' + if (*s == ':') { + attributes[i] = s + 1; + } else { + attributes[i] = nullptr; + } + if (i < num - 1) skipComma(); + } + s = before; + return attributes; + }; + // auto makeBinary = [&](BinaryOp op, WasmType type) { Name assign = getAssign(); skipComma(); @@ -559,9 +591,14 @@ private: match("_u"); Name assign = getAssign(); getConst(&curr->offset); - curr->align = curr->bytes; // XXX mustMatch("("); + auto attributes = getAttributes(1); curr->ptr = getInput(); + curr->align = curr->bytes; + if (attributes[0]) { + assert(strncmp(attributes[0], "p2align=", 8) == 0); + curr->align = pow(2, getInt(attributes[0] + 8)); + } setOutput(curr, assign); }; auto makeStore = [&](WasmType type) { @@ -570,12 +607,17 @@ private: curr->type = type; int32_t bytes = getInt(); curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type); - curr->align = curr->bytes; // XXX Name assign = getAssign(); getConst(&curr->offset); mustMatch("("); + auto attributes = getAttributes(2); auto inputs = getInputs(2); curr->ptr = inputs[0]; + curr->align = curr->bytes; + if (attributes[0]) { + assert(strncmp(attributes[0], "p2align=", 8) == 0); + curr->align = pow(2, getInt(attributes[0] + 8)); + } curr->value = inputs[1]; setOutput(curr, assign); }; |