jitcraft/Opcodes.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jun 25 02:57:28 2012 -0700 (2012-06-25)
changeset 0 c455ebb9a5dc
child 1 27f12e2fc369
permissions -rw-r--r--
Initial import of prototype.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #include "Opcodes.h"
    19 #include "Utility.h"
    20 #include "Code.h"
    21 
    22 using namespace jc;
    23 
    24 OpInfo jc::OpcodeInfo[] =
    25 {
    26 #define OPDEF(name, number, text, length, uses, defs) \
    27     {text, length, uses, defs},
    28 #include "Opcodes.tbl"
    29 #undef OPDEF
    30 };
    31 
    32 // All jumps must be the same length.
    33 STATIC_ASSERT(OP_JL_LENGTH == OP_JUMP_LENGTH);
    34 STATIC_ASSERT(OP_JLE_LENGTH == OP_JUMP_LENGTH);
    35 STATIC_ASSERT(OP_JG_LENGTH == OP_JUMP_LENGTH);
    36 STATIC_ASSERT(OP_JGE_LENGTH == OP_JUMP_LENGTH);
    37 STATIC_ASSERT(OP_JEQ_LENGTH == OP_JUMP_LENGTH);
    38 STATIC_ASSERT(OP_JNE_LENGTH == OP_JUMP_LENGTH);
    39 STATIC_ASSERT(OP_JT_LENGTH == OP_JUMP_LENGTH);
    40 STATIC_ASSERT(OP_JF_LENGTH == OP_JUMP_LENGTH);
    41 
    42 void
    43 jc::Disassemble(Code *code, FILE *fp)
    44 {
    45     bytecode *pc = code->start();
    46     for (;;) {
    47         Opcode op = Opcode(*pc);
    48 
    49         fprintf(fp, "%-4d %s ", int(pc - code->start()), OpcodeInfo[op].name);
    50 
    51         switch (op) {
    52           case OP_NOP:
    53           case OP_RETURN:
    54           case OP_ADD:
    55           case OP_SUB:
    56           case OP_MUL:
    57           case OP_DIV:
    58           case OP_POP:
    59           case OP_LD_STA_I:
    60           case OP_LD_STA_P:
    61           case OP_ST_STA_I:
    62           case OP_BOUNDS_STA:
    63             break;
    64 
    65           case OP_STOP:
    66             fprintf(fp, "\n");
    67             return;
    68 
    69           case OP_INT:
    70             fprintf(fp, "%d", READ_INT32(pc));
    71             break;
    72 
    73           case OP_JL:
    74           case OP_JLE:
    75           case OP_JG:
    76           case OP_JGE:
    77           case OP_JEQ:
    78           case OP_JNE:
    79           case OP_JT:
    80           case OP_JF:
    81           case OP_JUMP:
    82             fprintf(fp, "%d (%u)", READ_INT32(pc), unsigned((pc + READ_INT32(pc)) - code->start()));
    83             break;
    84 
    85           case OP_STACKARRAY:
    86           {
    87             unsigned width = pc[1];
    88             unsigned dims = pc[2];
    89 
    90             for (unsigned i = 0; i < dims; i++)
    91                 fprintf(fp, "[%u]", READ_UINT32(pc + 2 + (i * sizeof(unsigned))));
    92             fprintf(fp, " ; (width = %s)\n", (width == 1 ? "char" : "cell"));
    93             pc += 3 + dims * sizeof(unsigned);
    94             continue;
    95           }
    96 
    97           case OP_GETLOCAL:
    98           case OP_SETLOCAL:
    99           case OP_GETARG:
   100           case OP_SETARG:
   101             fprintf(fp, "%u", READ_UINT32(pc));
   102             break;
   103 
   104           case OP_CALLGLOBAL:
   105             fprintf(fp, "%u", READ_UINT32(pc));
   106             break;
   107 
   108           default:
   109             // Unknown opcode!
   110             assert(false);
   111             return;
   112         }
   113 
   114         fprintf(fp, "\n");
   115         pc += OpcodeInfo[op].length;
   116     }
   117 }