Explorar el Código

yeah added assembly stuff

nicolaswinkler hace 7 años
padre
commit
011b0748a8
Se han modificado 6 ficheros con 166 adiciones y 12 borrados
  1. 42 0
      src/AssemblyGenerator.cpp
  2. 47 0
      src/AssemblyGenerator.h
  3. 42 3
      src/Optimizer.cpp
  4. 14 4
      src/Optimizer.h
  5. 17 3
      src/main.cpp
  6. 4 2
      src/makefile

+ 42 - 0
src/AssemblyGenerator.cpp

@@ -0,0 +1,42 @@
+#include "AssemblyGenerator.h"
+
+using namespace zp;
+
+#include <iostream>
+
+void AssemblyGenerator::visitBlockInstruction(const BlockInstruction&)
+{
+}
+
+
+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);
+}

+ 47 - 0
src/AssemblyGenerator.h

@@ -0,0 +1,47 @@
+#ifndef ZP_ASSEMBLY_GENERATOR_H_
+#define ZP_ASSEMBLY_GENERATOR_H_
+
+#include "Optimizer.h"
+#include "asmjit/src/asmjit/x86.h"
+
+namespace zp
+{
+    class IRVisitor;
+
+    class AssemblyGenerator;
+}
+
+
+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
+{
+    asmjit::X86Assembler as;
+public:
+
+    inline AssemblyGenerator(asmjit::CodeHolder* ch) :
+        as{ ch } {}
+
+    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 */
+

+ 17 - 3
src/main.cpp

@@ -1,12 +1,17 @@
 #include <iostream>
 #include <string>
 #include <fstream>
+
 #include "Parser.h"
 #include "Optimizer.h"
+#include "AssemblyGenerator.h"
+
+#include "asmjit/src/asmjit/x86.h"
 
 using namespace std;
 using zp::Parser;
 using zp::Optimizer;
+using zp::AssemblyGenerator;
 
 
 int main(int argc, char** argv)
@@ -15,7 +20,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 +34,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 +46,18 @@ int main(int argc, char** argv)
     }
 
     Optimizer optimizer;
-    ast->accept(optimizer);
+    auto ir = ast->accept(optimizer);
     
+    using namespace asmjit;
+
+    JitRuntime rt;
+    CodeHolder ch;
+    ch.init(rt.getCodeInfo());
+
+    AssemblyGenerator ag{ &ch };
+    ir->accept(ag);
+
+
     if (filename != "") {
         dynamic_cast<ifstream*> (in)->close();
         delete in;

+ 4 - 2
src/makefile

@@ -1,15 +1,17 @@
 CXX         := g++
 CXXFLAGS    := -std=c++14 -Wall
+LNFLAGS     := -Lasmjit -lasmjit
 
 OBJECTS     := main.o Parser.o Optimizer.o
+OBJECTS     := $(patsubst %.cpp, %.o, $(wildcard *.cpp))
 EXECUTABLE  := zombie
 
 all: $(EXECUTABLE)
 
 $(EXECUTABLE): $(OBJECTS)
-	$(CXX) $(OBJECTS) -o $(EXECUTABLE)
+	$(CXX) $(OBJECTS) -o $(EXECUTABLE) $(LNFLAGS)
 
-%.o: %.c
+%.o: %.cpp
 		$(CXX) -c -o $@ $< $(CXXFLAGS)