Преглед изворни кода

Merge branch 'master' of https://gitlab.vis.ethz.ch/niwinkle/zombiefuck

Nicolas Winkler пре 7 година
родитељ
комит
d086b12263
6 измењених фајлова са 174 додато и 14 уклоњено
  1. 43 0
      src/AssemblyGenerator.cpp
  2. 62 0
      src/AssemblyGenerator.h
  3. 42 3
      src/Optimizer.cpp
  4. 14 4
      src/Optimizer.h
  5. 10 4
      src/main.cpp
  6. 3 3
      src/makefile

+ 43 - 0
src/AssemblyGenerator.cpp

@@ -0,0 +1,43 @@
+#include "AssemblyGenerator.h"
+
+using namespace zp;
+
+#include <iostream>
+
+void AssemblyGenerator::visitBlockInstruction(const BlockInstruction& bi)
+{
+    bi.
+}
+
+
+void AssemblyGenerator::visitUnionBlockInstruction(const UnionBlockInstruction& ubi)
+{
+    std::cout << "UnionBlockInstruction" << std::endl;
+    for (auto& a : ubi.content) {
+        a->accept(*this);
+    }
+}
+
+
+void AssemblyGenerator::visitIOInstruction(const IOInstruction&)
+{
+    std::cout << "IOInstruction" << std::endl;
+}
+
+
+void AssemblyGenerator::visitSimpleBlockInstruction(const SimpleBlockInstruction&)
+{
+
+}
+
+
+void AssemblyGenerator::visitLinearLoopInstruction(const LinearLoopInstruction&)
+{
+
+}
+
+
+void AssemblyGenerator::visitLoopInstruction(const LoopInstruction& li)
+{
+    visitUnionBlockInstruction(li);
+}

+ 62 - 0
src/AssemblyGenerator.h

@@ -0,0 +1,62 @@
+#ifndef ZP_ASSEMBLY_GENERATOR_H_
+#define ZP_ASSEMBLY_GENERATOR_H_
+
+#include "Optimizer.h"
+
+namespace zp
+{
+    class X64AssemblyHolder;
+
+    class IRVisitor;
+
+    class AssemblyGenerator;
+}
+
+
+class X64AssemblyHolder
+{
+public:
+    enum class Register {
+        RAX, RBX, RCX, RDX,
+        RSI, RDI, RBP, RSP,
+        R8, R9, R10, R11, R12, R13, R14, R15
+    };
+
+    void mov(Register src, Register target) = 0;
+    void mov(uint64_t imm, Register target) = 0;
+};
+
+
+class zp::IRVisitor
+{
+public:
+    virtual void visitBlockInstruction(const BlockInstruction&) = 0;
+    virtual void visitUnionBlockInstruction(const UnionBlockInstruction&) = 0;
+    virtual void visitIOInstruction(const IOInstruction&) = 0;
+    virtual void visitSimpleBlockInstruction(const SimpleBlockInstruction&) = 0;
+    virtual void visitLinearLoopInstruction(const LinearLoopInstruction&) = 0;
+    virtual void visitLoopInstruction(const LoopInstruction&) = 0;
+};
+
+
+class zp::AssemblyGenerator :
+    public IRVisitor
+{
+    X64AssemblyHolder& as;
+public:
+
+    inline AssemblyGenerator(X64AssemblyHolder& as) :
+        as{ as } {}
+
+    virtual void visitBlockInstruction(const BlockInstruction&);
+    virtual void visitUnionBlockInstruction(const UnionBlockInstruction&);
+    virtual void visitIOInstruction(const IOInstruction&);
+    virtual void visitSimpleBlockInstruction(const SimpleBlockInstruction&);
+    virtual void visitLinearLoopInstruction(const LinearLoopInstruction&);
+    virtual void visitLoopInstruction(const LoopInstruction&);
+};
+
+
+
+
+#endif // ZP_ASSEMBLY_GENERATOR_H_

+ 42 - 3
src/Optimizer.cpp

@@ -1,5 +1,6 @@
 #include "Optimizer.h"
 #include "Parser.h"
+#include "AssemblyGenerator.h"
 #include <iostream>
 #include <vector>
 
@@ -12,6 +13,36 @@ unique_ptr<BlockInstruction> AstVisitor::visit(Block& block)
 }
 
 
+void UnionBlockInstruction::accept(IRVisitor& v)
+{
+    v.visitUnionBlockInstruction(*this);
+}
+
+
+void IOInstruction::accept(IRVisitor& v)
+{
+    v.visitIOInstruction(*this);
+}
+
+
+void SimpleBlockInstruction::accept(IRVisitor& v)
+{
+    v.visitSimpleBlockInstruction(*this);
+}
+
+
+void LinearLoopInstruction::accept(IRVisitor& v)
+{
+    v.visitLinearLoopInstruction(*this);
+}
+
+
+void LoopInstruction::accept(IRVisitor& v)
+{
+    v.visitLoopInstruction(*this);
+}
+
+
 unique_ptr<BlockInstruction> Optimizer::visitInstructionBlock(InstructionBlock& ib)
 {
     std::cout << "InstructionBlock" << std::endl;
@@ -58,9 +89,17 @@ unique_ptr<BlockInstruction> Optimizer::visitUnionBlock(UnionBlock& ub)
 unique_ptr<BlockInstruction> Optimizer::visitLoop(Loop& loop)
 {
     auto ret = make_unique<LoopInstruction>();
-    ret->content.reserve(ub.instructions.size());
-    for (auto& block : ub.instructions) {
-        ret->content.push_back(visit(*block.get()));
+    ret->content.reserve(loop.instructions.size());
+    bool noSubLoops = true;
+    for (auto& block : loop.instructions) {
+        auto v = visit(*block.get());
+        if (!dynamic_cast<SimpleBlockInstruction*>(v.get())) {
+            noSubLoops = false;
+        }
+        ret->content.push_back(std::move(v));
+    }
+    if (noSubLoops) {
+        // TODO: apply linear loop optimizations
     }
     return ret;
 }

+ 14 - 4
src/Optimizer.h

@@ -29,6 +29,10 @@ namespace zp
 
     using Index = int;
     using Cell = unsigned char;
+
+
+    // forward declaration
+    class IRVisitor;
 }
 
 
@@ -51,6 +55,7 @@ public:
 struct zp::BlockInstruction
 {
     virtual ~BlockInstruction(void) = default;
+    virtual void accept(IRVisitor& v) = 0;
 };
 
 
@@ -58,15 +63,17 @@ struct zp::UnionBlockInstruction :
     public BlockInstruction
 {
     std::vector<std::unique_ptr<BlockInstruction>> content;
+    virtual void accept(IRVisitor& v);
 };
 
 
 struct zp::IOInstruction :
     public BlockInstruction
 {
-    /// true on , false on .
-    bool read;
-    inline BlockInstruction(bool read) : read{read} {}
+    /// true on "," (reads) false on "." (writes)
+    bool isRead;
+    inline IOInstruction(bool isRead) : isRead{isRead} {}
+    virtual void accept(IRVisitor& v);
 };
 
 
@@ -75,18 +82,21 @@ struct zp::SimpleBlockInstruction :
 {
     Index pointerMoved;
     std::unordered_map<Index, Cell> added;
+    virtual void accept(IRVisitor& v);
 };
 
 
 struct zp::LinearLoopInstruction :
     public BlockInstruction
 {
+    virtual void accept(IRVisitor& v);
 };
 
 
 struct zp::LoopInstruction :
     public UnionBlockInstruction
 {
+    virtual void accept(IRVisitor& v);
 };
 
 
@@ -98,8 +108,8 @@ public:
     std::unique_ptr<BlockInstruction> visitInstructionBlock(InstructionBlock& ib) override;
     std::unique_ptr<BlockInstruction> visitIOBlock(IOBlock& io) override;
     std::unique_ptr<BlockInstruction> visitUnionBlock(UnionBlock& ub) override;
-
 };
 
 
 #endif /* ZP_OPTIMIZER_H */
+

+ 10 - 4
src/main.cpp

@@ -1,12 +1,15 @@
 #include <iostream>
 #include <string>
 #include <fstream>
+
 #include "Parser.h"
 #include "Optimizer.h"
+#include "AssemblyGenerator.h"
 
 using namespace std;
 using zp::Parser;
 using zp::Optimizer;
+using zp::AssemblyGenerator;
 
 
 int main(int argc, char** argv)
@@ -15,7 +18,6 @@ int main(int argc, char** argv)
     for (int i = 1; i < argc; i++) {
         string arg = argv[i];
         if (arg == "") {
-
         }
         else if (arg[0] == '-') {
         }
@@ -30,7 +32,7 @@ int main(int argc, char** argv)
         in = new ifstream{filename.c_str(), fstream::in};
     }
 
-    Parser parser{*in};
+    Parser parser{ *in };
     unique_ptr<zp::Block> ast;
 
     try {
@@ -42,8 +44,12 @@ int main(int argc, char** argv)
     }
 
     Optimizer optimizer;
-    ast->accept(optimizer);
-    
+    auto ir = ast->accept(optimizer);
+
+    AssemblyGenerator ag{};
+    ir->accept(ag);
+
+
     if (filename != "") {
         dynamic_cast<ifstream*> (in)->close();
         delete in;

+ 3 - 3
src/makefile

@@ -1,6 +1,6 @@
 CXX         := g++
 CXXFLAGS    := -std=c++14 -Wall
-
+LNFLAGS     := -Lasmjit -lasmjit
 SOURCES     := $(wildcard *.cpp)
 OBJECTS     := $(patsubst %.cpp, %.o, $(SOURCES))
 EXECUTABLE  := zombie
@@ -8,9 +8,9 @@ EXECUTABLE  := zombie
 all: $(EXECUTABLE)
 
 $(EXECUTABLE): $(OBJECTS)
-	$(CXX) $(OBJECTS) -o $(EXECUTABLE)
+	$(CXX) $(OBJECTS) -o $(EXECUTABLE) $(LNFLAGS)
 
-%.o: %.c
+%.o: %.cpp
 		$(CXX) -c -o $@ $< $(CXXFLAGS)