Get preinc working again.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
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)
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.
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/.
20 #include "BytecodeEmitter.h"
21 #include "../Heap-inl.h"
22 #include "../Handles-inl.h"
26 class HIRTranslator : public HIRVisitor
29 HIRTranslator(Zone *zone, BytecodeEmitter &emitter)
35 void translate(HIR *hir) {
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 void visitIndex(HIndex *index);
51 BytecodeEmitter &emitter_;
57 HIRTranslator::visitFloat(HFloat *hir)
59 __ float_(hir->value());
63 HIRTranslator::visitInteger(HInteger *hir)
65 __ int_(hir->value());
69 HIRTranslator::visitCall(HCall *call)
71 Local<FunctionType> fun(zone_, FunctionType::cast(call->callee()->type()));
73 assert(call->args()->length() == fun->parameters()->length());
75 unsigned argc = call->args()->length();
77 for (size_t i = call->args()->length() - 1; i < call->args()->length(); i--) {
78 HIR *hir = call->args()->at(i);
82 call->callee()->accept(this);
87 HGlobal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
92 HGlobal::hold(BytecodeEmitter &emitter_)
97 HGlobal::store(BytecodeEmitter &emitter_)
103 HGlobal::load(BytecodeEmitter &emitter_)
109 HLocal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
111 if (sym_->type()->isReference())
116 HLocal::hold(BytecodeEmitter &emitter_)
118 if (sym_->type()->isReference())
123 HLocal::store(BytecodeEmitter &emitter_)
125 if (sym_->type()->isReference())
126 __ setref(sym_->type()->contained_ref());
132 HLocal::load(BytecodeEmitter &emitter_)
134 if (sym_->type()->isReference())
135 __ getref(sym_->type());
141 HIndex::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
143 left_->accept(visitor);
144 right_->accept(visitor);
148 HIndex::hold(BytecodeEmitter &emitter_)
154 HIndex::store(BytecodeEmitter &emitter_)
160 HIndex::load(BytecodeEmitter &emitter_)
166 HIRTranslator::visitLocal(HLocal *local)
168 local->bind(this, emitter_);
169 local->load(emitter_);
173 HIRTranslator::visitIndex(HIndex *index)
175 index->bind(this, emitter_);
176 index->load(emitter_);
180 HIRTranslator::visitGlobal(HGlobal *global)
182 __ getglobal(global->sym());
186 TokenToOpcode(TokenKind kind)
210 case TOK_ASSIGN_USHR:
216 case TOK_ASSIGN_BITAND:
219 case TOK_ASSIGN_BITOR:
234 assert(kind == TOK_BITXOR);
240 HIRTranslator::visitStore(HStore *store)
242 store->lval()->bind(this, emitter_);
243 if (store->kind() == TOK_ASSIGN) {
244 store->rval()->accept(this);
246 // Advanced case: dup the ref, load, op, store.
247 store->lval()->hold(emitter_);
248 store->lval()->load(emitter_);
249 store->rval()->accept(this);
250 __ binary(TokenToOpcode(store->kind()));
252 store->lval()->store(emitter_);
256 HIRTranslator::visitBinary(HBinary *binary)
258 binary->left()->accept(this);
259 binary->right()->accept(this);
261 // We define three sets of math operators:
263 // (1) ADD, SUB, MUL, DIV, MOD, which take two equal types and produce
265 // (2) LT, LE, GE, GT, EQ, NE, which take two equal types and produce
267 // (3) SHL, SR, USHR, BITAND, BITOR, BITXOR, BITNOT, which take two
268 // equal integer types and return that integer type.
270 Opcode op = TokenToOpcode(binary->token());
272 if (op >= OP_ADD && op <= OP_NE) {
273 if (binary->type()->isFloat())
274 op = Opcode(int(op) + int(OP_ADD_F - OP_ADD));
276 assert(binary->type()->isInt32());
283 HIRTranslator::visitConvert(HConvert *convert)
285 convert->in()->accept(this);
286 __ unary(convert->opcode());
290 ke::EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir)
292 HIRTranslator translator(zone, emitter);
293 translator.translate(hir);