6202749429
Change-Id: I2882546741b1dd8f6e03a21d85b5487fb754b742 Reviewed-on: https://dart-review.googlesource.com/55324 Reviewed-by: Régis Crelier <regis@google.com> Reviewed-by: Zach Anderson <zra@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
925 lines
22 KiB
Dart
925 lines
22 KiB
Dart
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
library vm.bytecode.assembler;
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:vm/bytecode/dbc.dart';
|
|
import 'package:vm/bytecode/exceptions.dart' show ExceptionsTable;
|
|
|
|
class Label {
|
|
List<int> _jumps = <int>[];
|
|
int offset = -1;
|
|
|
|
Label();
|
|
|
|
bool get isBound => offset >= 0;
|
|
|
|
int jumpOperand(int jumpOffset) {
|
|
if (isBound) {
|
|
// Jump instruction takes an offset in DBC words.
|
|
return (offset - jumpOffset) >> BytecodeAssembler.kLog2BytesPerBytecode;
|
|
}
|
|
_jumps.add(jumpOffset);
|
|
return 0;
|
|
}
|
|
|
|
List<int> bind(int offset) {
|
|
assert(!isBound);
|
|
this.offset = offset;
|
|
final jumps = _jumps;
|
|
_jumps = null;
|
|
return jumps;
|
|
}
|
|
}
|
|
|
|
class BytecodeAssembler {
|
|
static const int kBitsPerInt = 64;
|
|
static const int kLog2BytesPerBytecode = 2;
|
|
|
|
// TODO(alexmarkov): figure out more efficient storage for generated bytecode.
|
|
final List<int> bytecode = new List<int>();
|
|
final Uint32List _encodeBufferIn;
|
|
final Uint8List _encodeBufferOut;
|
|
final ExceptionsTable exceptionsTable = new ExceptionsTable();
|
|
|
|
BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut);
|
|
|
|
factory BytecodeAssembler() {
|
|
final buf = new Uint32List(1);
|
|
return new BytecodeAssembler._(buf, new Uint8List.view(buf.buffer));
|
|
}
|
|
|
|
int get offset => bytecode.length;
|
|
int get offsetInWords => bytecode.length >> kLog2BytesPerBytecode;
|
|
|
|
void bind(Label label) {
|
|
final List<int> jumps = label.bind(offset);
|
|
for (int jumpOffset in jumps) {
|
|
patchJump(jumpOffset, label.jumpOperand(jumpOffset));
|
|
}
|
|
}
|
|
|
|
void emitWord(int word) {
|
|
_encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
|
|
bytecode.addAll(_encodeBufferOut);
|
|
}
|
|
|
|
void _setWord(int pos, int word) {
|
|
_encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
|
|
bytecode.setRange(pos, pos + _encodeBufferOut.length, _encodeBufferOut);
|
|
}
|
|
|
|
int _unsigned(int v, int bits) {
|
|
assert(bits < kBitsPerInt);
|
|
final int mask = (1 << bits) - 1;
|
|
if ((v & mask) != v) {
|
|
throw 'Value $v is out of unsigned $bits-bit range';
|
|
}
|
|
return v;
|
|
}
|
|
|
|
int _signed(int v, int bits) {
|
|
assert(bits < kBitsPerInt);
|
|
final int shift = kBitsPerInt - bits;
|
|
if (((v << shift) >> shift) != v) {
|
|
throw 'Value $v is out of signed $bits-bit range';
|
|
}
|
|
final int mask = (1 << bits) - 1;
|
|
return v & mask;
|
|
}
|
|
|
|
int _uint8(int v) => _unsigned(v, 8);
|
|
int _uint16(int v) => _unsigned(v, 16);
|
|
|
|
int _int8(int v) => _signed(v, 8);
|
|
int _int16(int v) => _signed(v, 16);
|
|
int _int24(int v) => _signed(v, 24);
|
|
|
|
int _encode0(Opcode opcode) => _uint8(opcode.index);
|
|
|
|
int _encodeA(Opcode opcode, int ra) =>
|
|
_uint8(opcode.index) | (_uint8(ra) << 8);
|
|
|
|
int _encodeAD(Opcode opcode, int ra, int rd) =>
|
|
_uint8(opcode.index) | (_uint8(ra) << 8) | (_uint16(rd) << 16);
|
|
|
|
int _encodeAX(Opcode opcode, int ra, int rx) =>
|
|
_uint8(opcode.index) | (_uint8(ra) << 8) | (_int16(rx) << 16);
|
|
|
|
int _encodeD(Opcode opcode, int rd) =>
|
|
_uint8(opcode.index) | (_uint16(rd) << 16);
|
|
|
|
int _encodeX(Opcode opcode, int rx) =>
|
|
_uint8(opcode.index) | (_int16(rx) << 16);
|
|
|
|
int _encodeABC(Opcode opcode, int ra, int rb, int rc) =>
|
|
_uint8(opcode.index) |
|
|
(_uint8(ra) << 8) |
|
|
(_uint8(rb) << 16) |
|
|
(_uint8(rc) << 24);
|
|
|
|
int _encodeABY(Opcode opcode, int ra, int rb, int ry) =>
|
|
_uint8(opcode.index) |
|
|
(_uint8(ra) << 8) |
|
|
(_uint8(rb) << 16) |
|
|
(_int8(ry) << 24);
|
|
|
|
int _encodeT(Opcode opcode, int rt) =>
|
|
_uint8(opcode.index) | (_int24(rt) << 8);
|
|
|
|
void emitTrap() {
|
|
emitWord(_encode0(Opcode.kTrap));
|
|
}
|
|
|
|
void emitNop(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kNop, ra, rd));
|
|
}
|
|
|
|
void emitCompile() {
|
|
emitWord(_encode0(Opcode.kCompile));
|
|
}
|
|
|
|
void emitHotCheck(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kHotCheck, ra, rd));
|
|
}
|
|
|
|
void emitIntrinsic(int ra) {
|
|
emitWord(_encodeA(Opcode.kIntrinsic, ra));
|
|
}
|
|
|
|
void emitDrop1() {
|
|
emitWord(_encode0(Opcode.kDrop1));
|
|
}
|
|
|
|
void emitDropR(int ra) {
|
|
emitWord(_encodeA(Opcode.kDropR, ra));
|
|
}
|
|
|
|
void emitDrop(int ra) {
|
|
emitWord(_encodeA(Opcode.kDrop, ra));
|
|
}
|
|
|
|
void emitJump(Label label) {
|
|
emitWord(_encodeT(Opcode.kJump, label.jumpOperand(offset)));
|
|
}
|
|
|
|
void patchJump(int pos, int rt) {
|
|
_setWord(pos, _encodeT(Opcode.kJump, rt));
|
|
}
|
|
|
|
void emitReturn(int ra) {
|
|
emitWord(_encodeA(Opcode.kReturn, ra));
|
|
}
|
|
|
|
void emitReturnTOS() {
|
|
emitWord(_encode0(Opcode.kReturnTOS));
|
|
}
|
|
|
|
void emitMove(int ra, int rx) {
|
|
emitWord(_encodeAX(Opcode.kMove, ra, rx));
|
|
}
|
|
|
|
void emitSwap(int ra, int rx) {
|
|
emitWord(_encodeAX(Opcode.kSwap, ra, rx));
|
|
}
|
|
|
|
void emitPush(int rx) {
|
|
emitWord(_encodeX(Opcode.kPush, rx));
|
|
}
|
|
|
|
void emitLoadConstant(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kLoadConstant, ra, rd));
|
|
}
|
|
|
|
void emitLoadClassId(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kLoadClassId, ra, rd));
|
|
}
|
|
|
|
void emitLoadClassIdTOS() {
|
|
emitWord(_encode0(Opcode.kLoadClassIdTOS));
|
|
}
|
|
|
|
void emitPushConstant(int rd) {
|
|
emitWord(_encodeD(Opcode.kPushConstant, rd));
|
|
}
|
|
|
|
void emitStoreLocal(int rx) {
|
|
emitWord(_encodeX(Opcode.kStoreLocal, rx));
|
|
}
|
|
|
|
void emitPopLocal(int rx) {
|
|
emitWord(_encodeX(Opcode.kPopLocal, rx));
|
|
}
|
|
|
|
void emitIndirectStaticCall(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd));
|
|
}
|
|
|
|
void emitStaticCall(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kStaticCall, ra, rd));
|
|
}
|
|
|
|
void emitInstanceCall1(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kInstanceCall1, ra, rd));
|
|
}
|
|
|
|
void emitInstanceCall2(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kInstanceCall2, ra, rd));
|
|
}
|
|
|
|
void emitInstanceCall1Opt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kInstanceCall1Opt, ra, rd));
|
|
}
|
|
|
|
void emitInstanceCall2Opt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kInstanceCall2Opt, ra, rd));
|
|
}
|
|
|
|
void emitPushPolymorphicInstanceCall(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kPushPolymorphicInstanceCall, ra, rd));
|
|
}
|
|
|
|
void emitPushPolymorphicInstanceCallByRange(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kPushPolymorphicInstanceCallByRange, ra, rd));
|
|
}
|
|
|
|
void emitNativeCall(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kNativeCall, ra, rb, rc));
|
|
}
|
|
|
|
void emitOneByteStringFromCharCode(int ra, int rx) {
|
|
emitWord(_encodeAX(Opcode.kOneByteStringFromCharCode, ra, rx));
|
|
}
|
|
|
|
void emitStringToCharCode(int ra, int rx) {
|
|
emitWord(_encodeAX(Opcode.kStringToCharCode, ra, rx));
|
|
}
|
|
|
|
void emitAddTOS() {
|
|
emitWord(_encode0(Opcode.kAddTOS));
|
|
}
|
|
|
|
void emitSubTOS() {
|
|
emitWord(_encode0(Opcode.kSubTOS));
|
|
}
|
|
|
|
void emitMulTOS() {
|
|
emitWord(_encode0(Opcode.kMulTOS));
|
|
}
|
|
|
|
void emitBitOrTOS() {
|
|
emitWord(_encode0(Opcode.kBitOrTOS));
|
|
}
|
|
|
|
void emitBitAndTOS() {
|
|
emitWord(_encode0(Opcode.kBitAndTOS));
|
|
}
|
|
|
|
void emitEqualTOS() {
|
|
emitWord(_encode0(Opcode.kEqualTOS));
|
|
}
|
|
|
|
void emitLessThanTOS() {
|
|
emitWord(_encode0(Opcode.kLessThanTOS));
|
|
}
|
|
|
|
void emitGreaterThanTOS() {
|
|
emitWord(_encode0(Opcode.kGreaterThanTOS));
|
|
}
|
|
|
|
void emitSmiAddTOS() {
|
|
emitWord(_encode0(Opcode.kSmiAddTOS));
|
|
}
|
|
|
|
void emitSmiSubTOS() {
|
|
emitWord(_encode0(Opcode.kSmiSubTOS));
|
|
}
|
|
|
|
void emitSmiMulTOS() {
|
|
emitWord(_encode0(Opcode.kSmiMulTOS));
|
|
}
|
|
|
|
void emitSmiBitAndTOS() {
|
|
emitWord(_encode0(Opcode.kSmiBitAndTOS));
|
|
}
|
|
|
|
void emitAdd(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kAdd, ra, rb, rc));
|
|
}
|
|
|
|
void emitSub(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kSub, ra, rb, rc));
|
|
}
|
|
|
|
void emitMul(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kMul, ra, rb, rc));
|
|
}
|
|
|
|
void emitDiv(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDiv, ra, rb, rc));
|
|
}
|
|
|
|
void emitMod(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kMod, ra, rb, rc));
|
|
}
|
|
|
|
void emitShl(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kShl, ra, rb, rc));
|
|
}
|
|
|
|
void emitShr(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kShr, ra, rb, rc));
|
|
}
|
|
|
|
void emitShlImm(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kShlImm, ra, rb, rc));
|
|
}
|
|
|
|
void emitNeg(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kNeg, ra, rd));
|
|
}
|
|
|
|
void emitBitOr(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kBitOr, ra, rb, rc));
|
|
}
|
|
|
|
void emitBitAnd(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kBitAnd, ra, rb, rc));
|
|
}
|
|
|
|
void emitBitXor(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kBitXor, ra, rb, rc));
|
|
}
|
|
|
|
void emitBitNot(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kBitNot, ra, rd));
|
|
}
|
|
|
|
void emitMin(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kMin, ra, rb, rc));
|
|
}
|
|
|
|
void emitMax(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kMax, ra, rb, rc));
|
|
}
|
|
|
|
void emitWriteIntoDouble(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kWriteIntoDouble, ra, rd));
|
|
}
|
|
|
|
void emitUnboxDouble(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kUnboxDouble, ra, rd));
|
|
}
|
|
|
|
void emitCheckedUnboxDouble(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kCheckedUnboxDouble, ra, rd));
|
|
}
|
|
|
|
void emitUnboxInt32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kUnboxInt32, ra, rb, rc));
|
|
}
|
|
|
|
void emitBoxInt32(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kBoxInt32, ra, rd));
|
|
}
|
|
|
|
void emitBoxUint32(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kBoxUint32, ra, rd));
|
|
}
|
|
|
|
void emitSmiToDouble(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kSmiToDouble, ra, rd));
|
|
}
|
|
|
|
void emitDoubleToSmi(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDoubleToSmi, ra, rd));
|
|
}
|
|
|
|
void emitDAdd(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDAdd, ra, rb, rc));
|
|
}
|
|
|
|
void emitDSub(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDSub, ra, rb, rc));
|
|
}
|
|
|
|
void emitDMul(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDMul, ra, rb, rc));
|
|
}
|
|
|
|
void emitDDiv(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDDiv, ra, rb, rc));
|
|
}
|
|
|
|
void emitDNeg(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDNeg, ra, rd));
|
|
}
|
|
|
|
void emitDSqrt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDSqrt, ra, rd));
|
|
}
|
|
|
|
void emitDMin(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDMin, ra, rb, rc));
|
|
}
|
|
|
|
void emitDMax(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDMax, ra, rb, rc));
|
|
}
|
|
|
|
void emitDCos(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDCos, ra, rd));
|
|
}
|
|
|
|
void emitDSin(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDSin, ra, rd));
|
|
}
|
|
|
|
void emitDPow(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDPow, ra, rb, rc));
|
|
}
|
|
|
|
void emitDMod(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kDMod, ra, rb, rc));
|
|
}
|
|
|
|
void emitDTruncate(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDTruncate, ra, rd));
|
|
}
|
|
|
|
void emitDFloor(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDFloor, ra, rd));
|
|
}
|
|
|
|
void emitDCeil(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDCeil, ra, rd));
|
|
}
|
|
|
|
void emitDoubleToFloat(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDoubleToFloat, ra, rd));
|
|
}
|
|
|
|
void emitFloatToDouble(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kFloatToDouble, ra, rd));
|
|
}
|
|
|
|
void emitDoubleIsNaN(int ra) {
|
|
emitWord(_encodeA(Opcode.kDoubleIsNaN, ra));
|
|
}
|
|
|
|
void emitDoubleIsInfinite(int ra) {
|
|
emitWord(_encodeA(Opcode.kDoubleIsInfinite, ra));
|
|
}
|
|
|
|
void emitStoreStaticTOS(int rd) {
|
|
emitWord(_encodeD(Opcode.kStoreStaticTOS, rd));
|
|
}
|
|
|
|
void emitPushStatic(int rd) {
|
|
emitWord(_encodeD(Opcode.kPushStatic, rd));
|
|
}
|
|
|
|
void emitInitStaticTOS() {
|
|
emitWord(_encode0(Opcode.kInitStaticTOS));
|
|
}
|
|
|
|
void emitIfNeStrictTOS() {
|
|
emitWord(_encode0(Opcode.kIfNeStrictTOS));
|
|
}
|
|
|
|
void emitIfEqStrictTOS() {
|
|
emitWord(_encode0(Opcode.kIfEqStrictTOS));
|
|
}
|
|
|
|
void emitIfNeStrictNumTOS() {
|
|
emitWord(_encode0(Opcode.kIfNeStrictNumTOS));
|
|
}
|
|
|
|
void emitIfEqStrictNumTOS() {
|
|
emitWord(_encode0(Opcode.kIfEqStrictNumTOS));
|
|
}
|
|
|
|
void emitIfSmiLtTOS() {
|
|
emitWord(_encode0(Opcode.kIfSmiLtTOS));
|
|
}
|
|
|
|
void emitIfSmiLeTOS() {
|
|
emitWord(_encode0(Opcode.kIfSmiLeTOS));
|
|
}
|
|
|
|
void emitIfSmiGeTOS() {
|
|
emitWord(_encode0(Opcode.kIfSmiGeTOS));
|
|
}
|
|
|
|
void emitIfSmiGtTOS() {
|
|
emitWord(_encode0(Opcode.kIfSmiGtTOS));
|
|
}
|
|
|
|
void emitIfNeStrict(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfNeStrict, ra, rd));
|
|
}
|
|
|
|
void emitIfEqStrict(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfEqStrict, ra, rd));
|
|
}
|
|
|
|
void emitIfLe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfLe, ra, rd));
|
|
}
|
|
|
|
void emitIfLt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfLt, ra, rd));
|
|
}
|
|
|
|
void emitIfGe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfGe, ra, rd));
|
|
}
|
|
|
|
void emitIfGt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfGt, ra, rd));
|
|
}
|
|
|
|
void emitIfULe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfULe, ra, rd));
|
|
}
|
|
|
|
void emitIfULt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfULt, ra, rd));
|
|
}
|
|
|
|
void emitIfUGe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfUGe, ra, rd));
|
|
}
|
|
|
|
void emitIfUGt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfUGt, ra, rd));
|
|
}
|
|
|
|
void emitIfDNe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfDNe, ra, rd));
|
|
}
|
|
|
|
void emitIfDEq(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfDEq, ra, rd));
|
|
}
|
|
|
|
void emitIfDLe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfDLe, ra, rd));
|
|
}
|
|
|
|
void emitIfDLt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfDLt, ra, rd));
|
|
}
|
|
|
|
void emitIfDGe(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfDGe, ra, rd));
|
|
}
|
|
|
|
void emitIfDGt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfDGt, ra, rd));
|
|
}
|
|
|
|
void emitIfNeStrictNum(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfNeStrictNum, ra, rd));
|
|
}
|
|
|
|
void emitIfEqStrictNum(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kIfEqStrictNum, ra, rd));
|
|
}
|
|
|
|
void emitIfEqNull(int ra) {
|
|
emitWord(_encodeA(Opcode.kIfEqNull, ra));
|
|
}
|
|
|
|
void emitIfNeNull(int ra) {
|
|
emitWord(_encodeA(Opcode.kIfNeNull, ra));
|
|
}
|
|
|
|
void emitCreateArrayTOS() {
|
|
emitWord(_encode0(Opcode.kCreateArrayTOS));
|
|
}
|
|
|
|
void emitCreateArrayOpt(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kCreateArrayOpt, ra, rb, rc));
|
|
}
|
|
|
|
void emitAllocate(int rd) {
|
|
emitWord(_encodeD(Opcode.kAllocate, rd));
|
|
}
|
|
|
|
void emitAllocateT() {
|
|
emitWord(_encode0(Opcode.kAllocateT));
|
|
}
|
|
|
|
void emitAllocateOpt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kAllocateOpt, ra, rd));
|
|
}
|
|
|
|
void emitAllocateTOpt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kAllocateTOpt, ra, rd));
|
|
}
|
|
|
|
void emitStoreIndexedTOS() {
|
|
emitWord(_encode0(Opcode.kStoreIndexedTOS));
|
|
}
|
|
|
|
void emitStoreIndexed(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexed, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexedUint8(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexedUint8, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexedExternalUint8(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexedExternalUint8, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexedOneByteString(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexedOneByteString, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexedUint32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexedUint32, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexedFloat32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexedFloat32, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexed4Float32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexed4Float32, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexedFloat64(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexedFloat64, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreIndexed8Float64(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreIndexed8Float64, ra, rb, rc));
|
|
}
|
|
|
|
void emitNoSuchMethod() {
|
|
emitWord(_encode0(Opcode.kNoSuchMethod));
|
|
}
|
|
|
|
void emitTailCall() {
|
|
emitWord(_encode0(Opcode.kTailCall));
|
|
}
|
|
|
|
void emitTailCallOpt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kTailCallOpt, ra, rd));
|
|
}
|
|
|
|
void emitLoadArgDescriptor() {
|
|
emitWord(_encode0(Opcode.kLoadArgDescriptor));
|
|
}
|
|
|
|
void emitLoadArgDescriptorOpt(int ra) {
|
|
emitWord(_encodeA(Opcode.kLoadArgDescriptorOpt, ra));
|
|
}
|
|
|
|
void emitLoadFpRelativeSlot(int rx) {
|
|
emitWord(_encodeX(Opcode.kLoadFpRelativeSlot, rx));
|
|
}
|
|
|
|
void emitLoadFpRelativeSlotOpt(int ra, int rb, int ry) {
|
|
emitWord(_encodeABY(Opcode.kLoadFpRelativeSlotOpt, ra, rb, ry));
|
|
}
|
|
|
|
void emitStoreFpRelativeSlot(int rx) {
|
|
emitWord(_encodeX(Opcode.kStoreFpRelativeSlot, rx));
|
|
}
|
|
|
|
void emitStoreFpRelativeSlotOpt(int ra, int rb, int ry) {
|
|
emitWord(_encodeABY(Opcode.kStoreFpRelativeSlotOpt, ra, rb, ry));
|
|
}
|
|
|
|
void emitLoadIndexedTOS() {
|
|
emitWord(_encode0(Opcode.kLoadIndexedTOS));
|
|
}
|
|
|
|
void emitLoadIndexed(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexed, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedUint8(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedUint8, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedInt8(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedInt8, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedInt32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedInt32, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedUint32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedUint32, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedExternalUint8(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedExternalUint8, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedExternalInt8(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedExternalInt8, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedFloat32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedFloat32, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexed4Float32(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexed4Float32, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedFloat64(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedFloat64, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexed8Float64(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexed8Float64, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedOneByteString(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedOneByteString, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadIndexedTwoByteString(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadIndexedTwoByteString, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreField(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kStoreField, ra, rb, rc));
|
|
}
|
|
|
|
void emitStoreFieldExt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kStoreFieldExt, ra, rd));
|
|
}
|
|
|
|
void emitStoreFieldTOS(int rd) {
|
|
emitWord(_encodeD(Opcode.kStoreFieldTOS, rd));
|
|
}
|
|
|
|
void emitLoadField(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadField, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadFieldExt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kLoadFieldExt, ra, rd));
|
|
}
|
|
|
|
void emitLoadUntagged(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kLoadUntagged, ra, rb, rc));
|
|
}
|
|
|
|
void emitLoadFieldTOS(int rd) {
|
|
emitWord(_encodeD(Opcode.kLoadFieldTOS, rd));
|
|
}
|
|
|
|
void emitBooleanNegateTOS() {
|
|
emitWord(_encode0(Opcode.kBooleanNegateTOS));
|
|
}
|
|
|
|
void emitBooleanNegate(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kBooleanNegate, ra, rd));
|
|
}
|
|
|
|
void emitThrow(int ra) {
|
|
emitWord(_encodeA(Opcode.kThrow, ra));
|
|
}
|
|
|
|
void emitEntry(int rd) {
|
|
emitWord(_encodeD(Opcode.kEntry, rd));
|
|
}
|
|
|
|
void emitEntryOptimized(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kEntryOptimized, ra, rd));
|
|
}
|
|
|
|
void emitFrame(int rd) {
|
|
emitWord(_encodeD(Opcode.kFrame, rd));
|
|
}
|
|
|
|
void emitSetFrame(int ra) {
|
|
emitWord(_encodeA(Opcode.kSetFrame, ra));
|
|
}
|
|
|
|
void emitAllocateContext(int rd) {
|
|
emitWord(_encodeD(Opcode.kAllocateContext, rd));
|
|
}
|
|
|
|
void emitAllocateUninitializedContext(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kAllocateUninitializedContext, ra, rd));
|
|
}
|
|
|
|
void emitCloneContext() {
|
|
emitWord(_encode0(Opcode.kCloneContext));
|
|
}
|
|
|
|
void emitMoveSpecial(int ra, SpecialIndex rd) {
|
|
emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd.index));
|
|
}
|
|
|
|
void emitInstantiateType(int rd) {
|
|
emitWord(_encodeD(Opcode.kInstantiateType, rd));
|
|
}
|
|
|
|
void emitInstantiateTypeArgumentsTOS(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kInstantiateTypeArgumentsTOS, ra, rd));
|
|
}
|
|
|
|
void emitInstanceOf() {
|
|
emitWord(_encode0(Opcode.kInstanceOf));
|
|
}
|
|
|
|
void emitBadTypeError() {
|
|
emitWord(_encode0(Opcode.kBadTypeError));
|
|
}
|
|
|
|
void emitAssertAssignable(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kAssertAssignable, ra, rd));
|
|
}
|
|
|
|
void emitAssertSubtype() {
|
|
emitWord(_encode0(Opcode.kAssertSubtype));
|
|
}
|
|
|
|
void emitAssertBoolean(int ra) {
|
|
emitWord(_encodeA(Opcode.kAssertBoolean, ra));
|
|
}
|
|
|
|
void emitTestSmi(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kTestSmi, ra, rd));
|
|
}
|
|
|
|
void emitTestCids(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kTestCids, ra, rd));
|
|
}
|
|
|
|
void emitCheckSmi(int ra) {
|
|
emitWord(_encodeA(Opcode.kCheckSmi, ra));
|
|
}
|
|
|
|
void emitCheckEitherNonSmi(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kCheckEitherNonSmi, ra, rd));
|
|
}
|
|
|
|
void emitCheckClassId(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kCheckClassId, ra, rd));
|
|
}
|
|
|
|
void emitCheckClassIdRange(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kCheckClassIdRange, ra, rd));
|
|
}
|
|
|
|
void emitCheckBitTest(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kCheckBitTest, ra, rd));
|
|
}
|
|
|
|
void emitCheckCids(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kCheckCids, ra, rb, rc));
|
|
}
|
|
|
|
void emitCheckCidsByRange(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kCheckCidsByRange, ra, rb, rc));
|
|
}
|
|
|
|
void emitCheckStack() {
|
|
emitWord(_encode0(Opcode.kCheckStack));
|
|
}
|
|
|
|
void emitCheckStackAlwaysExit() {
|
|
emitWord(_encode0(Opcode.kCheckStackAlwaysExit));
|
|
}
|
|
|
|
void emitCheckFunctionTypeArgs(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kCheckFunctionTypeArgs, ra, rd));
|
|
}
|
|
|
|
void emitDebugStep() {
|
|
emitWord(_encode0(Opcode.kDebugStep));
|
|
}
|
|
|
|
void emitDebugBreak(int ra) {
|
|
emitWord(_encodeA(Opcode.kDebugBreak, ra));
|
|
}
|
|
|
|
void emitDeopt(int ra, int rd) {
|
|
emitWord(_encodeAD(Opcode.kDeopt, ra, rd));
|
|
}
|
|
|
|
void emitDeoptRewind() {
|
|
emitWord(_encode0(Opcode.kDeoptRewind));
|
|
}
|
|
|
|
void emitEntryOptional(int ra, int rb, int rc) {
|
|
emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc));
|
|
}
|
|
}
|