From 1014598c02e9635d9d4a008010d43c3c0b845e06 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 14 Oct 2012 23:42:59 +0200 Subject: [PATCH] handle compare/jump instructions in script assembler --- src/loader/Interpreter.cpp | 137 +++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index bd7473a..6bb022f 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -420,6 +420,58 @@ void Interpreter::ReadScript(const std::vector &s, Script *script if (i == end) { throw Error("unexpected script end after rand"); } + } else if (cmd == "cmp") { + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jmp") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jeq") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jne") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jl") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jle") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jg") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } + } else if (cmd == "jge") { + size += sizeof(int); + ++i; + if (i == end) { + throw Error("unexpected script end after cmp"); + } } else if (cmd == "sysc") { } else { @@ -530,6 +582,91 @@ void Interpreter::ReadScript(const std::vector &s, Script *script } else { throw Error("unexpected register " + reg); } + } else if (cmd == "cmp") { + ++i; + const string ®((*i)->RegisterName()); + ++i; + if (reg == "i0") { + if ((*i)->GetType() == ScriptToken::REGISTER && (*i)->RegisterName() == "i1") { + text[cursor] = Script::CODE_CMP_I0_I1; + ++cursor; + } else { + text[cursor] = Script::CODE_CMP_I0; + ++cursor; + ReadScriptInteger(**i, text + cursor); + cursor += sizeof(int); + } + } else if (reg == "i1") { + text[cursor] = Script::CODE_CMP_I1; + ++cursor; + ReadScriptInteger(**i, text + cursor); + cursor += sizeof(int); + } else { + throw Error("cannot use " + reg + " as lhs for comparison"); + } + } else if (cmd == "jmp") { + text[cursor] = Script::CODE_JUMP; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); + } else if (cmd == "jeq") { + text[cursor] = Script::CODE_JUMP_EQUAL; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); + } else if (cmd == "jne") { + text[cursor] = Script::CODE_JUMP_NOT_EQUAL; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); + } else if (cmd == "jl") { + text[cursor] = Script::CODE_JUMP_LESS; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); + } else if (cmd == "jle") { + text[cursor] = Script::CODE_JUMP_LESS_EQUAL; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); + } else if (cmd == "jg") { + text[cursor] = Script::CODE_JUMP_GREATER; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); + } else if (cmd == "jge") { + text[cursor] = Script::CODE_JUMP_GREATER_EQUAL; + ++cursor; + ++i; + if (!labels.count((*i)->Identifier())) { + throw Error("use of undefined label " + (*i)->Identifier()); + } + *reinterpret_cast(text + cursor) = labels[(*i)->Identifier()]; + cursor += sizeof(int); } else if (cmd == "sysc") { text[cursor] = Script::CODE_SYSCALL; ++cursor; -- 2.39.2