summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/assembler-ia32.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.h')
-rw-r--r--deps/v8/src/ia32/assembler-ia32.h217
1 files changed, 25 insertions, 192 deletions
diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h
index b721542f13..96bf2c7eeb 100644
--- a/deps/v8/src/ia32/assembler-ia32.h
+++ b/deps/v8/src/ia32/assembler-ia32.h
@@ -41,122 +41,16 @@
#include "src/assembler.h"
#include "src/ia32/constants-ia32.h"
+#include "src/ia32/register-ia32.h"
#include "src/ia32/sse-instr.h"
#include "src/isolate.h"
+#include "src/label.h"
+#include "src/objects/smi.h"
#include "src/utils.h"
namespace v8 {
namespace internal {
-#define GENERAL_REGISTERS(V) \
- V(eax) \
- V(ecx) \
- V(edx) \
- V(ebx) \
- V(esp) \
- V(ebp) \
- V(esi) \
- V(edi)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(V) \
- V(eax) \
- V(ecx) \
- V(edx) \
- V(ebx) \
- V(esi) \
- V(edi)
-
-#define DOUBLE_REGISTERS(V) \
- V(xmm0) \
- V(xmm1) \
- V(xmm2) \
- V(xmm3) \
- V(xmm4) \
- V(xmm5) \
- V(xmm6) \
- V(xmm7)
-
-#define FLOAT_REGISTERS DOUBLE_REGISTERS
-#define SIMD128_REGISTERS DOUBLE_REGISTERS
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
- V(xmm1) \
- V(xmm2) \
- V(xmm3) \
- V(xmm4) \
- V(xmm5) \
- V(xmm6) \
- V(xmm7)
-
-enum RegisterCode {
-#define REGISTER_CODE(R) kRegCode_##R,
- GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
- kRegAfterLast
-};
-
-class Register : public RegisterBase<Register, kRegAfterLast> {
- public:
- bool is_byte_register() const { return reg_code_ <= 3; }
-
- private:
- friend class RegisterBase<Register, kRegAfterLast>;
- explicit constexpr Register(int code) : RegisterBase(code) {}
-};
-
-ASSERT_TRIVIALLY_COPYABLE(Register);
-static_assert(sizeof(Register) == sizeof(int),
- "Register can efficiently be passed by value");
-
-#define DEFINE_REGISTER(R) \
- constexpr Register R = Register::from_code<kRegCode_##R>();
-GENERAL_REGISTERS(DEFINE_REGISTER)
-#undef DEFINE_REGISTER
-constexpr Register no_reg = Register::no_reg();
-
-constexpr bool kPadArguments = false;
-constexpr bool kSimpleFPAliasing = true;
-constexpr bool kSimdMaskRegisters = false;
-
-enum DoubleCode {
-#define REGISTER_CODE(R) kDoubleCode_##R,
- DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
- kDoubleAfterLast
-};
-
-class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
- friend class RegisterBase<XMMRegister, kDoubleAfterLast>;
- explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
-};
-
-typedef XMMRegister FloatRegister;
-
-typedef XMMRegister DoubleRegister;
-
-typedef XMMRegister Simd128Register;
-
-#define DEFINE_REGISTER(R) \
- constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
-DOUBLE_REGISTERS(DEFINE_REGISTER)
-#undef DEFINE_REGISTER
-constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
-
-// Note that the bit values must match those used in actual instruction encoding
-constexpr int kNumRegs = 8;
-
-// Caller-saved registers
-constexpr RegList kJSCallerSaved =
- Register::ListOf<eax, ecx, edx,
- ebx, // used as a caller-saved register in JavaScript code
- edi // callee function
- >();
-
-constexpr int kNumJSCallerSaved = 5;
-
-// Number of registers for which space is reserved in safepoints.
-constexpr int kNumSafepointRegisters = 8;
-
enum Condition {
// any value < 0 is considered no_condition
no_condition = -1,
@@ -218,11 +112,10 @@ class Immediate {
: Immediate(ext.address(), RelocInfo::EXTERNAL_REFERENCE) {}
inline explicit Immediate(Handle<HeapObject> handle)
: Immediate(handle.address(), RelocInfo::EMBEDDED_OBJECT) {}
- inline explicit Immediate(Smi* value)
- : Immediate(reinterpret_cast<intptr_t>(value)) {}
+ inline explicit Immediate(Smi value)
+ : Immediate(static_cast<intptr_t>(value.ptr())) {}
static Immediate EmbeddedNumber(double number); // Smi or HeapNumber.
- static Immediate EmbeddedCode(CodeStub* code);
static Immediate EmbeddedStringConstant(const StringConstantBase* str);
static Immediate CodeRelativeOffset(Label* label) {
@@ -246,6 +139,14 @@ class Immediate {
return value_.immediate;
}
+ bool is_embedded_object() const {
+ return !is_heap_object_request() && rmode() == RelocInfo::EMBEDDED_OBJECT;
+ }
+
+ Handle<HeapObject> embedded_object() const {
+ return Handle<HeapObject>(reinterpret_cast<Address*>(immediate()));
+ }
+
bool is_external_reference() const {
return rmode() == RelocInfo::EXTERNAL_REFERENCE;
}
@@ -361,17 +262,10 @@ class V8_EXPORT_PRIVATE Operand {
// register.
Register reg() const;
-#ifdef DEBUG
- bool UsesEbx() const { return uses_ebx_; }
-#endif // DEBUG
-
private:
// Set the ModRM byte without an encoded 'reg' register. The
// register is encoded later as part of the emit_operand operation.
inline void set_modrm(int mod, Register rm) {
-#ifdef DEBUG
- AddUsedRegister(rm);
-#endif
DCHECK_EQ(mod & -4, 0);
buf_[0] = mod << 6 | rm.code();
len_ = 1;
@@ -398,23 +292,12 @@ class V8_EXPORT_PRIVATE Operand {
// Only valid if len_ > 4.
RelocInfo::Mode rmode_ = RelocInfo::NONE;
-#ifdef DEBUG
- // TODO(v8:6666): Remove once kRootRegister support is complete.
- bool uses_ebx_ = false;
- void AddUsedRegister(Register reg) {
- if (reg == ebx) uses_ebx_ = true;
- }
-#endif // DEBUG
-
// TODO(clemensh): Get rid of this friendship, or make Operand immutable.
friend class Assembler;
};
ASSERT_TRIVIALLY_COPYABLE(Operand);
-// TODO(v8:6666): Re-enable globally once kRootRegister support is complete.
-#ifndef DEBUG
static_assert(sizeof(Operand) <= 2 * kPointerSize,
"Operand must be small enough to pass it by value");
-#endif
// -----------------------------------------------------------------------------
// A Displacement describes the 32bit immediate field of an instruction which
@@ -485,15 +368,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// for a detailed comment on the layout (globals.h).
//
// If the provided buffer is nullptr, the assembler allocates and grows its
- // own buffer, and buffer_size determines the initial buffer size. The buffer
- // is owned by the assembler and deallocated upon destruction of the
- // assembler.
- //
- // If the provided buffer is not nullptr, the assembler uses the provided
- // buffer for code generation and assumes its size to be buffer_size. If the
- // buffer is too small, a fatal error occurs. No deallocation of the buffer is
- // done upon destruction of the assembler.
- Assembler(const AssemblerOptions& options, void* buffer, int buffer_size);
+ // own buffer. Otherwise it takes ownership of the provided buffer.
+ explicit Assembler(const AssemblerOptions&,
+ std::unique_ptr<AssemblerBuffer> = {});
virtual ~Assembler() {}
// GetCode emits any pending (non-emitted) code and fills the descriptor
@@ -501,6 +378,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// Assembler functions are invoked in between GetCode() calls.
void GetCode(Isolate* isolate, CodeDesc* desc);
+ void FinalizeJumpOptimizationInfo();
+
// Read/Modify the code target in the branch/call instruction at pc.
// The isolate argument is unused (and may be nullptr) when skipping flushing.
inline static Address target_address_at(Address pc, Address constant_pool);
@@ -515,7 +394,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// This sets the branch destination (which is in the instruction on x86).
// This is for calls and branches within generated code.
inline static void deserialization_set_special_target_at(
- Address instruction_payload, Code* code, Address target);
+ Address instruction_payload, Code code, Address target);
// Get the size of the special target encoded at 'instruction_payload'.
inline static int deserialization_special_target_size(
@@ -532,8 +411,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// and the return address
static constexpr int kCallTargetAddressOffset = kPointerSize;
- static constexpr int kCallInstructionLength = 5;
-
// One byte opcode for test al, 0xXX.
static constexpr byte kTestAlByte = 0xA8;
// One byte opcode for nop.
@@ -851,7 +728,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void call(Register reg) { call(Operand(reg)); }
void call(Operand adr);
void call(Handle<Code> code, RelocInfo::Mode rmode);
- void call(CodeStub* stub);
void wasm_call(Address address, RelocInfo::Mode rmode);
// Jumps
@@ -1733,9 +1609,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
return pc_offset() - label->pos();
}
- // Use --code-comments to enable.
- void RecordComment(const char* msg);
-
// Record a deoptimization reason that can be used by a log or cpu profiler.
// Use --trace-deopt to enable.
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
@@ -1762,45 +1635,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
static bool IsNop(Address addr);
int relocation_writer_size() {
- return (buffer_ + buffer_size_) - reloc_info_writer.pos();
+ return (buffer_start_ + buffer_->size()) - reloc_info_writer.pos();
}
// Avoid overflows for displacements etc.
static constexpr int kMaximalBufferSize = 512 * MB;
- byte byte_at(int pos) { return buffer_[pos]; }
- void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
-
- void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
- ConstantPoolEntry::Access access,
- ConstantPoolEntry::Type type) {
- // No embedded constant pool support.
- UNREACHABLE();
- }
-
- // Temporary helper data structures while adding kRootRegister support to ia32
- // builtins. The SupportsRootRegisterScope is intended to mark each builtin
- // and helper that fully supports the root register, i.e. that does not
- // clobber ebx. The AllowExplicitEbxAccessScope marks regions that are allowed
- // to clobber ebx, e.g. when ebx is spilled and restored.
- // TODO(v8:6666): Remove once kRootRegister is fully supported.
- template <bool new_value>
- class SetRootRegisterSupportScope final {
- public:
- explicit SetRootRegisterSupportScope(Assembler* assembler)
- : assembler_(assembler), old_value_(assembler->is_ebx_addressable_) {
- assembler_->is_ebx_addressable_ = new_value;
- }
- ~SetRootRegisterSupportScope() {
- assembler_->is_ebx_addressable_ = old_value_;
- }
-
- private:
- Assembler* assembler_;
- const bool old_value_;
- };
- typedef SetRootRegisterSupportScope<false> SupportsRootRegisterScope;
- typedef SetRootRegisterSupportScope<true> AllowExplicitEbxAccessScope;
+ byte byte_at(int pos) { return buffer_start_[pos]; }
+ void set_byte_at(int pos, byte value) { buffer_start_[pos] = value; }
protected:
void emit_sse_operand(XMMRegister reg, Operand adr);
@@ -1808,18 +1650,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void emit_sse_operand(Register dst, XMMRegister src);
void emit_sse_operand(XMMRegister dst, Register src);
- byte* addr_at(int pos) { return buffer_ + pos; }
-
-#ifdef DEBUG
- // TODO(v8:6666): Remove once kRootRegister is fully supported.
- void AssertIsAddressable(const Register& reg);
- void AssertIsAddressable(const Operand& operand);
-#else
- // An empty inline definition to avoid slowing down release builds.
- void AssertIsAddressable(const Register&) {}
- void AssertIsAddressable(const Operand&) {}
-#endif // DEBUG
- bool is_ebx_addressable_ = true;
+ byte* addr_at(int pos) { return buffer_start_ + pos; }
private:
uint32_t long_at(int pos) {
@@ -1902,6 +1733,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
+ int WriteCodeComments();
+
friend class EnsureSpace;
// Internal reference positions, required for (potential) patching in