2000-04-18 04:19:09 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is the JavaScript 2 Prototype.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the
|
|
|
|
* terms of the GNU Public License (the "GPL"), in which case the
|
|
|
|
* provisions of the GPL are applicable instead of those above.
|
|
|
|
* If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of the GPL and not to allow others to use your
|
|
|
|
* version of this file under the NPL, indicate your decision by
|
|
|
|
* deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this
|
|
|
|
* file under either the NPL or the GPL.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef vmtypes_h
|
|
|
|
#define vmtypes_h
|
|
|
|
|
|
|
|
#include "numerics.h" /* needed for formatter << double */
|
2000-04-28 09:41:54 +04:00
|
|
|
#include "jstypes.h"
|
2000-06-27 06:39:32 +04:00
|
|
|
#include "jsclasses.h"
|
2000-05-06 07:47:13 +04:00
|
|
|
#include "world.h"
|
|
|
|
#include <vector>
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-06-15 03:26:15 +04:00
|
|
|
/* forward declare classes from JavaScript::ICG */
|
|
|
|
namespace JavaScript {
|
|
|
|
namespace ICG {
|
|
|
|
class ICodeModule;
|
|
|
|
} /* namespace ICG */
|
|
|
|
} /* namespace JavaScript */
|
|
|
|
|
2000-04-18 04:19:09 +04:00
|
|
|
namespace JavaScript {
|
2000-04-19 01:51:45 +04:00
|
|
|
namespace VM {
|
2000-04-28 09:41:54 +04:00
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
using namespace JSTypes;
|
2000-06-27 06:39:32 +04:00
|
|
|
using namespace JSClasses;
|
2000-04-28 09:41:54 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
enum ICodeOp {
|
|
|
|
ADD, /* dest, source1, source2 */
|
2000-05-06 01:38:16 +04:00
|
|
|
AND, /* dest, source1, source2 */
|
|
|
|
BITNOT, /* dest, source */
|
2000-04-19 01:51:45 +04:00
|
|
|
BRANCH, /* target label */
|
2000-05-18 04:03:23 +04:00
|
|
|
BRANCH_FALSE, /* target label, condition */
|
|
|
|
BRANCH_TRUE, /* target label, condition */
|
2000-06-22 02:32:21 +04:00
|
|
|
CALL, /* result, target, name, args */
|
2000-05-27 02:33:05 +04:00
|
|
|
COMPARE_EQ, /* dest, source1, source2 */
|
|
|
|
COMPARE_GE, /* dest, source1, source2 */
|
|
|
|
COMPARE_GT, /* dest, source1, source2 */
|
|
|
|
COMPARE_IN, /* dest, source1, source2 */
|
|
|
|
COMPARE_LE, /* dest, source1, source2 */
|
|
|
|
COMPARE_LT, /* dest, source1, source2 */
|
|
|
|
COMPARE_NE, /* dest, source1, source2 */
|
2000-06-24 02:27:17 +04:00
|
|
|
DEBUGGER, /* drop to the debugger */
|
2000-04-19 01:51:45 +04:00
|
|
|
DIVIDE, /* dest, source1, source2 */
|
2000-05-18 04:03:23 +04:00
|
|
|
ELEM_XCR, /* dest, base, index, value */
|
|
|
|
GET_ELEMENT, /* dest, base, index */
|
2000-04-19 01:51:45 +04:00
|
|
|
GET_PROP, /* dest, object, prop name */
|
2000-06-24 03:43:24 +04:00
|
|
|
GET_SLOT, /* dest, object, slot number */
|
2000-06-27 06:39:32 +04:00
|
|
|
GET_STATIC, /* dest, class, name */
|
2000-05-27 02:33:05 +04:00
|
|
|
INSTANCEOF, /* dest, source1, source2 */
|
2000-04-27 05:27:09 +04:00
|
|
|
JSR, /* target */
|
2000-06-21 02:45:45 +04:00
|
|
|
LOAD_BOOLEAN, /* dest, immediate value (boolean) */
|
2000-04-19 01:51:45 +04:00
|
|
|
LOAD_IMMEDIATE, /* dest, immediate value (double) */
|
|
|
|
LOAD_NAME, /* dest, name */
|
2000-05-06 03:22:31 +04:00
|
|
|
LOAD_STRING, /* dest, immediate value (string) */
|
2000-06-22 02:32:21 +04:00
|
|
|
METHOD_CALL, /* result, target base, target value, args */
|
2000-04-19 01:51:45 +04:00
|
|
|
MOVE, /* dest, source */
|
|
|
|
MULTIPLY, /* dest, source1, source2 */
|
2000-05-11 04:35:06 +04:00
|
|
|
NAME_XCR, /* dest, name, value */
|
2000-05-06 01:38:16 +04:00
|
|
|
NEGATE, /* dest, source */
|
2000-04-19 01:51:45 +04:00
|
|
|
NEW_ARRAY, /* dest */
|
2000-06-24 03:49:17 +04:00
|
|
|
NEW_CLASS, /* dest, class name */
|
2000-06-22 02:32:21 +04:00
|
|
|
NEW_FUNCTION, /* dest, ICodeModule */
|
2000-04-19 01:51:45 +04:00
|
|
|
NEW_OBJECT, /* dest */
|
|
|
|
NOP, /* do nothing and like it */
|
|
|
|
NOT, /* dest, source */
|
2000-05-06 01:38:16 +04:00
|
|
|
OR, /* dest, source1, source2 */
|
|
|
|
POSATE, /* dest, source */
|
2000-05-11 04:35:06 +04:00
|
|
|
PROP_XCR, /* dest, source, name, value */
|
2000-05-06 01:38:16 +04:00
|
|
|
REMAINDER, /* dest, source1, source2 */
|
2000-04-21 04:04:14 +04:00
|
|
|
RETURN, /* return value */
|
|
|
|
RETURN_VOID, /* Return without a value */
|
2000-04-27 05:27:09 +04:00
|
|
|
RTS, /* Return to sender */
|
2000-04-19 01:51:45 +04:00
|
|
|
SAVE_NAME, /* name, source */
|
2000-05-18 04:03:23 +04:00
|
|
|
SET_ELEMENT, /* base, index, value */
|
2000-04-19 01:51:45 +04:00
|
|
|
SET_PROP, /* object, name, source */
|
2000-06-24 03:43:24 +04:00
|
|
|
SET_SLOT, /* object, slot number, source */
|
2000-06-27 06:39:32 +04:00
|
|
|
SET_STATIC, /* class, name, source */
|
2000-05-06 01:38:16 +04:00
|
|
|
SHIFTLEFT, /* dest, source1, source2 */
|
|
|
|
SHIFTRIGHT, /* dest, source1, source2 */
|
2000-06-24 03:43:24 +04:00
|
|
|
SLOT_XCR, /* dest, source, slot number, value */
|
2000-06-28 22:41:30 +04:00
|
|
|
STATIC_CALL, /* result, target class, name, args */
|
2000-06-27 06:39:32 +04:00
|
|
|
STATIC_XCR, /* dest, class, name, value */
|
2000-05-27 02:33:05 +04:00
|
|
|
STRICT_EQ, /* dest, source1, source2 */
|
|
|
|
STRICT_NE, /* dest, source1, source2 */
|
2000-04-21 04:04:14 +04:00
|
|
|
SUBTRACT, /* dest, source1, source2 */
|
2000-05-18 04:03:23 +04:00
|
|
|
TEST, /* dest, source */
|
2000-04-27 05:27:09 +04:00
|
|
|
THROW, /* exception value */
|
2000-05-06 01:38:16 +04:00
|
|
|
TRYIN, /* catch target, finally target */
|
|
|
|
TRYOUT, /* mmm, there is no try, only do */
|
|
|
|
USHIFTRIGHT, /* dest, source1, source2 */
|
2000-05-11 04:35:06 +04:00
|
|
|
VAR_XCR, /* dest, source, value */
|
2000-04-29 18:10:53 +04:00
|
|
|
WITHIN, /* within this object */
|
2000-05-06 01:38:16 +04:00
|
|
|
WITHOUT, /* without this object */
|
2000-05-11 04:35:06 +04:00
|
|
|
XOR, /* dest, source1, source2 */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
2000-05-06 01:38:16 +04:00
|
|
|
|
2000-06-27 06:39:32 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/********************************************************************/
|
2000-05-11 04:35:06 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
static char *opcodeNames[] = {
|
|
|
|
"ADD ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"AND ",
|
|
|
|
"BITNOT ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"BRANCH ",
|
2000-05-18 04:03:23 +04:00
|
|
|
"BRANCH_FALSE ",
|
|
|
|
"BRANCH_TRUE ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"CALL ",
|
|
|
|
"COMPARE_EQ ",
|
|
|
|
"COMPARE_GE ",
|
|
|
|
"COMPARE_GT ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"COMPARE_IN ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"COMPARE_LE ",
|
|
|
|
"COMPARE_LT ",
|
|
|
|
"COMPARE_NE ",
|
2000-06-24 02:27:17 +04:00
|
|
|
"DEBUGGER ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"DIVIDE ",
|
2000-05-18 04:03:23 +04:00
|
|
|
"ELEM_XCR ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"GET_ELEMENT ",
|
|
|
|
"GET_PROP ",
|
2000-06-24 03:43:24 +04:00
|
|
|
"GET_SLOT ",
|
2000-06-27 06:39:32 +04:00
|
|
|
"GET_STATIC ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"INSTANCEOF ",
|
2000-04-27 05:27:09 +04:00
|
|
|
"JSR ",
|
2000-06-21 02:45:45 +04:00
|
|
|
"LOAD_BOOLEAN ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"LOAD_IMMEDIATE",
|
|
|
|
"LOAD_NAME ",
|
2000-05-06 03:22:31 +04:00
|
|
|
"LOAD_STRING ",
|
2000-06-22 02:32:21 +04:00
|
|
|
"METHOD_CALL ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"MOVE ",
|
|
|
|
"MULTIPLY ",
|
2000-05-11 04:35:06 +04:00
|
|
|
"NAME_XCR ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"NEGATE ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"NEW_ARRAY ",
|
2000-06-24 03:49:17 +04:00
|
|
|
"NEW_CLASS ",
|
2000-06-22 02:32:21 +04:00
|
|
|
"NEW_FUNCTION ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"NEW_OBJECT ",
|
|
|
|
"NOP ",
|
|
|
|
"NOT ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"OR ",
|
|
|
|
"POSATE ",
|
2000-05-11 04:35:06 +04:00
|
|
|
"PROP_XCR ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"REMAINDER ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"RETURN ",
|
2000-04-21 04:04:14 +04:00
|
|
|
"RETURN_VOID ",
|
2000-04-27 05:27:09 +04:00
|
|
|
"RTS ",
|
2000-04-19 01:51:45 +04:00
|
|
|
"SAVE_NAME ",
|
|
|
|
"SET_ELEMENT ",
|
|
|
|
"SET_PROP ",
|
2000-06-24 03:43:24 +04:00
|
|
|
"SET_SLOT ",
|
2000-06-27 06:39:32 +04:00
|
|
|
"SET_STATIC ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"SHIFTLEFT ",
|
|
|
|
"SHIFTRIGHT ",
|
2000-06-24 03:43:24 +04:00
|
|
|
"SLOT_XCR ",
|
2000-06-28 22:41:30 +04:00
|
|
|
"STATIC_CALL ",
|
2000-06-27 06:39:32 +04:00
|
|
|
"STATIC_XCR ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"STRICT_EQ ",
|
|
|
|
"STRICT_NE ",
|
2000-04-21 04:04:14 +04:00
|
|
|
"SUBTRACT ",
|
2000-05-18 04:03:23 +04:00
|
|
|
"TEST ",
|
2000-04-22 02:52:52 +04:00
|
|
|
"THROW ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"TRYIN ",
|
|
|
|
"TRYOUT ",
|
|
|
|
"USHIFTRIGHT ",
|
2000-05-11 04:35:06 +04:00
|
|
|
"VAR_XCR ",
|
2000-04-29 18:10:53 +04:00
|
|
|
"WITHIN ",
|
|
|
|
"WITHOUT ",
|
2000-05-06 01:38:16 +04:00
|
|
|
"XOR ",
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-05-11 04:35:06 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/********************************************************************/
|
2000-05-11 04:35:06 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
/* super-class for all instructions */
|
|
|
|
class Instruction
|
|
|
|
{
|
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
Instruction(ICodeOp aOpcode) : mOpcode(aOpcode) { }
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f)
|
|
|
|
{
|
2000-04-21 04:04:14 +04:00
|
|
|
f << opcodeNames[mOpcode] << "\t<unk>";
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
2000-04-28 09:41:54 +04:00
|
|
|
}
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/)
|
2000-04-28 09:41:54 +04:00
|
|
|
{
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2000-04-21 04:04:14 +04:00
|
|
|
ICodeOp op() { return mOpcode; }
|
2000-04-19 01:51:45 +04:00
|
|
|
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual int32 count() { return 0; }
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
protected:
|
2000-04-21 04:04:14 +04:00
|
|
|
ICodeOp mOpcode;
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
};
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/********************************************************************/
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
enum { NotARegister = 0xFFFFFFFF };
|
|
|
|
enum { NotALabel = 0xFFFFFFFF };
|
|
|
|
enum { NotAnOffset = 0xFFFFFFFF };
|
2000-04-27 05:27:09 +04:00
|
|
|
enum { NotABanana = 0xFFFFFFFF };
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
/********************************************************************/
|
|
|
|
|
|
|
|
typedef uint32 Register;
|
2000-06-24 03:43:24 +04:00
|
|
|
typedef std::pair<Register, JSType*> TypedRegister;
|
2000-06-21 02:45:45 +04:00
|
|
|
typedef std::vector<TypedRegister> RegisterList;
|
2000-04-19 01:51:45 +04:00
|
|
|
typedef std::vector<Instruction *> InstructionStream;
|
|
|
|
typedef InstructionStream::iterator InstructionIterator;
|
2000-06-21 02:45:45 +04:00
|
|
|
typedef std::map<String, TypedRegister, std::less<String> > VariableMap;
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
|
2000-04-28 17:20:26 +04:00
|
|
|
/**
|
|
|
|
* Helper to print Call operands.
|
|
|
|
*/
|
|
|
|
struct ArgList {
|
|
|
|
const RegisterList& mList;
|
|
|
|
const JSValues& mRegisters;
|
|
|
|
ArgList(const RegisterList& rl, const JSValues& registers)
|
|
|
|
: mList(rl), mRegisters(registers) {}
|
|
|
|
};
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/********************************************************************/
|
|
|
|
|
|
|
|
Formatter& operator<< (Formatter& f, Instruction& i);
|
|
|
|
Formatter& operator<< (Formatter& f, RegisterList& rl);
|
2000-04-28 17:25:57 +04:00
|
|
|
Formatter& operator<< (Formatter& f, const ArgList& al);
|
2000-05-05 02:42:49 +04:00
|
|
|
Formatter& operator<< (Formatter& f, InstructionStream& is);
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
/********************************************************************/
|
|
|
|
|
|
|
|
class Label {
|
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
Label(InstructionStream* aBase) :
|
|
|
|
mBase(aBase), mOffset(NotALabel) {}
|
2000-04-19 01:51:45 +04:00
|
|
|
|
2000-04-21 04:04:14 +04:00
|
|
|
InstructionStream *mBase;
|
|
|
|
uint32 mOffset;
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<Label *> LabelList;
|
|
|
|
typedef LabelList::iterator LabelIterator;
|
2000-04-29 04:23:06 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/********************************************************************/
|
2000-04-29 04:23:06 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/* 1, 2 and 3 operand opcode templates */
|
|
|
|
|
|
|
|
template <typename Operand1>
|
|
|
|
class Instruction_1 : public Instruction {
|
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
Instruction_1(ICodeOp aOpcode, Operand1 aOp1) :
|
|
|
|
Instruction(aOpcode), mOp1(aOp1) { }
|
|
|
|
Operand1& o1() { return mOp1; }
|
2000-04-28 09:41:54 +04:00
|
|
|
|
|
|
|
virtual int32 count() { return 1; }
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
protected:
|
2000-04-21 04:04:14 +04:00
|
|
|
Operand1 mOp1;
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Operand1, typename Operand2>
|
|
|
|
class Instruction_2 : public Instruction {
|
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
Instruction_2(ICodeOp aOpcode, Operand1 aOp1, Operand2 aOp2) :
|
|
|
|
Instruction(aOpcode), mOp1(aOp1), mOp2(aOp2) {}
|
|
|
|
Operand1& o1() { return mOp1; }
|
|
|
|
Operand2& o2() { return mOp2; }
|
2000-04-28 09:41:54 +04:00
|
|
|
|
|
|
|
virtual int32 count() { return 2; }
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
protected:
|
2000-04-21 04:04:14 +04:00
|
|
|
Operand1 mOp1;
|
|
|
|
Operand2 mOp2;
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Operand1, typename Operand2, typename Operand3>
|
|
|
|
class Instruction_3 : public Instruction {
|
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
Instruction_3(ICodeOp aOpcode, Operand1 aOp1, Operand2 aOp2,
|
|
|
|
Operand3 aOp3) :
|
|
|
|
Instruction(aOpcode), mOp1(aOp1), mOp2(aOp2), mOp3(aOp3) { }
|
|
|
|
Operand1& o1() { return mOp1; }
|
|
|
|
Operand2& o2() { return mOp2; }
|
|
|
|
Operand3& o3() { return mOp3; }
|
2000-04-28 09:41:54 +04:00
|
|
|
|
|
|
|
virtual int32 count() { return 3; }
|
2000-04-19 01:51:45 +04:00
|
|
|
|
|
|
|
protected:
|
2000-04-21 04:04:14 +04:00
|
|
|
Operand1 mOp1;
|
|
|
|
Operand2 mOp2;
|
|
|
|
Operand3 mOp3;
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-05-11 04:35:06 +04:00
|
|
|
template <typename Operand1, typename Operand2, typename Operand3, typename Operand4>
|
|
|
|
class Instruction_4 : public Instruction {
|
|
|
|
public:
|
|
|
|
Instruction_4(ICodeOp aOpcode, Operand1 aOp1, Operand2 aOp2,
|
|
|
|
Operand3 aOp3, Operand4 aOp4) :
|
|
|
|
Instruction(aOpcode), mOp1(aOp1), mOp2(aOp2), mOp3(aOp3), mOp4(aOp4) { }
|
|
|
|
Operand1& o1() { return mOp1; }
|
|
|
|
Operand2& o2() { return mOp2; }
|
|
|
|
Operand3& o3() { return mOp3; }
|
|
|
|
Operand4& o4() { return mOp4; }
|
|
|
|
|
|
|
|
virtual int32 count() { return 4; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Operand1 mOp1;
|
|
|
|
Operand2 mOp2;
|
|
|
|
Operand3 mOp3;
|
|
|
|
Operand4 mOp4;
|
|
|
|
};
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/********************************************************************/
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
/* Instruction groups */
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Arithmetic : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-06-21 02:45:45 +04:00
|
|
|
Arithmetic (ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc1,
|
|
|
|
TypedRegister aSrc2) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>(aOpcode, aDest, aSrc1, aSrc2) {}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f)
|
|
|
|
{
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first << ", R" << mOp3.first;
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
|
|
|
|
{
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Unary : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-06-21 02:45:45 +04:00
|
|
|
Unary(ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>(aOpcode, aDest, aSrc) {}
|
2000-04-19 01:51:45 +04:00
|
|
|
virtual Formatter& print (Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
|
|
|
|
{
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class GenericBranch : public Instruction_2<Label*, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
GenericBranch (ICodeOp aOpcode, Label* aLabel,
|
2000-06-21 02:45:45 +04:00
|
|
|
TypedRegister aR = TypedRegister(NotARegister, &Any_Type) ) :
|
|
|
|
Instruction_2<Label*, TypedRegister>(aOpcode, aLabel, aR) {}
|
2000-04-19 01:51:45 +04:00
|
|
|
virtual Formatter& print (Formatter& f) {
|
2000-04-25 00:08:16 +04:00
|
|
|
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset;
|
2000-06-21 02:45:45 +04:00
|
|
|
if (mOp2.first == NotARegister) {
|
2000-04-25 00:08:16 +04:00
|
|
|
f << ", R~";
|
|
|
|
} else {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << ", R" << mOp2.first;
|
2000-04-25 00:08:16 +04:00
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
|
|
|
|
{
|
2000-06-21 02:45:45 +04:00
|
|
|
if (mOp2.first != NotARegister)
|
|
|
|
f << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2000-04-21 04:04:14 +04:00
|
|
|
void resolveTo (uint32 aOffset) { mOp1->mOffset = aOffset; }
|
|
|
|
uint32 getOffset() { return mOp1->mOffset; }
|
2000-05-27 02:33:05 +04:00
|
|
|
void setTarget(Label *label) { mOp1 = label; }
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-04-21 04:04:14 +04:00
|
|
|
/********************************************************************/
|
|
|
|
|
|
|
|
/* Specific opcodes */
|
2000-04-19 01:51:45 +04:00
|
|
|
class Add : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Add (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-04-19 01:51:45 +04:00
|
|
|
Arithmetic
|
2000-04-21 04:04:14 +04:00
|
|
|
(ADD, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class And : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
And (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(AND, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Bitnot : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
|
|
|
/* dest, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
Bitnot (TypedRegister aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>
|
2000-05-06 01:38:16 +04:00
|
|
|
(BITNOT, aOp1, aOp2) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[BITNOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
|
2000-05-06 01:38:16 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-05-06 01:38:16 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
class Branch : public GenericBranch {
|
|
|
|
public:
|
|
|
|
/* target label */
|
2000-04-21 04:04:14 +04:00
|
|
|
Branch (Label* aOp1) :
|
2000-04-19 01:51:45 +04:00
|
|
|
GenericBranch
|
2000-04-21 04:04:14 +04:00
|
|
|
(BRANCH, aOp1) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-05-27 02:33:05 +04:00
|
|
|
f << opcodeNames[BRANCH] << "\t" << "Offset " << ((mOp1) ? mOp1->mOffset : NotAnOffset);
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-05-18 04:03:23 +04:00
|
|
|
class BranchFalse : public GenericBranch {
|
|
|
|
public:
|
|
|
|
/* target label, condition */
|
2000-06-21 02:45:45 +04:00
|
|
|
BranchFalse (Label* aOp1, TypedRegister aOp2) :
|
2000-05-18 04:03:23 +04:00
|
|
|
GenericBranch
|
|
|
|
(BRANCH_FALSE, aOp1, aOp2) {};
|
|
|
|
/* print() and printOperands() inherited from GenericBranch */
|
|
|
|
};
|
|
|
|
|
|
|
|
class BranchTrue : public GenericBranch {
|
|
|
|
public:
|
|
|
|
/* target label, condition */
|
2000-06-21 02:45:45 +04:00
|
|
|
BranchTrue (Label* aOp1, TypedRegister aOp2) :
|
2000-05-18 04:03:23 +04:00
|
|
|
GenericBranch
|
|
|
|
(BRANCH_TRUE, aOp1, aOp2) {};
|
|
|
|
/* print() and printOperands() inherited from GenericBranch */
|
|
|
|
};
|
|
|
|
|
2000-06-22 02:32:21 +04:00
|
|
|
class Call : public Instruction_4<TypedRegister, TypedRegister, const StringAtom*, RegisterList> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-06-22 02:32:21 +04:00
|
|
|
/* result, target, name, args */
|
|
|
|
Call (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3, RegisterList aOp4) :
|
|
|
|
Instruction_4<TypedRegister, TypedRegister, const StringAtom*, RegisterList>
|
|
|
|
(CALL, aOp1, aOp2, aOp3, aOp4) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-22 02:32:21 +04:00
|
|
|
f << opcodeNames[CALL] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-22 02:32:21 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << ArgList(mOp4, registers);
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareEQ (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_EQ, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareGE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareGE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_GE, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareGT : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareGT (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_GT, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareIN : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareIN (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_IN, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-05-06 01:38:16 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareLE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareLE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_LE, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareLT : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareLT (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_LT, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class CompareNE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
CompareNE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(COMPARE_NE, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-24 02:27:17 +04:00
|
|
|
class Debugger : public Instruction {
|
|
|
|
public:
|
|
|
|
/* drop to the debugger */
|
|
|
|
Debugger () :
|
|
|
|
Instruction
|
|
|
|
(DEBUGGER) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[DEBUGGER];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
class Divide : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Divide (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-04-19 01:51:45 +04:00
|
|
|
Arithmetic
|
2000-04-21 04:04:14 +04:00
|
|
|
(DIVIDE, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class ElemXcr : public Instruction_4<TypedRegister, TypedRegister, TypedRegister, double> {
|
2000-05-18 04:03:23 +04:00
|
|
|
public:
|
|
|
|
/* dest, base, index, value */
|
2000-06-21 02:45:45 +04:00
|
|
|
ElemXcr (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3, double aOp4) :
|
|
|
|
Instruction_4<TypedRegister, TypedRegister, TypedRegister, double>
|
2000-05-18 04:03:23 +04:00
|
|
|
(ELEM_XCR, aOp1, aOp2, aOp3, aOp4) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[ELEM_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first << ", " << mOp4;
|
2000-05-18 04:03:23 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
2000-05-18 04:03:23 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class GetElement : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, base, index */
|
2000-06-21 02:45:45 +04:00
|
|
|
GetElement (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(GET_ELEMENT, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[GET_ELEMENT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class GetProp : public Instruction_3<TypedRegister, TypedRegister, const StringAtom*> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
|
|
|
/* dest, object, prop name */
|
2000-06-21 02:45:45 +04:00
|
|
|
GetProp (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, const StringAtom*>
|
2000-04-21 04:04:14 +04:00
|
|
|
(GET_PROP, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[GET_PROP] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'";
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-24 03:43:24 +04:00
|
|
|
class GetSlot : public Instruction_3<TypedRegister, TypedRegister, uint32> {
|
|
|
|
public:
|
|
|
|
/* dest, object, slot number */
|
|
|
|
GetSlot (TypedRegister aOp1, TypedRegister aOp2, uint32 aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, uint32>
|
|
|
|
(GET_SLOT, aOp1, aOp2, aOp3) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[GET_SLOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-28 20:13:12 +04:00
|
|
|
class GetStatic : public Instruction_3<TypedRegister, JSClass*, uint32> {
|
2000-06-27 06:39:32 +04:00
|
|
|
public:
|
2000-06-28 20:13:12 +04:00
|
|
|
/* dest, class, index */
|
|
|
|
GetStatic (TypedRegister aOp1, JSClass* aOp2, uint32 aOp3) :
|
|
|
|
Instruction_3<TypedRegister, JSClass*, uint32>
|
2000-06-27 06:39:32 +04:00
|
|
|
(GET_STATIC, aOp1, aOp2, aOp3) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-28 20:13:12 +04:00
|
|
|
f << opcodeNames[GET_STATIC] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << mOp3;
|
2000-06-27 06:39:32 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Instanceof : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Instanceof (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(INSTANCEOF, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-05-06 01:38:16 +04:00
|
|
|
};
|
|
|
|
|
2000-04-27 05:27:09 +04:00
|
|
|
class Jsr : public GenericBranch {
|
|
|
|
public:
|
|
|
|
/* target */
|
|
|
|
Jsr (Label* aOp1) :
|
|
|
|
GenericBranch
|
|
|
|
(JSR, aOp1) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-05-27 02:33:05 +04:00
|
|
|
f << opcodeNames[JSR] << "\t" << "Offset " << ((mOp1) ? mOp1->mOffset : NotAnOffset);
|
2000-04-27 05:27:09 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-27 05:27:09 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class LoadBoolean : public Instruction_2<TypedRegister, bool> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-06-21 02:45:45 +04:00
|
|
|
/* dest, immediate value (boolean) */
|
|
|
|
LoadBoolean (TypedRegister aOp1, bool aOp2) :
|
|
|
|
Instruction_2<TypedRegister, bool>
|
|
|
|
(LOAD_BOOLEAN, aOp1, aOp2) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[LOAD_BOOLEAN] << "\t" << "R" << mOp1.first << ", " << "'" << ((mOp2) ? "true" : "false") << "'";
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class LoadImmediate : public Instruction_2<TypedRegister, double> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-06-21 02:45:45 +04:00
|
|
|
/* dest, immediate value (double) */
|
|
|
|
LoadImmediate (TypedRegister aOp1, double aOp2) :
|
|
|
|
Instruction_2<TypedRegister, double>
|
|
|
|
(LOAD_IMMEDIATE, aOp1, aOp2) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[LOAD_IMMEDIATE] << "\t" << "R" << mOp1.first << ", " << mOp2;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class LoadName : public Instruction_2<TypedRegister, const StringAtom*> {
|
2000-05-06 03:22:31 +04:00
|
|
|
public:
|
2000-06-21 02:45:45 +04:00
|
|
|
/* dest, name */
|
|
|
|
LoadName (TypedRegister aOp1, const StringAtom* aOp2) :
|
|
|
|
Instruction_2<TypedRegister, const StringAtom*>
|
|
|
|
(LOAD_NAME, aOp1, aOp2) {};
|
2000-05-06 03:22:31 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[LOAD_NAME] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
|
2000-05-06 03:22:31 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-05-06 03:22:31 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class LoadString : public Instruction_2<TypedRegister, JSString*> {
|
2000-05-18 04:03:23 +04:00
|
|
|
public:
|
2000-06-21 02:45:45 +04:00
|
|
|
/* dest, immediate value (string) */
|
|
|
|
LoadString (TypedRegister aOp1, JSString* aOp2) :
|
|
|
|
Instruction_2<TypedRegister, JSString*>
|
|
|
|
(LOAD_STRING, aOp1, aOp2) {};
|
2000-05-18 04:03:23 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[LOAD_STRING] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
|
2000-05-18 04:03:23 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-05-18 04:03:23 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-22 02:32:21 +04:00
|
|
|
class MethodCall : public Instruction_4<TypedRegister, TypedRegister, TypedRegister, RegisterList> {
|
|
|
|
public:
|
|
|
|
/* result, target base, target value, args */
|
|
|
|
MethodCall (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3, RegisterList aOp4) :
|
|
|
|
Instruction_4<TypedRegister, TypedRegister, TypedRegister, RegisterList>
|
|
|
|
(METHOD_CALL, aOp1, aOp2, aOp3, aOp4) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[METHOD_CALL] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first << ", " << mOp4;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first] << ", " << ArgList(mOp4, registers);
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Move : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
|
|
|
/* dest, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
Move (TypedRegister aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(MOVE, aOp1, aOp2) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[MOVE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
class Multiply : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Multiply (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-04-19 01:51:45 +04:00
|
|
|
Arithmetic
|
2000-04-21 04:04:14 +04:00
|
|
|
(MULTIPLY, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class NameXcr : public Instruction_3<TypedRegister, const StringAtom*, double> {
|
2000-05-11 04:35:06 +04:00
|
|
|
public:
|
|
|
|
/* dest, name, value */
|
2000-06-21 02:45:45 +04:00
|
|
|
NameXcr (TypedRegister aOp1, const StringAtom* aOp2, double aOp3) :
|
|
|
|
Instruction_3<TypedRegister, const StringAtom*, double>
|
2000-05-11 04:35:06 +04:00
|
|
|
(NAME_XCR, aOp1, aOp2, aOp3) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[NAME_XCR] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << mOp3;
|
2000-05-11 04:35:06 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-05-11 04:35:06 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Negate : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
|
|
|
/* dest, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
Negate (TypedRegister aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>
|
2000-05-06 01:38:16 +04:00
|
|
|
(NEGATE, aOp1, aOp2) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[NEGATE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
|
2000-05-06 01:38:16 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-05-06 01:38:16 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class NewArray : public Instruction_1<TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
|
|
|
/* dest */
|
2000-06-21 02:45:45 +04:00
|
|
|
NewArray (TypedRegister aOp1) :
|
|
|
|
Instruction_1<TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(NEW_ARRAY, aOp1) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[NEW_ARRAY] << "\t" << "R" << mOp1.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-24 03:49:17 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class NewClass : public Instruction_2<TypedRegister, const StringAtom*> {
|
|
|
|
public:
|
|
|
|
/* dest, class name */
|
|
|
|
NewClass (TypedRegister aOp1, const StringAtom* aOp2) :
|
|
|
|
Instruction_2<TypedRegister, const StringAtom*>
|
|
|
|
(NEW_CLASS, aOp1, aOp2) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[NEW_CLASS] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-22 02:32:21 +04:00
|
|
|
class NewFunction : public Instruction_2<TypedRegister, ICodeModule *> {
|
|
|
|
public:
|
|
|
|
/* dest, ICodeModule */
|
|
|
|
NewFunction (TypedRegister aOp1, ICodeModule * aOp2) :
|
|
|
|
Instruction_2<TypedRegister, ICodeModule *>
|
|
|
|
(NEW_FUNCTION, aOp1, aOp2) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[NEW_FUNCTION] << "\t" << "R" << mOp1.first << ", " << "ICodeModule";
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class NewObject : public Instruction_1<TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
|
|
|
/* dest */
|
2000-06-21 02:45:45 +04:00
|
|
|
NewObject (TypedRegister aOp1) :
|
|
|
|
Instruction_1<TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(NEW_OBJECT, aOp1) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[NEW_OBJECT] << "\t" << "R" << mOp1.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
class Nop : public Instruction {
|
|
|
|
public:
|
|
|
|
/* do nothing and like it */
|
|
|
|
Nop () :
|
|
|
|
Instruction
|
|
|
|
(NOP) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-04-19 01:51:45 +04:00
|
|
|
f << opcodeNames[NOP];
|
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Not : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
|
|
|
/* dest, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
Not (TypedRegister aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(NOT, aOp1, aOp2) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[NOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class Or : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Or (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(OR, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Posate : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
|
|
|
/* dest, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
Posate (TypedRegister aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>
|
2000-05-06 01:38:16 +04:00
|
|
|
(POSATE, aOp1, aOp2) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[POSATE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
|
2000-05-06 01:38:16 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-05-06 01:38:16 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class PropXcr : public Instruction_4<TypedRegister, TypedRegister, const StringAtom*, double> {
|
2000-05-11 04:35:06 +04:00
|
|
|
public:
|
|
|
|
/* dest, source, name, value */
|
2000-06-21 02:45:45 +04:00
|
|
|
PropXcr (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3, double aOp4) :
|
|
|
|
Instruction_4<TypedRegister, TypedRegister, const StringAtom*, double>
|
2000-05-11 04:35:06 +04:00
|
|
|
(PROP_XCR, aOp1, aOp2, aOp3, aOp4) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[PROP_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
|
2000-05-11 04:35:06 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-05-11 04:35:06 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class Remainder : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Remainder (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(REMAINDER, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Return : public Instruction_1<TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
/* return value */
|
2000-06-21 02:45:45 +04:00
|
|
|
Return (TypedRegister aOp1) :
|
|
|
|
Instruction_1<TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(RETURN, aOp1) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[RETURN] << "\t" << "R" << mOp1.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-04-21 04:04:14 +04:00
|
|
|
class ReturnVoid : public Instruction {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
/* Return without a value */
|
|
|
|
ReturnVoid () :
|
|
|
|
Instruction
|
|
|
|
(RETURN_VOID) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-04-21 04:04:14 +04:00
|
|
|
f << opcodeNames[RETURN_VOID];
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-04-27 05:27:09 +04:00
|
|
|
class Rts : public Instruction {
|
|
|
|
public:
|
|
|
|
/* Return to sender */
|
|
|
|
Rts () :
|
|
|
|
Instruction
|
|
|
|
(RTS) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-04-27 05:27:09 +04:00
|
|
|
f << opcodeNames[RTS];
|
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-27 05:27:09 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class SaveName : public Instruction_2<const StringAtom*, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-04-21 04:04:14 +04:00
|
|
|
/* name, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
SaveName (const StringAtom* aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<const StringAtom*, TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(SAVE_NAME, aOp1, aOp2) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[SAVE_NAME] << "\t" << "'" << *mOp1 << "'" << ", " << "R" << mOp2.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class SetElement : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* base, index, value */
|
2000-06-21 02:45:45 +04:00
|
|
|
SetElement (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(SET_ELEMENT, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[SET_ELEMENT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class SetProp : public Instruction_3<TypedRegister, const StringAtom*, TypedRegister> {
|
2000-04-19 01:51:45 +04:00
|
|
|
public:
|
|
|
|
/* object, name, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
SetProp (TypedRegister aOp1, const StringAtom* aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, const StringAtom*, TypedRegister>
|
2000-04-21 04:04:14 +04:00
|
|
|
(SET_PROP, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[SET_PROP] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << "R" << mOp3.first;
|
2000-04-19 01:51:45 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-24 03:43:24 +04:00
|
|
|
class SetSlot : public Instruction_3<TypedRegister, uint32, TypedRegister> {
|
|
|
|
public:
|
|
|
|
/* object, slot number, source */
|
|
|
|
SetSlot (TypedRegister aOp1, uint32 aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, uint32, TypedRegister>
|
|
|
|
(SET_SLOT, aOp1, aOp2, aOp3) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[SET_SLOT] << "\t" << "R" << mOp1.first << ", " << mOp2 << ", " << "R" << mOp3.first;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-28 20:13:12 +04:00
|
|
|
class SetStatic : public Instruction_3<JSClass*, uint32, TypedRegister> {
|
2000-06-27 06:39:32 +04:00
|
|
|
public:
|
2000-06-28 20:13:12 +04:00
|
|
|
/* class, index, source */
|
|
|
|
SetStatic (JSClass* aOp1, uint32 aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<JSClass*, uint32, TypedRegister>
|
2000-06-27 06:39:32 +04:00
|
|
|
(SET_STATIC, aOp1, aOp2, aOp3) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-28 20:13:12 +04:00
|
|
|
f << opcodeNames[SET_STATIC] << "\t" << "'" << *mOp1 << "'" << ", " << mOp2 << ", " << "R" << mOp3.first;
|
2000-06-27 06:39:32 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp3.first << '=' << registers[mOp3.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class Shiftleft : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Shiftleft (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(SHIFTLEFT, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
|
|
|
class Shiftright : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Shiftright (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(SHIFTRIGHT, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
2000-06-24 03:43:24 +04:00
|
|
|
class SlotXcr : public Instruction_4<TypedRegister, TypedRegister, uint32, double> {
|
|
|
|
public:
|
|
|
|
/* dest, source, slot number, value */
|
|
|
|
SlotXcr (TypedRegister aOp1, TypedRegister aOp2, uint32 aOp3, double aOp4) :
|
|
|
|
Instruction_4<TypedRegister, TypedRegister, uint32, double>
|
|
|
|
(SLOT_XCR, aOp1, aOp2, aOp3, aOp4) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[SLOT_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3 << ", " << mOp4;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-28 22:41:30 +04:00
|
|
|
class StaticCall : public Instruction_4<TypedRegister, JSClass*, const StringAtom*, RegisterList> {
|
|
|
|
public:
|
|
|
|
/* result, target class, name, args */
|
|
|
|
StaticCall (TypedRegister aOp1, JSClass* aOp2, const StringAtom* aOp3, RegisterList aOp4) :
|
|
|
|
Instruction_4<TypedRegister, JSClass*, const StringAtom*, RegisterList>
|
|
|
|
(STATIC_CALL, aOp1, aOp2, aOp3, aOp4) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[STATIC_CALL] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << ArgList(mOp4, registers);
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-28 20:13:12 +04:00
|
|
|
class StaticXcr : public Instruction_4<TypedRegister, JSClass*, uint32, double> {
|
2000-06-27 06:39:32 +04:00
|
|
|
public:
|
2000-06-28 20:13:12 +04:00
|
|
|
/* dest, class, index, value */
|
|
|
|
StaticXcr (TypedRegister aOp1, JSClass* aOp2, uint32 aOp3, double aOp4) :
|
|
|
|
Instruction_4<TypedRegister, JSClass*, uint32, double>
|
2000-06-27 06:39:32 +04:00
|
|
|
(STATIC_XCR, aOp1, aOp2, aOp3, aOp4) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-28 20:13:12 +04:00
|
|
|
f << opcodeNames[STATIC_XCR] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << mOp3 << ", " << mOp4;
|
2000-06-27 06:39:32 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class StrictEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
StrictEQ (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(STRICT_EQ, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-05-06 01:38:16 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class StrictNE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
2000-05-06 01:38:16 +04:00
|
|
|
public:
|
2000-05-23 04:08:29 +04:00
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
StrictNE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
2000-05-23 04:08:29 +04:00
|
|
|
(STRICT_NE, aOp1, aOp2, aOp3) {};
|
2000-06-21 02:45:45 +04:00
|
|
|
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
|
2000-05-06 01:38:16 +04:00
|
|
|
};
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
class Subtract : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Subtract (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-04-19 01:51:45 +04:00
|
|
|
Arithmetic
|
2000-04-21 04:04:14 +04:00
|
|
|
(SUBTRACT, aOp1, aOp2, aOp3) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
2000-04-19 01:51:45 +04:00
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Test : public Instruction_2<TypedRegister, TypedRegister> {
|
2000-05-18 04:03:23 +04:00
|
|
|
public:
|
|
|
|
/* dest, source */
|
2000-06-21 02:45:45 +04:00
|
|
|
Test (TypedRegister aOp1, TypedRegister aOp2) :
|
|
|
|
Instruction_2<TypedRegister, TypedRegister>
|
2000-05-18 04:03:23 +04:00
|
|
|
(TEST, aOp1, aOp2) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[TEST] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
|
2000-05-18 04:03:23 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-05-18 04:03:23 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Throw : public Instruction_1<TypedRegister> {
|
2000-04-22 02:52:52 +04:00
|
|
|
public:
|
2000-04-27 05:27:09 +04:00
|
|
|
/* exception value */
|
2000-06-21 02:45:45 +04:00
|
|
|
Throw (TypedRegister aOp1) :
|
|
|
|
Instruction_1<TypedRegister>
|
2000-04-22 02:52:52 +04:00
|
|
|
(THROW, aOp1) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[THROW] << "\t" << "R" << mOp1.first;
|
2000-04-22 02:52:52 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-22 02:52:52 +04:00
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class Tryin : public Instruction_2<Label*, Label*> {
|
2000-04-22 02:52:52 +04:00
|
|
|
public:
|
2000-04-27 05:27:09 +04:00
|
|
|
/* catch target, finally target */
|
2000-05-06 01:38:16 +04:00
|
|
|
Tryin (Label* aOp1, Label* aOp2) :
|
2000-04-27 05:27:09 +04:00
|
|
|
Instruction_2<Label*, Label*>
|
2000-05-06 01:38:16 +04:00
|
|
|
(TRYIN, aOp1, aOp2) {};
|
2000-04-28 09:41:54 +04:00
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-05-27 02:33:05 +04:00
|
|
|
f << opcodeNames[TRYIN] << "\t" << "Offset " << ((mOp1) ? mOp1->mOffset : NotAnOffset) << ", " << "Offset " << ((mOp2) ? mOp2->mOffset : NotAnOffset);
|
2000-04-27 05:27:09 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-28 17:20:26 +04:00
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
2000-04-28 09:41:54 +04:00
|
|
|
return f;
|
|
|
|
}
|
2000-04-22 02:52:52 +04:00
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class Tryout : public Instruction {
|
|
|
|
public:
|
|
|
|
/* mmm, there is no try, only do */
|
|
|
|
Tryout () :
|
|
|
|
Instruction
|
|
|
|
(TRYOUT) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[TRYOUT];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Ushiftright : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Ushiftright (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(USHIFTRIGHT, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class VarXcr : public Instruction_3<TypedRegister, TypedRegister, double> {
|
2000-05-11 04:35:06 +04:00
|
|
|
public:
|
|
|
|
/* dest, source, value */
|
2000-06-21 02:45:45 +04:00
|
|
|
VarXcr (TypedRegister aOp1, TypedRegister aOp2, double aOp3) :
|
|
|
|
Instruction_3<TypedRegister, TypedRegister, double>
|
2000-05-11 04:35:06 +04:00
|
|
|
(VAR_XCR, aOp1, aOp2, aOp3) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[VAR_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
|
2000-05-11 04:35:06 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
2000-05-11 04:35:06 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-06-21 02:45:45 +04:00
|
|
|
class Within : public Instruction_1<TypedRegister> {
|
2000-04-29 18:10:53 +04:00
|
|
|
public:
|
|
|
|
/* within this object */
|
2000-06-21 02:45:45 +04:00
|
|
|
Within (TypedRegister aOp1) :
|
|
|
|
Instruction_1<TypedRegister>
|
2000-04-29 18:10:53 +04:00
|
|
|
(WITHIN, aOp1) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << opcodeNames[WITHIN] << "\t" << "R" << mOp1.first;
|
2000-04-29 18:10:53 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
2000-06-21 02:45:45 +04:00
|
|
|
f << "R" << mOp1.first << '=' << registers[mOp1.first];
|
2000-04-29 18:10:53 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Without : public Instruction {
|
|
|
|
public:
|
|
|
|
/* without this object */
|
|
|
|
Without () :
|
|
|
|
Instruction
|
|
|
|
(WITHOUT) {};
|
|
|
|
virtual Formatter& print(Formatter& f) {
|
|
|
|
f << opcodeNames[WITHOUT];
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
virtual Formatter& printOperands(Formatter& f, const JSValues& /*registers*/) {
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2000-05-06 01:38:16 +04:00
|
|
|
class Xor : public Arithmetic {
|
|
|
|
public:
|
|
|
|
/* dest, source1, source2 */
|
2000-06-21 02:45:45 +04:00
|
|
|
Xor (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
2000-05-06 01:38:16 +04:00
|
|
|
Arithmetic
|
|
|
|
(XOR, aOp1, aOp2, aOp3) {};
|
|
|
|
/* print() and printOperands() inherited from Arithmetic */
|
|
|
|
};
|
|
|
|
|
2000-04-19 01:51:45 +04:00
|
|
|
} /* namespace VM */
|
2000-04-18 04:19:09 +04:00
|
|
|
|
2000-04-18 11:14:49 +04:00
|
|
|
} /* namespace JavaScript */
|
2000-04-18 04:19:09 +04:00
|
|
|
|
|
|
|
#endif /* vmtypes_h */
|