offset = -offset;
sign = '-';
}
- STATIC_ASSERT(sizeof(*instr) == 1);
- AppendToOutput("#%c0x%x (addr %p)", sign, offset, instr + offset);
+ AppendToOutput("#%c0x%x (addr %p)", sign, offset,
+ instr->InstructionAtOffset(offset, Instruction::NO_CHECK));
return 13;
}
offset = -offset;
sign = '-';
}
- STATIC_ASSERT(sizeof(*instr) == 1);
- AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, instr + offset);
+ AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset,
+ instr->InstructionAtOffset(offset), Instruction::NO_CHECK);
return 8;
}
Instruction* Instruction::ImmPCOffsetTarget() {
- return this + ImmPCOffset();
+ return InstructionAtOffset(ImmPCOffset());
}
bool Instruction::IsTargetInImmPCOffsetRange(Instruction* target) {
- int offset = target - this;
- return IsValidImmPCOffset(BranchType(), offset);
+ return IsValidImmPCOffset(BranchType(), DistanceTo(target));
}
// ADRP is not supported, so 'this' must point to an ADR instruction.
ASSERT(Mask(PCRelAddressingMask) == ADR);
- Instr imm = Assembler::ImmPCRelAddress(target - this);
+ Instr imm = Assembler::ImmPCRelAddress(DistanceTo(target));
SetInstructionBits(Mask(~ImmPCRel_mask) | imm);
}
void Instruction::SetBranchImmTarget(Instruction* target) {
- ASSERT(((target - this) & 3) == 0);
+ ASSERT(IsAligned(DistanceTo(target), kInstructionSize));
Instr branch_imm = 0;
uint32_t imm_mask = 0;
- int offset = (target - this) >> kInstructionSizeLog2;
+ ptrdiff_t offset = DistanceTo(target) >> kInstructionSizeLog2;
switch (BranchType()) {
case CondBranchType: {
branch_imm = Assembler::ImmCondBranch(offset);
void Instruction::SetImmLLiteral(Instruction* source) {
- ASSERT(((source - this) & 3) == 0);
- int offset = (source - this) >> kLiteralEntrySizeLog2;
+ ASSERT(IsAligned(DistanceTo(source), kInstructionSize));
+ ptrdiff_t offset = DistanceTo(source) >> kLiteralEntrySizeLog2;
Instr imm = Assembler::ImmLLiteral(offset);
Instr mask = ImmLLiteral_mask;
return InstructionBits() & mask;
}
- Instruction* following(int count = 1) {
- return this + count * kInstructionSize;
+ V8_INLINE Instruction* following(int count = 1) {
+ return InstructionAtOffset(count * static_cast<int>(kInstructionSize));
}
- Instruction* preceding(int count = 1) {
- return this - count * kInstructionSize;
+ V8_INLINE Instruction* preceding(int count = 1) {
+ return following(-count);
}
#define DEFINE_GETTER(Name, HighBit, LowBit, Func) \
return reinterpret_cast<uint8_t*>(this) + offset;
}
- Instruction* NextInstruction() {
- return this + kInstructionSize;
- }
+ enum CheckAlignment { NO_CHECK, CHECK_ALIGNMENT };
- Instruction* InstructionAtOffset(int64_t offset) {
- ASSERT(IsAligned(reinterpret_cast<uintptr_t>(this) + offset,
- kInstructionSize));
- return this + offset;
+ V8_INLINE Instruction* InstructionAtOffset(
+ int64_t offset,
+ CheckAlignment check = CHECK_ALIGNMENT) {
+ Address addr = reinterpret_cast<Address>(this) + offset;
+ // The FUZZ_disasm test relies on no check being done.
+ ASSERT(check == NO_CHECK || IsAddressAligned(addr, kInstructionSize));
+ return Cast(addr);
}
- template<typename T> static Instruction* Cast(T src) {
+ template<typename T> V8_INLINE static Instruction* Cast(T src) {
return reinterpret_cast<Instruction*>(src);
}
+ V8_INLINE ptrdiff_t DistanceTo(Instruction* target) {
+ return reinterpret_cast<Address>(target) - reinterpret_cast<Address>(this);
+ }
+
void SetPCRelImmTarget(Instruction* target);
void SetBranchImmTarget(Instruction* target);
reg_ = Register::XRegFromCode(reg_code);
uint64_t smi_check_delta = DeltaBits::decode(payload);
ASSERT(smi_check_delta != 0);
- smi_check_ = inline_data - (smi_check_delta * kInstructionSize);
+ smi_check_ = inline_data->preceding(smi_check_delta);
}
}
}
void Simulator::CheckBreakNext() {
// If the current instruction is a BL, insert a breakpoint just after it.
if (break_on_next_ && pc_->IsBranchAndLinkToRegister()) {
- SetBreakpoint(pc_->NextInstruction());
+ SetBreakpoint(pc_->following());
break_on_next_ = false;
}
}
void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) {
Instruction* end = start->InstructionAtOffset(count * kInstructionSize);
- for (Instruction* pc = start; pc < end; pc = pc->NextInstruction()) {
+ for (Instruction* pc = start; pc < end; pc = pc->following()) {
disassembler_decoder_->Decode(pc);
}
}
void Simulator::VisitUnconditionalBranch(Instruction* instr) {
switch (instr->Mask(UnconditionalBranchMask)) {
case BL:
- set_lr(instr->NextInstruction());
+ set_lr(instr->following());
// Fall through.
case B:
set_pc(instr->ImmPCOffsetTarget());
Instruction* target = reg<Instruction*>(instr->Rn());
switch (instr->Mask(UnconditionalBranchToRegisterMask)) {
case BLR: {
- set_lr(instr->NextInstruction());
+ set_lr(instr->following());
if (instr->Rn() == 31) {
// BLR XZR is used as a guard for the constant pool. We should never hit
// this, but if we do trap to allow debugging.
// Read the arguments encoded inline in the instruction stream.
uint32_t code;
uint32_t parameters;
- char const * message;
- ASSERT(sizeof(*pc_) == 1);
- memcpy(&code, pc_ + kDebugCodeOffset, sizeof(code));
- memcpy(¶meters, pc_ + kDebugParamsOffset, sizeof(parameters));
- message = reinterpret_cast<char const *>(pc_ + kDebugMessageOffset);
+ memcpy(&code,
+ pc_->InstructionAtOffset(kDebugCodeOffset),
+ sizeof(code));
+ memcpy(¶meters,
+ pc_->InstructionAtOffset(kDebugParamsOffset),
+ sizeof(parameters));
+ char const *message =
+ reinterpret_cast<char const*>(
+ pc_->InstructionAtOffset(kDebugMessageOffset));
// Always print something when we hit a debug point that breaks.
// We are going to break, so printing something is not an issue in
// The stop parameters are inlined in the code. Skip them:
// - Skip to the end of the message string.
- pc_ += kDebugMessageOffset + strlen(message) + 1;
- // - Advance to the next aligned location.
- pc_ = AlignUp(pc_, kInstructionSize);
+ size_t size = kDebugMessageOffset + strlen(message) + 1;
+ pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize));
// - Verify that the unreachable marker is present.
ASSERT(pc_->Mask(ExceptionMask) == HLT);
ASSERT(pc_->ImmException() == kImmExceptionIsUnreachable);
// - Skip past the unreachable marker.
- set_pc(pc_->NextInstruction());
+ set_pc(pc_->following());
// Check if the debugger should break.
if (parameters & BREAK) Debug();
} else if (instr->ImmException() == kImmExceptionIsPrintf) {
// Read the argument encoded inline in the instruction stream.
uint32_t type;
- ASSERT(sizeof(*pc_) == 1);
- memcpy(&type, pc_ + kPrintfTypeOffset, sizeof(type));
+ memcpy(&type,
+ pc_->InstructionAtOffset(kPrintfTypeOffset),
+ sizeof(type));
const char* format = reg<const char*>(0);
void increment_pc() {
if (!pc_modified_) {
- pc_ = pc_->NextInstruction();
+ pc_ = pc_->following();
}
pc_modified_ = false;