src/compiler/HIR.cpp
author David Anderson <dvander@alliedmods.net>
Sat Nov 17 19:07:49 2012 -0800 (2012-11-17)
changeset 196 9904633b1dfc
parent 195 c1ba166f3fc4
child 209 5cbec15fadfe
permissions -rw-r--r--
Fix Linux build problems.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "HIR.h"
    20 #include "BytecodeEmitter.h"
    21 #include "../Heap-inl.h"
    22 #include "../Handles-inl.h"
    23 
    24 using namespace ke;
    25 
    26 class HIRTranslator : public HIRVisitor
    27 {
    28   public:
    29     HIRTranslator(Zone *zone, BytecodeEmitter &emitter)
    30       : zone_(zone),
    31         emitter_(emitter)
    32     {
    33     }
    34 
    35     void translate(HIR *hir) {
    36         hir->accept(this);
    37     }
    38 
    39     void visitFloat(HFloat *hir);
    40     void visitInteger(HInteger *hir);
    41     void visitCall(HCall *call);
    42     void visitStore(HStore *store);
    43     void visitBinary(HBinary *binary);
    44     void visitLocal(HLocal *local);
    45     void visitGlobal(HGlobal *global);
    46     void visitConvert(HConvert *convert);
    47 
    48   private:
    49     Zone *zone_;
    50     BytecodeEmitter &emitter_;
    51 };
    52 
    53 #define __ emitter_.
    54 
    55 void
    56 HIRTranslator::visitFloat(HFloat *hir)
    57 {
    58     __ float_(hir->value());
    59 }
    60 
    61 void
    62 HIRTranslator::visitInteger(HInteger *hir)
    63 {
    64     __ int_(hir->value());
    65 }
    66 
    67 void
    68 HIRTranslator::visitCall(HCall *call)
    69 {
    70     Local<FunctionType> fun(zone_, FunctionType::cast(call->callee()->type()));
    71     
    72     assert(call->args()->length() == fun->parameters()->length());
    73 
    74     unsigned argc = call->args()->length();
    75 
    76     for (size_t i = call->args()->length() - 1; i < call->args()->length(); i--) {
    77         HIR *hir = call->args()->at(i);
    78         hir->accept(this);
    79     }
    80 
    81     call->callee()->accept(this);
    82     __ call(fun, argc);
    83 }
    84 
    85 void
    86 HGlobal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
    87 {
    88 }
    89 
    90 void
    91 HGlobal::store(BytecodeEmitter &emitter_)
    92 {
    93     __ setglobal(sym_);
    94 }
    95 
    96 void
    97 HGlobal::load(BytecodeEmitter &emitter_)
    98 {
    99     __ getglobal(sym_);
   100 }
   101 
   102 void
   103 HLocal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
   104 {
   105     if (sym_->type()->isReference())
   106         __ getlocal(sym_);
   107 }
   108 
   109 void
   110 HLocal::store(BytecodeEmitter &emitter_)
   111 {
   112     if (sym_->type()->isReference())
   113         __ setref(sym_->type()->contained());
   114     else
   115         __ setlocal(sym_);
   116 }
   117 
   118 void
   119 HLocal::load(BytecodeEmitter &emitter_)
   120 {
   121     if (sym_->type()->isReference())
   122         __ getref(sym_->type());
   123     else
   124         __ getlocal(sym_);
   125 }
   126 
   127 void
   128 HIndex::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
   129 {
   130     left_->accept(visitor);
   131     right_->accept(visitor);
   132 }
   133 
   134 void
   135 HIndex::store(BytecodeEmitter &emitter_)
   136 {
   137     __ setelem(type());
   138 }
   139 
   140 void
   141 HIndex::load(BytecodeEmitter &emitter_)
   142 {
   143     __ getelem(type());
   144 }
   145 
   146 void
   147 HIRTranslator::visitLocal(HLocal *local)
   148 {
   149     local->bind(this, emitter_);
   150     local->load(emitter_);
   151 }
   152 
   153 void
   154 HIRTranslator::visitGlobal(HGlobal *global)
   155 {
   156     __ getglobal(global->sym());
   157 }
   158 
   159 void
   160 HIRTranslator::visitStore(HStore *store)
   161 {
   162     store->lval()->bind(this, emitter_);
   163     store->rval()->accept(this);
   164     store->lval()->store(emitter_);
   165 }
   166 
   167 static inline Opcode
   168 TokenToOpcode(TokenKind kind)
   169 {
   170     switch (kind) {
   171       case TOK_PLUS:
   172         return OP_ADD;
   173       case TOK_MINUS:
   174         return OP_SUB;
   175       case TOK_STAR:
   176         return OP_MUL;
   177       case TOK_SLASH:
   178         return OP_DIV;
   179       case TOK_PERCENT:
   180         return OP_MOD;
   181       case TOK_SHR:
   182         return OP_SHR;
   183       case TOK_USHR:
   184         return OP_USHR;
   185       case TOK_SHL:
   186         return OP_SHL;
   187       case TOK_BITAND:
   188         return OP_BITAND;
   189       case TOK_BITOR:
   190         return OP_BITOR;
   191       case TOK_GT:
   192           return OP_GT;
   193       case TOK_GE:
   194           return OP_GE;
   195       case TOK_LT:
   196           return OP_LT;
   197       case TOK_LE:
   198           return OP_LE;
   199       case TOK_EQUALS:
   200           return OP_EQ;
   201       case TOK_NOTEQUALS:
   202           return OP_NE;
   203       default:
   204         assert(kind == TOK_BITXOR);
   205         return OP_BITXOR;
   206     }
   207 }
   208 
   209 void
   210 HIRTranslator::visitBinary(HBinary *binary)
   211 {
   212     binary->left()->accept(this);
   213     binary->right()->accept(this);
   214 
   215     // We define three sets of math operators:
   216     //
   217     //  (1) ADD, SUB, MUL, DIV, MOD, which take two equal types and produce
   218     //      the same type.
   219     //  (2) LT, LE, GE, GT, EQ, NE, which take two equal types and produce
   220     //      a boolean.
   221     //  (3) SHL, SR, USHR, BITAND, BITOR, BITXOR, BITNOT, which take two
   222     //      equal integer types and return that integer type.
   223     //
   224     Opcode op = TokenToOpcode(binary->token());
   225 
   226     if (op >= OP_ADD && op <= OP_NE) {
   227         if (binary->type()->isFloat())
   228             op = Opcode(int(op) + int(OP_ADD_F - OP_ADD));
   229     } else {
   230         assert(binary->type()->isInt32());
   231     }
   232 
   233     __ binary(op);
   234 }
   235 
   236 void
   237 HIRTranslator::visitConvert(HConvert *convert)
   238 {
   239     convert->in()->accept(this);
   240     __ unary(convert->opcode());
   241 }
   242 
   243 void
   244 ke::EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir)
   245 {
   246     HIRTranslator translator(zone, emitter);
   247     translator.translate(hir);
   248 }