blob: 8cc827c35fe553a4c11872cb7a2cdf59c6af08eb [file] [log] [blame]
// Copyright (c) 2013, 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.
#ifndef VM_CONSTANTS_X64_H_
#define VM_CONSTANTS_X64_H_
namespace dart {
enum Register {
kFirstFreeCpuRegister = 0,
RAX = 0,
RCX = 1,
RDX = 2,
RBX = 3,
RSP = 4,
RBP = 5,
RSI = 6,
RDI = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15,
kLastFreeCpuRegister = 15,
kNumberOfCpuRegisters = 16,
kNoRegister = -1 // Signals an illegal register.
};
enum ByteRegister {
AL = 0,
CL = 1,
DL = 2,
BL = 3,
AH = 4,
CH = 5,
DH = 6,
BH = 7,
kNoByteRegister = -1 // Signals an illegal register.
};
enum XmmRegister {
XMM0 = 0,
XMM1 = 1,
XMM2 = 2,
XMM3 = 3,
XMM4 = 4,
XMM5 = 5,
XMM6 = 6,
XMM7 = 7,
XMM8 = 8,
XMM9 = 9,
XMM10 = 10,
XMM11 = 11,
XMM12 = 12,
XMM13 = 13,
XMM14 = 14,
XMM15 = 15,
kNumberOfXmmRegisters = 16,
kNoXmmRegister = -1 // Signals an illegal register.
};
// Architecture independent aliases.
typedef XmmRegister FpuRegister;
const FpuRegister FpuTMP = XMM0;
const int kNumberOfFpuRegisters = kNumberOfXmmRegisters;
const FpuRegister kNoFpuRegister = kNoXmmRegister;
enum RexBits {
REX_NONE = 0,
REX_B = 1 << 0,
REX_X = 1 << 1,
REX_R = 1 << 2,
REX_W = 1 << 3,
REX_PREFIX = 1 << 6
};
// Register aliases.
const Register TMP = R11; // Used as scratch register by the assembler.
const Register CTX = R15; // Caches current context in generated code.
const Register PP = kNoRegister; // No object pool pointer.
const Register SPREG = RSP; // Stack pointer register.
const Register FPREG = RBP; // Frame pointer register.
// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
const Register kExceptionObjectReg = RAX;
// Stack trace object is passed in this register to the catch handlers when
// an exception is thrown.
const Register kStackTraceObjectReg = RDX;
enum ScaleFactor {
TIMES_1 = 0,
TIMES_2 = 1,
TIMES_4 = 2,
TIMES_8 = 3,
TIMES_16 = 4,
TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1
};
enum Condition {
OVERFLOW = 0,
NO_OVERFLOW = 1,
BELOW = 2,
ABOVE_EQUAL = 3,
EQUAL = 4,
NOT_EQUAL = 5,
BELOW_EQUAL = 6,
ABOVE = 7,
SIGN = 8,
NOT_SIGN = 9,
PARITY_EVEN = 10,
PARITY_ODD = 11,
LESS = 12,
GREATER_EQUAL = 13,
LESS_EQUAL = 14,
GREATER = 15,
ZERO = EQUAL,
NOT_ZERO = NOT_EQUAL,
NEGATIVE = SIGN,
POSITIVE = NOT_SIGN,
CARRY = BELOW,
NOT_CARRY = ABOVE_EQUAL
};
class Instr {
public:
static const uint8_t kHltInstruction = 0xF4;
// We prefer not to use the int3 instruction since it conflicts with gdb.
static const uint8_t kBreakPointInstruction = kHltInstruction;
static const int kBreakPointInstructionSize = 1;
bool IsBreakPoint() {
ASSERT(kBreakPointInstructionSize == 1);
return (*reinterpret_cast<const uint8_t*>(this)) == kBreakPointInstruction;
}
// Instructions are read out of a code stream. The only way to get a
// reference to an instruction is to convert a pointer. There is no way
// to allocate or create instances of class Instr.
// Use the At(pc) function to create references to Instr.
static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
private:
DISALLOW_ALLOCATION();
// We need to prevent the creation of instances of class Instr.
DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
};
// The largest multibyte nop we will emit. This could go up to 15 if it
// becomes important to us.
const int MAX_NOP_SIZE = 8;
} // namespace dart
#endif // VM_CONSTANTS_X64_H_