// -----------------------------------------------------------------------------
-// Implementation of Assembler.
-
-// Instruction encoding bits.
-enum {
- H = 1 << 5, // halfword (or byte)
- S6 = 1 << 6, // signed (or unsigned)
- L = 1 << 20, // load (or store)
- S = 1 << 20, // set condition code (or leave unchanged)
- W = 1 << 21, // writeback base register (or leave unchanged)
- A = 1 << 21, // accumulate in multiply instruction (or not)
- B = 1 << 22, // unsigned byte (or word)
- N = 1 << 22, // long (or short)
- U = 1 << 23, // positive (or negative) offset/index
- P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing)
- I = 1 << 25, // immediate shifter operand (or not)
-
- B4 = 1 << 4,
- B5 = 1 << 5,
- B6 = 1 << 6,
- B7 = 1 << 7,
- B8 = 1 << 8,
- B9 = 1 << 9,
- B12 = 1 << 12,
- B16 = 1 << 16,
- B18 = 1 << 18,
- B19 = 1 << 19,
- B20 = 1 << 20,
- B21 = 1 << 21,
- B22 = 1 << 22,
- B23 = 1 << 23,
- B24 = 1 << 24,
- B25 = 1 << 25,
- B26 = 1 << 26,
- B27 = 1 << 27,
-
- // Instruction bit masks.
- RdMask = 15 << 12, // in str instruction
- CondMask = 15 << 28,
- CoprocessorMask = 15 << 8,
- OpCodeMask = 15 << 21, // in data-processing instructions
- Imm24Mask = (1 << 24) - 1,
- Off12Mask = (1 << 12) - 1,
- // Reserved condition.
- nv = 15 << 28
-};
-
+// Specific instructions, constants, and masks.
// add(sp, sp, 4) instruction (aka Pop())
-static const Instr kPopInstruction =
- al | 4 * B21 | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12;
+const Instr kPopInstruction =
+ al | PostIndex | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12;
// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
// register r is not encoded.
-static const Instr kPushRegPattern =
+const Instr kPushRegPattern =
al | B26 | 4 | NegPreIndex | sp.code() * B16;
// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
// register r is not encoded.
-static const Instr kPopRegPattern =
+const Instr kPopRegPattern =
al | B26 | L | 4 | PostIndex | sp.code() * B16;
// mov lr, pc
-const Instr kMovLrPc = al | 13*B21 | pc.code() | lr.code() * B12;
+const Instr kMovLrPc = al | MOV | pc.code() | lr.code() * B12;
// ldr rd, [pc, #offset]
-const Instr kLdrPCMask = CondMask | 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPCMask = kCondMask | 15 * B24 | 7 * B20 | 15 * B16;
const Instr kLdrPCPattern = al | 5 * B24 | L | pc.code() * B16;
// blxcc rm
const Instr kBlxRegMask =
15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
const Instr kBlxRegPattern =
- B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | 3 * B4;
+ B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | BLX;
const Instr kMovMvnMask = 0x6d * B21 | 0xf * B16;
const Instr kMovMvnPattern = 0xd * B21;
const Instr kMovMvnFlip = B22;
const Instr kCmpCmnMask = 0xdd * B20 | 0xf * B12;
const Instr kCmpCmnPattern = 0x15 * B20;
const Instr kCmpCmnFlip = B21;
-const Instr kALUMask = 0x6f * B21;
-const Instr kAddPattern = 0x4 * B21;
-const Instr kSubPattern = 0x2 * B21;
-const Instr kBicPattern = 0xe * B21;
-const Instr kAndPattern = 0x0 * B21;
const Instr kAddSubFlip = 0x6 * B21;
const Instr kAndBicFlip = 0xe * B21;
// A mask for the Rd register for push, pop, ldr, str instructions.
-const Instr kRdMask = 0x0000f000;
-static const int kRdShift = 12;
-static const Instr kLdrRegFpOffsetPattern =
+const Instr kLdrRegFpOffsetPattern =
al | B26 | L | Offset | fp.code() * B16;
-static const Instr kStrRegFpOffsetPattern =
+const Instr kStrRegFpOffsetPattern =
al | B26 | Offset | fp.code() * B16;
-static const Instr kLdrRegFpNegOffsetPattern =
+const Instr kLdrRegFpNegOffsetPattern =
al | B26 | L | NegOffset | fp.code() * B16;
-static const Instr kStrRegFpNegOffsetPattern =
+const Instr kStrRegFpNegOffsetPattern =
al | B26 | NegOffset | fp.code() * B16;
-static const Instr kLdrStrInstrTypeMask = 0xffff0000;
-static const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
-static const Instr kLdrStrOffsetMask = 0x00000fff;
+const Instr kLdrStrInstrTypeMask = 0xffff0000;
+const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
+const Instr kLdrStrOffsetMask = 0x00000fff;
+
// Spare buffer.
static const int kMinimalBufferSize = 4*KB;
static byte* spare_buffer_ = NULL;
+
Assembler::Assembler(void* buffer, int buffer_size)
: positions_recorder_(this),
allow_peephole_optimization_(false) {
ASSERT(IsBranch(instr));
// Take the jump offset in the lower 24 bits, sign extend it and multiply it
// with 4 to get the offset in bytes.
- return ((instr & Imm24Mask) << 8) >> 6;
+ return ((instr & kImm24Mask) << 8) >> 6;
}
int Assembler::GetLdrRegisterImmediateOffset(Instr instr) {
ASSERT(IsLdrRegisterImmediate(instr));
bool positive = (instr & B23) == B23;
- int offset = instr & Off12Mask; // Zero extended offset.
+ int offset = instr & kOff12Mask; // Zero extended offset.
return positive ? offset : -offset;
}
// Set bit indicating whether the offset should be added.
instr = (instr & ~B23) | (positive ? B23 : 0);
// Set the actual offset.
- return (instr & ~Off12Mask) | offset;
+ return (instr & ~kOff12Mask) | offset;
}
// Set bit indicating whether the offset should be added.
instr = (instr & ~B23) | (positive ? B23 : 0);
// Set the actual offset.
- return (instr & ~Off12Mask) | offset;
+ return (instr & ~kOff12Mask) | offset;
}
ASSERT(offset >= 0);
ASSERT(is_uint12(offset));
// Set the offset.
- return (instr & ~Off12Mask) | offset;
+ return (instr & ~kOff12Mask) | offset;
}
Register Assembler::GetRd(Instr instr) {
Register reg;
- reg.code_ = ((instr & kRdMask) >> kRdShift);
+ reg.code_ = Instruction::RdValue(instr);
return reg;
}
bool Assembler::IsLdrPcImmediateOffset(Instr instr) {
// Check the instruction is indeed a
// ldr<cond> <Rd>, [pc +/- offset_12].
- return (instr & 0x0f7f0000) == 0x051f0000;
+ return (instr & (kLdrPCMask & ~kCondMask)) == 0x051f0000;
}
int Assembler::target_at(int pos) {
Instr instr = instr_at(pos);
- if ((instr & ~Imm24Mask) == 0) {
+ if ((instr & ~kImm24Mask) == 0) {
// Emitted label constant, not part of a branch.
return instr - (Code::kHeaderSize - kHeapObjectTag);
}
ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
- int imm26 = ((instr & Imm24Mask) << 8) >> 6;
- if ((instr & CondMask) == nv && (instr & B24) != 0) {
+ int imm26 = ((instr & kImm24Mask) << 8) >> 6;
+ if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
+ ((instr & B24) != 0)) {
// blx uses bit 24 to encode bit 2 of imm26
imm26 += 2;
}
void Assembler::target_at_put(int pos, int target_pos) {
Instr instr = instr_at(pos);
- if ((instr & ~Imm24Mask) == 0) {
+ if ((instr & ~kImm24Mask) == 0) {
ASSERT(target_pos == kEndOfChain || target_pos >= 0);
// Emitted label constant, not part of a branch.
// Make label relative to Code* of generated Code object.
}
int imm26 = target_pos - (pos + kPcLoadDelta);
ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
- if ((instr & CondMask) == nv) {
+ if (Instruction::ConditionField(instr) == kSpecialCondition) {
// blx uses bit 24 to encode bit 2 of imm26
ASSERT((imm26 & 1) == 0);
- instr = (instr & ~(B24 | Imm24Mask)) | ((imm26 & 2) >> 1)*B24;
+ instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
} else {
ASSERT((imm26 & 3) == 0);
- instr &= ~Imm24Mask;
+ instr &= ~kImm24Mask;
}
int imm24 = imm26 >> 2;
ASSERT(is_int24(imm24));
- instr_at_put(pos, instr | (imm24 & Imm24Mask));
+ instr_at_put(pos, instr | (imm24 & kImm24Mask));
}
while (l.is_linked()) {
PrintF("@ %d ", l.pos());
Instr instr = instr_at(l.pos());
- if ((instr & ~Imm24Mask) == 0) {
+ if ((instr & ~kImm24Mask) == 0) {
PrintF("value\n");
} else {
ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx
- int cond = instr & CondMask;
+ Condition cond = Instruction::ConditionField(instr);
const char* b;
const char* c;
- if (cond == nv) {
+ if (cond == kSpecialCondition) {
b = "blx";
c = "";
} else {
}
} else {
Instr alu_insn = (*instr & kALUMask);
- if (alu_insn == kAddPattern ||
- alu_insn == kSubPattern) {
+ if (alu_insn == ADD ||
+ alu_insn == SUB) {
if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) {
*instr ^= kAddSubFlip;
return true;
}
- } else if (alu_insn == kAndPattern ||
- alu_insn == kBicPattern) {
+ } else if (alu_insn == AND ||
+ alu_insn == BIC) {
if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
*instr ^= kAndBicFlip;
return true;
Register rd,
const Operand& x) {
CheckBuffer();
- ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0);
+ ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
if (!x.rm_.is_valid()) {
// Immediate.
uint32_t rotate_imm;
// However, if the original instruction is a 'mov rd, x' (not setting the
// condition code), then replace it with a 'ldr rd, [pc]'.
CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
- Condition cond = static_cast<Condition>(instr & CondMask);
- if ((instr & ~CondMask) == 13*B21) { // mov, S not set
+ Condition cond = Instruction::ConditionField(instr);
+ if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
if (x.must_use_constant_pool() || !CpuFeatures::IsSupported(ARMv7)) {
RecordRelocInfo(x.rmode_, x.imm32_);
ldr(rd, MemOperand(pc, 0), cond);
void Assembler::addrmod2(Instr instr, Register rd, const MemOperand& x) {
- ASSERT((instr & ~(CondMask | B | L)) == B26);
+ ASSERT((instr & ~(kCondMask | B | L)) == B26);
int am = x.am_;
if (!x.rm_.is_valid()) {
// Immediate offset.
// Immediate offset cannot be encoded, load it first to register ip
// rn (and rd in a load) should never be ip, or will be trashed.
ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
- mov(ip, Operand(x.offset_), LeaveCC,
- static_cast<Condition>(instr & CondMask));
+ mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
addrmod2(instr, rd, MemOperand(x.rn_, ip, x.am_));
return;
}
void Assembler::addrmod3(Instr instr, Register rd, const MemOperand& x) {
- ASSERT((instr & ~(CondMask | L | S6 | H)) == (B4 | B7));
+ ASSERT((instr & ~(kCondMask | L | S6 | H)) == (B4 | B7));
ASSERT(x.rn_.is_valid());
int am = x.am_;
if (!x.rm_.is_valid()) {
// Immediate offset cannot be encoded, load it first to register ip
// rn (and rd in a load) should never be ip, or will be trashed.
ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
- mov(ip, Operand(x.offset_), LeaveCC,
- static_cast<Condition>(instr & CondMask));
+ mov(ip, Operand(x.offset_), LeaveCC, Instruction::ConditionField(instr));
addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
return;
}
// rn (and rd in a load) should never be ip, or will be trashed.
ASSERT(!x.rn_.is(ip) && ((instr & L) == L || !rd.is(ip)));
mov(ip, Operand(x.rm_, x.shift_op_, x.shift_imm_), LeaveCC,
- static_cast<Condition>(instr & CondMask));
+ Instruction::ConditionField(instr));
addrmod3(instr, rd, MemOperand(x.rn_, ip, x.am_));
return;
} else {
void Assembler::addrmod4(Instr instr, Register rn, RegList rl) {
- ASSERT((instr & ~(CondMask | P | U | W | L)) == B27);
+ ASSERT((instr & ~(kCondMask | P | U | W | L)) == B27);
ASSERT(rl != 0);
ASSERT(!rn.is(pc));
emit(instr | rn.code()*B16 | rl);
void Assembler::addrmod5(Instr instr, CRegister crd, const MemOperand& x) {
// Unindexed addressing is not encoded by this function.
ASSERT_EQ((B27 | B26),
- (instr & ~(CondMask | CoprocessorMask | P | U | N | W | L)));
+ (instr & ~(kCondMask | kCoprocessorMask | P | U | N | W | L)));
ASSERT(x.rn_.is_valid() && !x.rm_.is_valid());
int am = x.am_;
int offset_8 = x.offset_;
ASSERT((branch_offset & 3) == 0);
int imm24 = branch_offset >> 2;
ASSERT(is_int24(imm24));
- emit(cond | B27 | B25 | (imm24 & Imm24Mask));
+ emit(cond | B27 | B25 | (imm24 & kImm24Mask));
if (cond == al) {
// Dead code is a good location to emit the constant pool.
ASSERT((branch_offset & 3) == 0);
int imm24 = branch_offset >> 2;
ASSERT(is_int24(imm24));
- emit(cond | B27 | B25 | B24 | (imm24 & Imm24Mask));
+ emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
}
int h = ((branch_offset & 2) >> 1)*B24;
int imm24 = branch_offset >> 2;
ASSERT(is_int24(imm24));
- emit(nv | B27 | B25 | h | (imm24 & Imm24Mask));
+ emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
}
void Assembler::blx(Register target, Condition cond) { // v5 and above
positions_recorder()->WriteRecordedPositions();
ASSERT(!target.is(pc));
- emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | 3*B4 | target.code());
+ emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
}
void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t
positions_recorder()->WriteRecordedPositions();
ASSERT(!target.is(pc)); // use of pc is actually allowed, but discouraged
- emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | B4 | target.code());
+ emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
}
void Assembler::and_(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 0*B21 | s, src1, dst, src2);
+ addrmod1(cond | AND | s, src1, dst, src2);
}
void Assembler::eor(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 1*B21 | s, src1, dst, src2);
+ addrmod1(cond | EOR | s, src1, dst, src2);
}
void Assembler::sub(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 2*B21 | s, src1, dst, src2);
+ addrmod1(cond | SUB | s, src1, dst, src2);
}
void Assembler::rsb(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 3*B21 | s, src1, dst, src2);
+ addrmod1(cond | RSB | s, src1, dst, src2);
}
void Assembler::add(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 4*B21 | s, src1, dst, src2);
+ addrmod1(cond | ADD | s, src1, dst, src2);
// Eliminate pattern: push(r), pop()
// str(src, MemOperand(sp, 4, NegPreIndex), al);
if (can_peephole_optimize(2) &&
// Pattern.
instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
- (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) {
+ (instr_at(pc_ - 2 * kInstrSize) & ~kRdMask) == kPushRegPattern) {
pc_ -= 2 * kInstrSize;
if (FLAG_print_peephole_optimization) {
PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
void Assembler::adc(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 5*B21 | s, src1, dst, src2);
+ addrmod1(cond | ADC | s, src1, dst, src2);
}
void Assembler::sbc(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 6*B21 | s, src1, dst, src2);
+ addrmod1(cond | SBC | s, src1, dst, src2);
}
void Assembler::rsc(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 7*B21 | s, src1, dst, src2);
+ addrmod1(cond | RSC | s, src1, dst, src2);
}
void Assembler::tst(Register src1, const Operand& src2, Condition cond) {
- addrmod1(cond | 8*B21 | S, src1, r0, src2);
+ addrmod1(cond | TST | S, src1, r0, src2);
}
void Assembler::teq(Register src1, const Operand& src2, Condition cond) {
- addrmod1(cond | 9*B21 | S, src1, r0, src2);
+ addrmod1(cond | TEQ | S, src1, r0, src2);
}
void Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
- addrmod1(cond | 10*B21 | S, src1, r0, src2);
+ addrmod1(cond | CMP | S, src1, r0, src2);
}
void Assembler::cmn(Register src1, const Operand& src2, Condition cond) {
- addrmod1(cond | 11*B21 | S, src1, r0, src2);
+ addrmod1(cond | CMN | S, src1, r0, src2);
}
void Assembler::orr(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 12*B21 | s, src1, dst, src2);
+ addrmod1(cond | ORR | s, src1, dst, src2);
}
// the mov instruction. They must be generated using nop(int/NopMarkerTypes)
// or MarkCode(int/NopMarkerTypes) pseudo instructions.
ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
- addrmod1(cond | 13*B21 | s, r0, dst, src);
+ addrmod1(cond | MOV | s, r0, dst, src);
}
void Assembler::bic(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
- addrmod1(cond | 14*B21 | s, src1, dst, src2);
+ addrmod1(cond | BIC | s, src1, dst, src2);
}
void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
- addrmod1(cond | 15*B21 | s, r0, dst, src);
+ addrmod1(cond | MVN | s, r0, dst, src);
}
// v5 and above.
ASSERT(!dst.is(pc) && !src.is(pc));
emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
- 15*B8 | B4 | src.code());
+ 15*B8 | CLZ | src.code());
}
Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
if (IsPush(push_instr) && IsPop(pop_instr)) {
- if ((pop_instr & kRdMask) != (push_instr & kRdMask)) {
+ if (Instruction::RdValue(pop_instr) != Instruction::RdValue(push_instr)) {
// For consecutive push and pop on different registers,
// we delete both the push & pop and insert a register move.
// push ry, pop rx --> mov rx, ry
IsPop(mem_read_instr)) {
if ((IsLdrRegFpOffset(ldr_instr) ||
IsLdrRegFpNegOffset(ldr_instr))) {
- if ((mem_write_instr & kRdMask) ==
- (mem_read_instr & kRdMask)) {
+ if (Instruction::RdValue(mem_write_instr) ==
+ Instruction::RdValue(mem_read_instr)) {
// Pattern: push & pop from/to same register,
// with a fp+offset ldr in between
//
// else
// ldr rz, [fp, #-24]
- if ((mem_write_instr & kRdMask) == (ldr_instr & kRdMask)) {
+ if (Instruction::RdValue(mem_write_instr) ==
+ Instruction::RdValue(ldr_instr)) {
pc_ -= 3 * kInstrSize;
} else {
pc_ -= 3 * kInstrSize;
// ldr rz, [fp, #-24]
Register reg_pushed, reg_popped;
- if ((mem_read_instr & kRdMask) == (ldr_instr & kRdMask)) {
+ if (Instruction::RdValue(mem_read_instr) ==
+ Instruction::RdValue(ldr_instr)) {
reg_pushed = GetRd(mem_write_instr);
reg_popped = GetRd(mem_read_instr);
pc_ -= 3 * kInstrSize;
mov(reg_popped, reg_pushed);
- } else if ((mem_write_instr & kRdMask)
- != (ldr_instr & kRdMask)) {
+ } else if (Instruction::RdValue(mem_write_instr) !=
+ Instruction::RdValue(ldr_instr)) {
reg_pushed = GetRd(mem_write_instr);
reg_popped = GetRd(mem_read_instr);
pc_ -= 3 * kInstrSize;
emit(ldr_instr);
mov(reg_popped, reg_pushed);
- } else if (((mem_read_instr & kRdMask)
- != (ldr_instr & kRdMask)) ||
- ((mem_write_instr & kRdMask)
- == (ldr_instr & kRdMask)) ) {
+ } else if ((Instruction::RdValue(mem_read_instr) !=
+ Instruction::RdValue(ldr_instr)) ||
+ (Instruction::RdValue(mem_write_instr) ==
+ Instruction::RdValue(ldr_instr))) {
reg_pushed = GetRd(mem_write_instr);
reg_popped = GetRd(mem_read_instr);
pc_ -= 3 * kInstrSize;
// enabling/disabling and a counter feature. See simulator-arm.h .
void Assembler::stop(const char* msg, Condition cond, int32_t code) {
#ifndef __arm__
- // See constants-arm.h SoftwareInterruptCodes. Unluckily the Assembler and
- // Simulator do not share constants declaration.
ASSERT(code >= kDefaultStopCode);
- static const uint32_t kStopInterruptCode = 1 << 23;
- static const uint32_t kMaxStopCode = kStopInterruptCode - 1;
// The Simulator will handle the stop instruction and get the message address.
// It expects to find the address just after the svc instruction.
BlockConstPoolFor(2);
if (code >= 0) {
- svc(kStopInterruptCode + code, cond);
+ svc(kStopCode + code, cond);
} else {
- svc(kStopInterruptCode + kMaxStopCode, cond);
+ svc(kStopCode + kMaxStopCode, cond);
}
emit(reinterpret_cast<Instr>(msg));
#else // def __arm__
void Assembler::bkpt(uint32_t imm16) { // v5 and above
ASSERT(is_uint16(imm16));
- emit(al | B24 | B21 | (imm16 >> 4)*B8 | 7*B4 | (imm16 & 0xf));
+ emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
}
CRegister crn,
CRegister crm,
int opcode_2) { // v5 and above
- cdp(coproc, opcode_1, crd, crn, crm, opcode_2, static_cast<Condition>(nv));
+ cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition);
}
CRegister crn,
CRegister crm,
int opcode_2) { // v5 and above
- mcr(coproc, opcode_1, rd, crn, crm, opcode_2, static_cast<Condition>(nv));
+ mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
}
CRegister crn,
CRegister crm,
int opcode_2) { // v5 and above
- mrc(coproc, opcode_1, rd, crn, crm, opcode_2, static_cast<Condition>(nv));
+ mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition);
}
CRegister crd,
const MemOperand& src,
LFlag l) { // v5 and above
- ldc(coproc, crd, src, l, static_cast<Condition>(nv));
+ ldc(coproc, crd, src, l, kSpecialCondition);
}
Register rn,
int option,
LFlag l) { // v5 and above
- ldc(coproc, crd, rn, option, l, static_cast<Condition>(nv));
+ ldc(coproc, crd, rn, option, l, kSpecialCondition);
}
coproc, CRegister crd,
const MemOperand& dst,
LFlag l) { // v5 and above
- stc(coproc, crd, dst, l, static_cast<Condition>(nv));
+ stc(coproc, crd, dst, l, kSpecialCondition);
}
Register rn,
int option,
LFlag l) { // v5 and above
- stc(coproc, crd, rn, option, l, static_cast<Condition>(nv));
+ stc(coproc, crd, rn, option, l, kSpecialCondition);
}
// Instruction to patch must be a ldr/str [pc, #offset].
// P and U set, B and W clear, Rn == pc, offset12 still 0.
- ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) ==
+ ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | kOff12Mask)) ==
(2*B25 | P | U | pc.code()*B16));
int delta = pc_ - rinfo.pc() - 8;
ASSERT(delta >= -4); // instr could be ldr pc, [pc, #-4] followed by targ32
#define V8_ARM_ASSEMBLER_ARM_H_
#include <stdio.h>
#include "assembler.h"
+#include "constants-arm.h"
#include "serialize.h"
namespace v8 {
const DwVfpRegister d14 = { 14 };
const DwVfpRegister d15 = { 15 };
-// VFP FPSCR constants.
-static const uint32_t kVFPNConditionFlagBit = 1 << 31;
-static const uint32_t kVFPZConditionFlagBit = 1 << 30;
-static const uint32_t kVFPCConditionFlagBit = 1 << 29;
-static const uint32_t kVFPVConditionFlagBit = 1 << 28;
-
-static const uint32_t kVFPFlushToZeroMask = 1 << 24;
-
-static const uint32_t kVFPRoundingModeMask = 3 << 22;
-static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22;
-
-static const uint32_t kVFPExceptionMask = 0xf;
// Coprocessor register
struct CRegister {
};
-// Condition field in instructions.
-enum Condition {
- // any value < 0 is considered no_condition
- no_condition = -1,
-
- eq = 0 << 28, // Z set equal.
- ne = 1 << 28, // Z clear not equal.
- nz = 1 << 28, // Z clear not zero.
- cs = 2 << 28, // C set carry set.
- hs = 2 << 28, // C set unsigned higher or same.
- cc = 3 << 28, // C clear carry clear.
- lo = 3 << 28, // C clear unsigned lower.
- mi = 4 << 28, // N set negative.
- pl = 5 << 28, // N clear positive or zero.
- vs = 6 << 28, // V set overflow.
- vc = 7 << 28, // V clear no overflow.
- hi = 8 << 28, // C set, Z clear unsigned higher.
- ls = 9 << 28, // C clear or Z set unsigned lower or same.
- ge = 10 << 28, // N == V greater or equal.
- lt = 11 << 28, // N != V less than.
- gt = 12 << 28, // Z clear, N == V greater than.
- le = 13 << 28, // Z set or N != V less then or equal
- al = 14 << 28 // always.
-};
-
-
-// Returns the equivalent of !cc.
-inline Condition NegateCondition(Condition cc) {
- ASSERT(cc != al);
- return static_cast<Condition>(cc ^ ne);
-}
-
-
-// Corresponds to transposing the operands of a comparison.
-inline Condition ReverseCondition(Condition cc) {
- switch (cc) {
- case lo:
- return hi;
- case hi:
- return lo;
- case hs:
- return ls;
- case ls:
- return hs;
- case lt:
- return gt;
- case gt:
- return lt;
- case ge:
- return le;
- case le:
- return ge;
- default:
- return cc;
- };
-}
-
-
-// Branch hints are not used on the ARM. They are defined so that they can
-// appear in shared function signatures, but will be ignored in ARM
-// implementations.
-enum Hint { no_hint };
-
-// Hints are not used on the arm. Negating is trivial.
-inline Hint NegateHint(Hint ignored) { return no_hint; }
-
-
-// -----------------------------------------------------------------------------
-// Addressing modes and instruction variants
-
-// Shifter operand shift operation
-enum ShiftOp {
- LSL = 0 << 5,
- LSR = 1 << 5,
- ASR = 2 << 5,
- ROR = 3 << 5,
- RRX = -1
-};
-
-
-// Condition code updating mode
-enum SBit {
- SetCC = 1 << 20, // set condition code
- LeaveCC = 0 << 20 // leave condition code unchanged
-};
-
-
-// Status register selection
-enum SRegister {
- CPSR = 0 << 22,
- SPSR = 1 << 22
-};
-
-
-// Status register fields
-enum SRegisterField {
- CPSR_c = CPSR | 1 << 16,
- CPSR_x = CPSR | 1 << 17,
- CPSR_s = CPSR | 1 << 18,
- CPSR_f = CPSR | 1 << 19,
- SPSR_c = SPSR | 1 << 16,
- SPSR_x = SPSR | 1 << 17,
- SPSR_s = SPSR | 1 << 18,
- SPSR_f = SPSR | 1 << 19
-};
-
-// Status register field mask (or'ed SRegisterField enum values)
-typedef uint32_t SRegisterFieldMask;
-
-
-// Memory operand addressing mode
-enum AddrMode {
- // bit encoding P U W
- Offset = (8|4|0) << 21, // offset (without writeback to base)
- PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback
- PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback
- NegOffset = (8|0|0) << 21, // negative offset (without writeback to base)
- NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback
- NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback
-};
-
-
-// Load/store multiple addressing mode
-enum BlockAddrMode {
- // bit encoding P U W
- da = (0|0|0) << 21, // decrement after
- ia = (0|4|0) << 21, // increment after
- db = (8|0|0) << 21, // decrement before
- ib = (8|4|0) << 21, // increment before
- da_w = (0|0|1) << 21, // decrement after with writeback to base
- ia_w = (0|4|1) << 21, // increment after with writeback to base
- db_w = (8|0|1) << 21, // decrement before with writeback to base
- ib_w = (8|4|1) << 21 // increment before with writeback to base
-};
-
-
-// Coprocessor load/store operand size
-enum LFlag {
- Long = 1 << 22, // long load/store coprocessor
- Short = 0 << 22 // short load/store coprocessor
-};
-
-
// -----------------------------------------------------------------------------
// Machine instruction Operands
};
-typedef int32_t Instr;
-
-
extern const Instr kMovLrPc;
extern const Instr kLdrPCMask;
extern const Instr kLdrPCPattern;
extern const Instr kCmpCmnMask;
extern const Instr kCmpCmnPattern;
extern const Instr kCmpCmnFlip;
-
-extern const Instr kALUMask;
-extern const Instr kAddPattern;
-extern const Instr kSubPattern;
-extern const Instr kAndPattern;
-extern const Instr kBicPattern;
extern const Instr kAddSubFlip;
extern const Instr kAndBicFlip;
+
+
class Assembler : public Malloced {
public:
// Create an assembler. Instructions and relocation information are emitted
void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
// Exception-generating instructions and debugging support
- static const int kDefaultStopCode = -1;
void stop(const char* msg,
Condition cond = al,
int32_t code = kDefaultStopCode);
// Check whether an empty sized array is requested.
__ tst(array_size, array_size);
- __ b(nz, ¬_empty);
+ __ b(ne, ¬_empty);
// If an empty array is requested allocate a small elements array anyway. This
// keeps the code below free of special casing for the empty array.
__ mov(r2, Operand(debug_step_in_fp));
__ ldr(r2, MemOperand(r2));
__ tst(r2, r2);
- __ b(nz, &rt_call);
+ __ b(ne, &rt_call);
#endif
// Load the initial map and verify that it is in fact a map.
static void EmitIdenticalObjectComparison(MacroAssembler* masm,
Label* slow,
- Condition cc,
+ Condition cond,
bool never_nan_nan);
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
Register lhs,
Label* lhs_not_nan,
Label* slow,
bool strict);
-static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc);
+static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cond);
static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
Register lhs,
Register rhs);
// for "identity and not NaN".
static void EmitIdenticalObjectComparison(MacroAssembler* masm,
Label* slow,
- Condition cc,
+ Condition cond,
bool never_nan_nan) {
Label not_identical;
Label heap_number, return_equal;
// The two objects are identical. If we know that one of them isn't NaN then
// we now know they test equal.
- if (cc != eq || !never_nan_nan) {
+ if (cond != eq || !never_nan_nan) {
// Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
// so we do the second best thing - test it ourselves.
// They are both equal and they are not both Smis so both of them are not
// Smis. If it's not a heap number, then return equal.
- if (cc == lt || cc == gt) {
+ if (cond == lt || cond == gt) {
__ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE);
__ b(ge, slow);
} else {
__ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
__ b(eq, &heap_number);
// Comparing JS objects with <=, >= is complicated.
- if (cc != eq) {
+ if (cond != eq) {
__ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
__ b(ge, slow);
// Normally here we fall through to return_equal, but undefined is
// special: (undefined == undefined) == true, but
// (undefined <= undefined) == false! See ECMAScript 11.8.5.
- if (cc == le || cc == ge) {
+ if (cond == le || cond == ge) {
__ cmp(r4, Operand(ODDBALL_TYPE));
__ b(ne, &return_equal);
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
__ cmp(r0, r2);
__ b(ne, &return_equal);
- if (cc == le) {
+ if (cond == le) {
// undefined <= undefined should fail.
__ mov(r0, Operand(GREATER));
} else {
}
__ bind(&return_equal);
- if (cc == lt) {
+ if (cond == lt) {
__ mov(r0, Operand(GREATER)); // Things aren't less than themselves.
- } else if (cc == gt) {
+ } else if (cond == gt) {
__ mov(r0, Operand(LESS)); // Things aren't greater than themselves.
} else {
__ mov(r0, Operand(EQUAL)); // Things are <=, >=, ==, === themselves.
}
__ Ret();
- if (cc != eq || !never_nan_nan) {
+ if (cond != eq || !never_nan_nan) {
// For less and greater we don't have to check for NaN since the result of
// x < x is false regardless. For the others here is some code to check
// for NaN.
- if (cc != lt && cc != gt) {
+ if (cond != lt && cond != gt) {
__ bind(&heap_number);
// It is a heap number, so return non-equal if it's NaN and equal if it's
// not NaN.
// if all bits in mantissa are zero (it's an Infinity) and non-zero if
// not (it's a NaN). For <= and >= we need to load r0 with the failing
// value if it's a NaN.
- if (cc != eq) {
+ if (cond != eq) {
// All-zero means Infinity means equal.
__ Ret(eq);
- if (cc == le) {
+ if (cond == le) {
__ mov(r0, Operand(GREATER)); // NaN <= NaN should fail.
} else {
__ mov(r0, Operand(LESS)); // NaN >= NaN should fail.
}
-void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cc) {
+void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cond) {
bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
Register rhs_exponent = exp_first ? r0 : r1;
Register lhs_exponent = exp_first ? r2 : r3;
__ bind(&one_is_nan);
// NaN comparisons always fail.
// Load whatever we need in r0 to make the comparison fail.
- if (cc == lt || cc == le) {
+ if (cond == lt || cond == le) {
__ mov(r0, Operand(GREATER));
} else {
__ mov(r0, Operand(LESS));
// See comment at call site.
-static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) {
+static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm,
+ Condition cond) {
bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
Register rhs_exponent = exp_first ? r0 : r1;
Register lhs_exponent = exp_first ? r2 : r3;
Register lhs_mantissa = exp_first ? r3 : r2;
// r0, r1, r2, r3 have the two doubles. Neither is a NaN.
- if (cc == eq) {
+ if (cond == eq) {
// Doubles are not equal unless they have the same bit pattern.
// Exception: 0 and -0.
__ cmp(rhs_mantissa, Operand(lhs_mantissa));
} else if (FLAG_debug_code) {
__ orr(r2, r1, r0);
__ tst(r2, Operand(kSmiTagMask));
- __ Assert(nz, "CompareStub: unexpected smi operands.");
+ __ Assert(ne, "CompareStub: unexpected smi operands.");
}
// NOTICE! This code is only reached after a smi-fast-case check, so
__ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset));
if (FLAG_debug_code) {
__ tst(regexp_data, Operand(kSmiTagMask));
- __ Check(nz, "Unexpected type for RegExp data, FixedArray expected");
+ __ Check(ne, "Unexpected type for RegExp data, FixedArray expected");
__ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE);
__ Check(eq, "Unexpected type for RegExp data, FixedArray expected");
}
// Is first part a flat string?
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(r0, Operand(kStringRepresentationMask));
- __ b(nz, &runtime);
+ __ b(ne, &runtime);
__ bind(&seq_string);
// subject: Subject string
// If the first cons component is also non-flat, then go to runtime.
STATIC_ASSERT(kSeqStringTag == 0);
__ tst(result_, Operand(kStringRepresentationMask));
- __ b(nz, &call_runtime_);
+ __ b(ne, &call_runtime_);
// Check for 1-byte or 2-byte string.
__ bind(&flat_string);
STATIC_ASSERT(kAsciiStringTag != 0);
__ tst(result_, Operand(kStringEncodingMask));
- __ b(nz, &ascii_string);
+ __ b(ne, &ascii_string);
// 2-byte string.
// Load the 2-byte character code into the result register. We can
__ tst(code_,
Operand(kSmiTagMask |
((~String::kMaxAsciiCharCode) << kSmiTagSize)));
- __ b(nz, &slow_case_);
+ __ b(ne, &slow_case_);
__ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
// At this point code register contains smi tagged ascii char code.
__ add(hash, hash, Operand(hash, LSL, 15), SetCC);
// if (hash == 0) hash = 27;
- __ mov(hash, Operand(27), LeaveCC, nz);
+ __ mov(hash, Operand(27), LeaveCC, ne);
}
// Platform-specific inline functions.
void DeferredCode::Jump() { __ jmp(&entry_label_); }
-void DeferredCode::Branch(Condition cc) { __ b(cc, &entry_label_); }
+void DeferredCode::Branch(Condition cond) { __ b(cond, &entry_label_); }
#undef __
}
-void CodeGenerator::Comparison(Condition cc,
+void CodeGenerator::Comparison(Condition cond,
Expression* left,
Expression* right,
bool strict) {
// result : cc register
// Strict only makes sense for equality comparisons.
- ASSERT(!strict || cc == eq);
+ ASSERT(!strict || cond == eq);
Register lhs;
Register rhs;
// We load the top two stack positions into registers chosen by the virtual
// frame. This should keep the register shuffling to a minimum.
// Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
- if (cc == gt || cc == le) {
- cc = ReverseCondition(cc);
+ if (cond == gt || cond == le) {
+ cond = ReverseCondition(cond);
lhs_is_smi = frame_->KnownSmiAt(0);
rhs_is_smi = frame_->KnownSmiAt(1);
lhs = frame_->PopToRegister();
// Perform non-smi comparison by stub.
// CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0.
// We call with 0 args because there are 0 on the stack.
- CompareStub stub(cc, strict, NO_SMI_COMPARE_IN_STUB, lhs, rhs);
+ CompareStub stub(cond, strict, NO_SMI_COMPARE_IN_STUB, lhs, rhs);
frame_->CallStub(&stub, 0);
__ cmp(r0, Operand(0, RelocInfo::NONE));
exit.Jump();
__ cmp(lhs, Operand(rhs));
exit.Bind();
- cc_reg_ = cc;
+ cc_reg_ = cond;
}
void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
ASSERT(has_cc());
- Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_);
- target->Branch(cc);
+ Condition cond = if_true ? cc_reg_ : NegateCondition(cc_reg_);
+ target->Branch(cond);
cc_reg_ = al;
}
deferred->Branch(lt);
__ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset));
__ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask));
- deferred->Branch(nz);
+ deferred->Branch(ne);
// Check the object's elements are in fast case and writable.
__ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset));
__ mov(tmp2, index1);
__ orr(tmp2, tmp2, index2);
__ tst(tmp2, Operand(kSmiTagMask));
- deferred->Branch(nz);
+ deferred->Branch(ne);
// Check that both indices are valid.
__ ldr(tmp2, FieldMemOperand(object, JSArray::kLengthOffset));
#include "constants-arm.h"
-namespace assembler {
-namespace arm {
+namespace v8 {
+namespace internal {
-namespace v8i = v8::internal;
-
-double Instr::DoubleImmedVmov() const {
+double Instruction::DoubleImmedVmov() const {
// Reconstruct a double from the immediate encoded in the vmov instruction.
//
// instruction: [xxxxxxxx,xxxxabcd,xxxxxxxx,xxxxefgh]
}
-} } // namespace assembler::arm
+} } // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM
#define USE_BLX 1
#endif
-namespace assembler {
-namespace arm {
+namespace v8 {
+namespace internal {
// Number of registers in normal ARM mode.
static const int kNumRegisters = 16;
static const int kPCRegister = 15;
static const int kNoRegister = -1;
+// -----------------------------------------------------------------------------
+// Conditions.
+
// Defines constants and accessor classes to assemble, disassemble and
// simulate ARM instructions.
//
// Constants for specific fields are defined in their respective named enums.
// General constants are in an anonymous enum in class Instr.
-typedef unsigned char byte;
-
// Values for the condition field as defined in section A3.2
enum Condition {
- no_condition = -1,
- EQ = 0, // equal
- NE = 1, // not equal
- CS = 2, // carry set/unsigned higher or same
- CC = 3, // carry clear/unsigned lower
- MI = 4, // minus/negative
- PL = 5, // plus/positive or zero
- VS = 6, // overflow
- VC = 7, // no overflow
- HI = 8, // unsigned higher
- LS = 9, // unsigned lower or same
- GE = 10, // signed greater than or equal
- LT = 11, // signed less than
- GT = 12, // signed greater than
- LE = 13, // signed less than or equal
- AL = 14, // always (unconditional)
- special_condition = 15, // special condition (refer to section A3.2.1)
- max_condition = 16
+ kNoCondition = -1,
+
+ eq = 0 << 28, // Z set Equal.
+ ne = 1 << 28, // Z clear Not equal.
+ cs = 2 << 28, // C set Unsigned higher or same.
+ cc = 3 << 28, // C clear Unsigned lower.
+ mi = 4 << 28, // N set Negative.
+ pl = 5 << 28, // N clear Positive or zero.
+ vs = 6 << 28, // V set Overflow.
+ vc = 7 << 28, // V clear No overflow.
+ hi = 8 << 28, // C set, Z clear Unsigned higher.
+ ls = 9 << 28, // C clear or Z set Unsigned lower or same.
+ ge = 10 << 28, // N == V Greater or equal.
+ lt = 11 << 28, // N != V Less than.
+ gt = 12 << 28, // Z clear, N == V Greater than.
+ le = 13 << 28, // Z set or N != V Less then or equal
+ al = 14 << 28, // Always.
+
+ kSpecialCondition = 15 << 28, // Special condition (refer to section A3.2.1).
+ kNumberOfConditions = 16,
+
+ // Aliases.
+ hs = cs, // C set Unsigned higher or same.
+ lo = cc // C clear Unsigned lower.
};
+inline Condition NegateCondition(Condition cond) {
+ ASSERT(cond != al);
+ return static_cast<Condition>(cond ^ ne);
+}
+
+
+// Corresponds to transposing the operands of a comparison.
+inline Condition ReverseCondition(Condition cond) {
+ switch (cond) {
+ case lo:
+ return hi;
+ case hi:
+ return lo;
+ case hs:
+ return ls;
+ case ls:
+ return hs;
+ case lt:
+ return gt;
+ case gt:
+ return lt;
+ case ge:
+ return le;
+ case le:
+ return ge;
+ default:
+ return cond;
+ };
+}
+
+
+// -----------------------------------------------------------------------------
+// Instructions encoding.
+
+// Instr is merely used by the Assembler to distinguish 32bit integers
+// representing instructions from usual 32 bit values.
+// Instruction objects are pointers to 32bit values, and provide methods to
+// access the various ISA fields.
+typedef int32_t Instr;
+
+
// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
// as defined in section A3.4
enum Opcode {
- no_operand = -1,
- AND = 0, // Logical AND
- EOR = 1, // Logical Exclusive OR
- SUB = 2, // Subtract
- RSB = 3, // Reverse Subtract
- ADD = 4, // Add
- ADC = 5, // Add with Carry
- SBC = 6, // Subtract with Carry
- RSC = 7, // Reverse Subtract with Carry
- TST = 8, // Test
- TEQ = 9, // Test Equivalence
- CMP = 10, // Compare
- CMN = 11, // Compare Negated
- ORR = 12, // Logical (inclusive) OR
- MOV = 13, // Move
- BIC = 14, // Bit Clear
- MVN = 15, // Move Not
- max_operand = 16
+ AND = 0 << 21, // Logical AND.
+ EOR = 1 << 21, // Logical Exclusive OR.
+ SUB = 2 << 21, // Subtract.
+ RSB = 3 << 21, // Reverse Subtract.
+ ADD = 4 << 21, // Add.
+ ADC = 5 << 21, // Add with Carry.
+ SBC = 6 << 21, // Subtract with Carry.
+ RSC = 7 << 21, // Reverse Subtract with Carry.
+ TST = 8 << 21, // Test.
+ TEQ = 9 << 21, // Test Equivalence.
+ CMP = 10 << 21, // Compare.
+ CMN = 11 << 21, // Compare Negated.
+ ORR = 12 << 21, // Logical (inclusive) OR.
+ MOV = 13 << 21, // Move.
+ BIC = 14 << 21, // Bit Clear.
+ MVN = 15 << 21 // Move Not.
};
// The bits for bit 7-4 for some type 0 miscellaneous instructions.
enum MiscInstructionsBits74 {
// With bits 22-21 01.
- BX = 1,
- BXJ = 2,
- BLX = 3,
- BKPT = 7,
+ BX = 1 << 4,
+ BXJ = 2 << 4,
+ BLX = 3 << 4,
+ BKPT = 7 << 4,
// With bits 22-21 11.
- CLZ = 1
+ CLZ = 1 << 4
+};
+
+
+// Instruction encoding bits and masks.
+enum {
+ H = 1 << 5, // Halfword (or byte).
+ S6 = 1 << 6, // Signed (or unsigned).
+ L = 1 << 20, // Load (or store).
+ S = 1 << 20, // Set condition code (or leave unchanged).
+ W = 1 << 21, // Writeback base register (or leave unchanged).
+ A = 1 << 21, // Accumulate in multiply instruction (or not).
+ B = 1 << 22, // Unsigned byte (or word).
+ N = 1 << 22, // Long (or short).
+ U = 1 << 23, // Positive (or negative) offset/index.
+ P = 1 << 24, // Offset/pre-indexed addressing (or post-indexed addressing).
+ I = 1 << 25, // Immediate shifter operand (or not).
+
+ B4 = 1 << 4,
+ B5 = 1 << 5,
+ B6 = 1 << 6,
+ B7 = 1 << 7,
+ B8 = 1 << 8,
+ B9 = 1 << 9,
+ B12 = 1 << 12,
+ B16 = 1 << 16,
+ B18 = 1 << 18,
+ B19 = 1 << 19,
+ B20 = 1 << 20,
+ B21 = 1 << 21,
+ B22 = 1 << 22,
+ B23 = 1 << 23,
+ B24 = 1 << 24,
+ B25 = 1 << 25,
+ B26 = 1 << 26,
+ B27 = 1 << 27,
+ B28 = 1 << 28,
+
+ // Instruction bit masks.
+ kCondMask = 15 << 28,
+ kALUMask = 0x6f << 21,
+ kRdMask = 15 << 12, // In str instruction.
+ kCoprocessorMask = 15 << 8,
+ kOpCodeMask = 15 << 21, // In data-processing instructions.
+ kImm24Mask = (1 << 24) - 1,
+ kOff12Mask = (1 << 12) - 1
+};
+
+
+// -----------------------------------------------------------------------------
+// Addressing modes and instruction variants.
+
+// Condition code updating mode.
+enum SBit {
+ SetCC = 1 << 20, // Set condition code.
+ LeaveCC = 0 << 20 // Leave condition code unchanged.
+};
+
+
+// Status register selection.
+enum SRegister {
+ CPSR = 0 << 22,
+ SPSR = 1 << 22
};
// Shifter types for Data-processing operands as defined in section A5.1.2.
-enum Shift {
- no_shift = -1,
- LSL = 0, // Logical shift left
- LSR = 1, // Logical shift right
- ASR = 2, // Arithmetic shift right
- ROR = 3, // Rotate right
- max_shift = 4
+enum ShiftOp {
+ LSL = 0 << 5, // Logical shift left.
+ LSR = 1 << 5, // Logical shift right.
+ ASR = 2 << 5, // Arithmetic shift right.
+ ROR = 3 << 5, // Rotate right.
+
+ // RRX is encoded as ROR with shift_imm == 0.
+ // Use a special code to make the distinction. The RRX ShiftOp is only used
+ // as an argument, and will never actually be encoded. The Assembler will
+ // detect it and emit the correct ROR shift operand with shift_imm == 0.
+ RRX = -1,
+ kNumberOfShifts = 4
+};
+
+
+// Status register fields.
+enum SRegisterField {
+ CPSR_c = CPSR | 1 << 16,
+ CPSR_x = CPSR | 1 << 17,
+ CPSR_s = CPSR | 1 << 18,
+ CPSR_f = CPSR | 1 << 19,
+ SPSR_c = SPSR | 1 << 16,
+ SPSR_x = SPSR | 1 << 17,
+ SPSR_s = SPSR | 1 << 18,
+ SPSR_f = SPSR | 1 << 19
};
+// Status register field mask (or'ed SRegisterField enum values).
+typedef uint32_t SRegisterFieldMask;
+
+
+// Memory operand addressing mode.
+enum AddrMode {
+ // Bit encoding P U W.
+ Offset = (8|4|0) << 21, // Offset (without writeback to base).
+ PreIndex = (8|4|1) << 21, // Pre-indexed addressing with writeback.
+ PostIndex = (0|4|0) << 21, // Post-indexed addressing with writeback.
+ NegOffset = (8|0|0) << 21, // Negative offset (without writeback to base).
+ NegPreIndex = (8|0|1) << 21, // Negative pre-indexed with writeback.
+ NegPostIndex = (0|0|0) << 21 // Negative post-indexed with writeback.
+};
+
+
+// Load/store multiple addressing mode.
+enum BlockAddrMode {
+ // Bit encoding P U W .
+ da = (0|0|0) << 21, // Decrement after.
+ ia = (0|4|0) << 21, // Increment after.
+ db = (8|0|0) << 21, // Decrement before.
+ ib = (8|4|0) << 21, // Increment before.
+ da_w = (0|0|1) << 21, // Decrement after with writeback to base.
+ ia_w = (0|4|1) << 21, // Increment after with writeback to base.
+ db_w = (8|0|1) << 21, // Decrement before with writeback to base.
+ ib_w = (8|4|1) << 21, // Increment before with writeback to base.
+
+ // Alias modes for comparison when writeback does not matter.
+ da_x = (0|0|0) << 21, // Decrement after.
+ ia_x = (0|4|0) << 21, // Increment after.
+ db_x = (8|0|0) << 21, // Decrement before.
+ ib_x = (8|4|0) << 21 // Increment before.
+};
+
+
+// Coprocessor load/store operand size.
+enum LFlag {
+ Long = 1 << 22, // Long load/store coprocessor.
+ Short = 0 << 22 // Short load/store coprocessor.
+};
+
+
+// -----------------------------------------------------------------------------
+// Supervisor Call (svc) specific support.
// Special Software Interrupt codes when used in the presence of the ARM
// simulator.
// standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
enum SoftwareInterruptCodes {
// transition to C code
- call_rt_redirected = 0x10,
+ kCallRtRedirected= 0x10,
// break point
- break_point = 0x20,
+ kBreakpoint= 0x20,
// stop
- stop = 1 << 23
+ kStopCode = 1 << 23
};
-static const int32_t kStopCodeMask = stop - 1;
-static const uint32_t kMaxStopCode = stop - 1;
+static const uint32_t kStopCodeMask = kStopCode - 1;
+static const uint32_t kMaxStopCode = kStopCode - 1;
+static const int32_t kDefaultStopCode = -1;
// Type of VFP register. Determines register encoding.
kDoublePrecision = 1
};
+
+// VFP FPSCR constants.
+static const uint32_t kVFPExceptionMask = 0xf;
+static const uint32_t kVFPRoundingModeMask = 3 << 22;
+static const uint32_t kVFPFlushToZeroMask = 1 << 24;
+static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22;
+static const uint32_t kVFPInvalidExceptionBit = 1;
+
+static const uint32_t kVFPNConditionFlagBit = 1 << 31;
+static const uint32_t kVFPZConditionFlagBit = 1 << 30;
+static const uint32_t kVFPCConditionFlagBit = 1 << 29;
+static const uint32_t kVFPVConditionFlagBit = 1 << 28;
+
+
// VFP rounding modes. See ARM DDI 0406B Page A2-29.
enum FPSCRRoundingModes {
RN, // Round to Nearest.
RZ // Round towards zero.
};
-typedef int32_t instr_t;
+// -----------------------------------------------------------------------------
+// Hints.
+
+// Branch hints are not used on the ARM. They are defined so that they can
+// appear in shared function signatures, but will be ignored in ARM
+// implementations.
+enum Hint { no_hint };
+
+// Hints are not used on the arm. Negating is trivial.
+inline Hint NegateHint(Hint ignored) { return no_hint; }
+
+
+// -----------------------------------------------------------------------------
+// Specific instructions, constants, and masks.
+// These constants are declared in assembler-arm.cc, as they use named registers
+// and other constants.
+
+
+// add(sp, sp, 4) instruction (aka Pop())
+extern const Instr kPopInstruction;
-// The class Instr enables access to individual fields defined in the ARM
+// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
+// register r is not encoded.
+extern const Instr kPushRegPattern;
+
+// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
+// register r is not encoded.
+extern const Instr kPopRegPattern;
+
+// mov lr, pc
+extern const Instr kMovLrPc;
+// ldr rd, [pc, #offset]
+extern const Instr kLdrPCMask;
+extern const Instr kLdrPCPattern;
+// blxcc rm
+extern const Instr kBlxRegMask;
+
+extern const Instr kBlxRegPattern;
+
+extern const Instr kMovMvnMask;
+extern const Instr kMovMvnPattern;
+extern const Instr kMovMvnFlip;
+extern const Instr kMovLeaveCCMask;
+extern const Instr kMovLeaveCCPattern;
+extern const Instr kMovwMask;
+extern const Instr kMovwPattern;
+extern const Instr kMovwLeaveCCFlip;
+extern const Instr kCmpCmnMask;
+extern const Instr kCmpCmnPattern;
+extern const Instr kCmpCmnFlip;
+extern const Instr kAddSubFlip;
+extern const Instr kAndBicFlip;
+
+// A mask for the Rd register for push, pop, ldr, str instructions.
+extern const Instr kLdrRegFpOffsetPattern;
+
+extern const Instr kStrRegFpOffsetPattern;
+
+extern const Instr kLdrRegFpNegOffsetPattern;
+
+extern const Instr kStrRegFpNegOffsetPattern;
+
+extern const Instr kLdrStrInstrTypeMask;
+extern const Instr kLdrStrInstrArgumentMask;
+extern const Instr kLdrStrOffsetMask;
+
+
+// -----------------------------------------------------------------------------
+// Instruction abstraction.
+
+// The class Instruction enables access to individual fields defined in the ARM
// architecture instruction set encoding as described in figure A3-1.
+// Note that the Assembler uses typedef int32_t Instr.
//
// Example: Test whether the instruction at ptr does set the condition code
// bits.
//
// bool InstructionSetsConditionCodes(byte* ptr) {
-// Instr* instr = Instr::At(ptr);
-// int type = instr->TypeField();
+// Instruction* instr = Instruction::At(ptr);
+// int type = instr->TypeValue();
// return ((type == 0) || (type == 1)) && instr->HasS();
// }
//
-class Instr {
+class Instruction {
public:
enum {
kInstrSize = 4,
kPCReadOffset = 8
};
+ // Helper macro to define static accessors.
+ // We use the cast to char* trick to bypass the strict anti-aliasing rules.
+ #define DECLARE_STATIC_TYPED_ACCESSOR(return_type, Name) \
+ static inline return_type Name(Instr instr) { \
+ char* temp = reinterpret_cast<char*>(&instr); \
+ return reinterpret_cast<Instruction*>(temp)->Name(); \
+ }
+
+ #define DECLARE_STATIC_ACCESSOR(Name) DECLARE_STATIC_TYPED_ACCESSOR(int, Name)
+
// Get the raw instruction bits.
- inline instr_t InstructionBits() const {
- return *reinterpret_cast<const instr_t*>(this);
+ inline Instr InstructionBits() const {
+ return *reinterpret_cast<const Instr*>(this);
}
// Set the raw instruction bits to value.
- inline void SetInstructionBits(instr_t value) {
- *reinterpret_cast<instr_t*>(this) = value;
+ inline void SetInstructionBits(Instr value) {
+ *reinterpret_cast<Instr*>(this) = value;
}
// Read one particular bit out of the instruction bits.
return (InstructionBits() >> nr) & 1;
}
- // Read a bit field out of the instruction bits.
+ // Read a bit field's value out of the instruction bits.
inline int Bits(int hi, int lo) const {
return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
}
+ // Read a bit field out of the instruction bits.
+ inline int BitField(int hi, int lo) const {
+ return InstructionBits() & (((2 << (hi - lo)) - 1) << lo);
+ }
+
+ // Static support.
+
+ // Read one particular bit out of the instruction bits.
+ static inline int Bit(Instr instr, int nr) {
+ return (instr >> nr) & 1;
+ }
+
+ // Read the value of a bit field out of the instruction bits.
+ static inline int Bits(Instr instr, int hi, int lo) {
+ return (instr >> lo) & ((2 << (hi - lo)) - 1);
+ }
+
+
+ // Read a bit field out of the instruction bits.
+ static inline int BitField(Instr instr, int hi, int lo) {
+ return instr & (((2 << (hi - lo)) - 1) << lo);
+ }
+
// Accessors for the different named fields used in the ARM encoding.
// The naming of these accessor corresponds to figure A3-1.
+ //
+ // Two kind of accessors are declared:
+ // - <Name>Field() will return the raw field, ie the field's bits at their
+ // original place in the instruction encoding.
+ // eg. if instr is the 'addgt r0, r1, r2' instruction, encoded as 0xC0810002
+ // ConditionField(instr) will return 0xC0000000.
+ // - <Name>Value() will return the field value, shifted back to bit 0.
+ // eg. if instr is the 'addgt r0, r1, r2' instruction, encoded as 0xC0810002
+ // ConditionField(instr) will return 0xC.
+
+
// Generally applicable fields
- inline Condition ConditionField() const {
+ inline Condition ConditionValue() const {
return static_cast<Condition>(Bits(31, 28));
}
- inline int TypeField() const { return Bits(27, 25); }
+ inline Condition ConditionField() const {
+ return static_cast<Condition>(BitField(31, 28));
+ }
+ DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionValue);
+ DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionField);
- inline int RnField() const { return Bits(19, 16); }
- inline int RdField() const { return Bits(15, 12); }
+ inline int TypeValue() const { return Bits(27, 25); }
- inline int CoprocessorField() const { return Bits(11, 8); }
+ inline int RnValue() const { return Bits(19, 16); }
+ inline int RdValue() const { return Bits(15, 12); }
+ DECLARE_STATIC_ACCESSOR(RdValue);
+
+ inline int CoprocessorValue() const { return Bits(11, 8); }
// Support for VFP.
// Vn(19-16) | Vd(15-12) | Vm(3-0)
- inline int VnField() const { return Bits(19, 16); }
- inline int VmField() const { return Bits(3, 0); }
- inline int VdField() const { return Bits(15, 12); }
- inline int NField() const { return Bit(7); }
- inline int MField() const { return Bit(5); }
- inline int DField() const { return Bit(22); }
- inline int RtField() const { return Bits(15, 12); }
- inline int PField() const { return Bit(24); }
- inline int UField() const { return Bit(23); }
- inline int Opc1Field() const { return (Bit(23) << 2) | Bits(21, 20); }
- inline int Opc2Field() const { return Bits(19, 16); }
- inline int Opc3Field() const { return Bits(7, 6); }
- inline int SzField() const { return Bit(8); }
- inline int VLField() const { return Bit(20); }
- inline int VCField() const { return Bit(8); }
- inline int VAField() const { return Bits(23, 21); }
- inline int VBField() const { return Bits(6, 5); }
- inline int VFPNRegCode(VFPRegPrecision pre) {
- return VFPGlueRegCode(pre, 16, 7);
+ inline int VnValue() const { return Bits(19, 16); }
+ inline int VmValue() const { return Bits(3, 0); }
+ inline int VdValue() const { return Bits(15, 12); }
+ inline int NValue() const { return Bit(7); }
+ inline int MValue() const { return Bit(5); }
+ inline int DValue() const { return Bit(22); }
+ inline int RtValue() const { return Bits(15, 12); }
+ inline int PValue() const { return Bit(24); }
+ inline int UValue() const { return Bit(23); }
+ inline int Opc1Value() const { return (Bit(23) << 2) | Bits(21, 20); }
+ inline int Opc2Value() const { return Bits(19, 16); }
+ inline int Opc3Value() const { return Bits(7, 6); }
+ inline int SzValue() const { return Bit(8); }
+ inline int VLValue() const { return Bit(20); }
+ inline int VCValue() const { return Bit(8); }
+ inline int VAValue() const { return Bits(23, 21); }
+ inline int VBValue() const { return Bits(6, 5); }
+ inline int VFPNRegValue(VFPRegPrecision pre) {
+ return VFPGlueRegValue(pre, 16, 7);
}
- inline int VFPMRegCode(VFPRegPrecision pre) {
- return VFPGlueRegCode(pre, 0, 5);
+ inline int VFPMRegValue(VFPRegPrecision pre) {
+ return VFPGlueRegValue(pre, 0, 5);
}
- inline int VFPDRegCode(VFPRegPrecision pre) {
- return VFPGlueRegCode(pre, 12, 22);
+ inline int VFPDRegValue(VFPRegPrecision pre) {
+ return VFPGlueRegValue(pre, 12, 22);
}
// Fields used in Data processing instructions
- inline Opcode OpcodeField() const {
+ inline int OpcodeValue() const {
return static_cast<Opcode>(Bits(24, 21));
}
- inline int SField() const { return Bit(20); }
+ inline Opcode OpcodeField() const {
+ return static_cast<Opcode>(BitField(24, 21));
+ }
+ inline int SValue() const { return Bit(20); }
// with register
- inline int RmField() const { return Bits(3, 0); }
- inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); }
- inline int RegShiftField() const { return Bit(4); }
- inline int RsField() const { return Bits(11, 8); }
- inline int ShiftAmountField() const { return Bits(11, 7); }
+ inline int RmValue() const { return Bits(3, 0); }
+ inline int ShiftValue() const { return static_cast<ShiftOp>(Bits(6, 5)); }
+ inline ShiftOp ShiftField() const {
+ return static_cast<ShiftOp>(BitField(6, 5));
+ }
+ inline int RegShiftValue() const { return Bit(4); }
+ inline int RsValue() const { return Bits(11, 8); }
+ inline int ShiftAmountValue() const { return Bits(11, 7); }
// with immediate
- inline int RotateField() const { return Bits(11, 8); }
- inline int Immed8Field() const { return Bits(7, 0); }
- inline int Immed4Field() const { return Bits(19, 16); }
- inline int ImmedMovwMovtField() const {
- return Immed4Field() << 12 | Offset12Field(); }
+ inline int RotateValue() const { return Bits(11, 8); }
+ inline int Immed8Value() const { return Bits(7, 0); }
+ inline int Immed4Value() const { return Bits(19, 16); }
+ inline int ImmedMovwMovtValue() const {
+ return Immed4Value() << 12 | Offset12Value(); }
// Fields used in Load/Store instructions
- inline int PUField() const { return Bits(24, 23); }
- inline int BField() const { return Bit(22); }
- inline int WField() const { return Bit(21); }
- inline int LField() const { return Bit(20); }
+ inline int PUValue() const { return Bits(24, 23); }
+ inline int PUField() const { return BitField(24, 23); }
+ inline int BValue() const { return Bit(22); }
+ inline int WValue() const { return Bit(21); }
+ inline int LValue() const { return Bit(20); }
// with register uses same fields as Data processing instructions above
// with immediate
- inline int Offset12Field() const { return Bits(11, 0); }
+ inline int Offset12Value() const { return Bits(11, 0); }
// multiple
- inline int RlistField() const { return Bits(15, 0); }
+ inline int RlistValue() const { return Bits(15, 0); }
// extra loads and stores
- inline int SignField() const { return Bit(6); }
- inline int HField() const { return Bit(5); }
- inline int ImmedHField() const { return Bits(11, 8); }
- inline int ImmedLField() const { return Bits(3, 0); }
+ inline int SignValue() const { return Bit(6); }
+ inline int HValue() const { return Bit(5); }
+ inline int ImmedHValue() const { return Bits(11, 8); }
+ inline int ImmedLValue() const { return Bits(3, 0); }
// Fields used in Branch instructions
- inline int LinkField() const { return Bit(24); }
- inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
+ inline int LinkValue() const { return Bit(24); }
+ inline int SImmed24Value() const { return ((InstructionBits() << 8) >> 8); }
// Fields used in Software interrupt instructions
- inline SoftwareInterruptCodes SvcField() const {
+ inline SoftwareInterruptCodes SvcValue() const {
return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
}
// Test for a stop instruction.
inline bool IsStop() const {
- return (TypeField() == 7) && (Bit(24) == 1) && (SvcField() >= stop);
+ return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= kStopCode);
}
// Special accessors that test for existence of a value.
- inline bool HasS() const { return SField() == 1; }
- inline bool HasB() const { return BField() == 1; }
- inline bool HasW() const { return WField() == 1; }
- inline bool HasL() const { return LField() == 1; }
- inline bool HasU() const { return UField() == 1; }
- inline bool HasSign() const { return SignField() == 1; }
- inline bool HasH() const { return HField() == 1; }
- inline bool HasLink() const { return LinkField() == 1; }
+ inline bool HasS() const { return SValue() == 1; }
+ inline bool HasB() const { return BValue() == 1; }
+ inline bool HasW() const { return WValue() == 1; }
+ inline bool HasL() const { return LValue() == 1; }
+ inline bool HasU() const { return UValue() == 1; }
+ inline bool HasSign() const { return SignValue() == 1; }
+ inline bool HasH() const { return HValue() == 1; }
+ inline bool HasLink() const { return LinkValue() == 1; }
// Decoding the double immediate in the vmov instruction.
double DoubleImmedVmov() const;
// Instructions are read of out 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(byte* pc) { return reinterpret_cast<Instr*>(pc); }
+ // to allocate or create instances of class Instruction.
+ // Use the At(pc) function to create references to Instruction.
+ static Instruction* At(byte* pc) {
+ return reinterpret_cast<Instruction*>(pc);
+ }
+
private:
// Join split register codes, depending on single or double precision.
// four_bit is the position of the least-significant bit of the four
// bit specifier. one_bit is the position of the additional single bit
// specifier.
- inline int VFPGlueRegCode(VFPRegPrecision pre, int four_bit, int one_bit) {
+ inline int VFPGlueRegValue(VFPRegPrecision pre, int four_bit, int one_bit) {
if (pre == kSinglePrecision) {
return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit);
}
return (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit);
}
- // We need to prevent the creation of instances of class Instr.
- DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
+ // We need to prevent the creation of instances of class Instruction.
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
};
};
-} } // namespace assembler::arm
+} } // namespace v8::internal
#endif // V8_ARM_CONSTANTS_ARM_H_
// that the Icache was flushed.
// None of this code ends up in the snapshot so there are no issues
// around whether or not to generate the code when building snapshots.
- assembler::arm::Simulator::FlushICache(start, size);
+ Simulator::FlushICache(start, size);
#else
// Ideally, we would call
// syscall(__ARM_NR_cacheflush, start,
#include "platform.h"
-namespace assembler {
-namespace arm {
-
-namespace v8i = v8::internal;
+namespace v8 {
+namespace internal {
//------------------------------------------------------------------------------
class Decoder {
public:
Decoder(const disasm::NameConverter& converter,
- v8::internal::Vector<char> out_buffer)
+ Vector<char> out_buffer)
: converter_(converter),
out_buffer_(out_buffer),
out_buffer_pos_(0) {
void PrintRegister(int reg);
void PrintSRegister(int reg);
void PrintDRegister(int reg);
- int FormatVFPRegister(Instr* instr, const char* format);
- void PrintMovwMovt(Instr* instr);
- int FormatVFPinstruction(Instr* instr, const char* format);
- void PrintCondition(Instr* instr);
- void PrintShiftRm(Instr* instr);
- void PrintShiftImm(Instr* instr);
- void PrintShiftSat(Instr* instr);
- void PrintPU(Instr* instr);
+ int FormatVFPRegister(Instruction* instr, const char* format);
+ void PrintMovwMovt(Instruction* instr);
+ int FormatVFPinstruction(Instruction* instr, const char* format);
+ void PrintCondition(Instruction* instr);
+ void PrintShiftRm(Instruction* instr);
+ void PrintShiftImm(Instruction* instr);
+ void PrintShiftSat(Instruction* instr);
+ void PrintPU(Instruction* instr);
void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
// Handle formatting of instructions and their options.
- int FormatRegister(Instr* instr, const char* option);
- int FormatOption(Instr* instr, const char* option);
- void Format(Instr* instr, const char* format);
- void Unknown(Instr* instr);
+ int FormatRegister(Instruction* instr, const char* option);
+ int FormatOption(Instruction* instr, const char* option);
+ void Format(Instruction* instr, const char* format);
+ void Unknown(Instruction* instr);
// Each of these functions decodes one particular instruction type, a 3-bit
// field in the instruction encoding.
// Types 0 and 1 are combined as they are largely the same except for the way
// they interpret the shifter operand.
- void DecodeType01(Instr* instr);
- void DecodeType2(Instr* instr);
- void DecodeType3(Instr* instr);
- void DecodeType4(Instr* instr);
- void DecodeType5(Instr* instr);
- void DecodeType6(Instr* instr);
+ void DecodeType01(Instruction* instr);
+ void DecodeType2(Instruction* instr);
+ void DecodeType3(Instruction* instr);
+ void DecodeType4(Instruction* instr);
+ void DecodeType5(Instruction* instr);
+ void DecodeType6(Instruction* instr);
// Type 7 includes special Debugger instructions.
- int DecodeType7(Instr* instr);
+ int DecodeType7(Instruction* instr);
// For VFP support.
- void DecodeTypeVFP(Instr* instr);
- void DecodeType6CoprocessorIns(Instr* instr);
+ void DecodeTypeVFP(Instruction* instr);
+ void DecodeType6CoprocessorIns(Instruction* instr);
- void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr);
- void DecodeVCMP(Instr* instr);
- void DecodeVCVTBetweenDoubleAndSingle(Instr* instr);
- void DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr);
+ void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
+ void DecodeVCMP(Instruction* instr);
+ void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
+ void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
const disasm::NameConverter& converter_;
- v8::internal::Vector<char> out_buffer_;
+ Vector<char> out_buffer_;
int out_buffer_pos_;
DISALLOW_COPY_AND_ASSIGN(Decoder);
// These condition names are defined in a way to match the native disassembler
// formatting. See for example the command "objdump -d <binary file>".
-static const char* cond_names[max_condition] = {
+static const char* cond_names[kNumberOfConditions] = {
"eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
"hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
};
// Print the condition guarding the instruction.
-void Decoder::PrintCondition(Instr* instr) {
- Print(cond_names[instr->ConditionField()]);
+void Decoder::PrintCondition(Instruction* instr) {
+ Print(cond_names[instr->ConditionValue()]);
}
// Print the VFP S register name according to the active name converter.
void Decoder::PrintSRegister(int reg) {
- Print(assembler::arm::VFPRegisters::Name(reg, false));
+ Print(VFPRegisters::Name(reg, false));
}
// Print the VFP D register name according to the active name converter.
void Decoder::PrintDRegister(int reg) {
- Print(assembler::arm::VFPRegisters::Name(reg, true));
+ Print(VFPRegisters::Name(reg, true));
}
// These shift names are defined in a way to match the native disassembler
// formatting. See for example the command "objdump -d <binary file>".
-static const char* shift_names[max_shift] = {
+static const char* shift_names[kNumberOfShifts] = {
"lsl", "lsr", "asr", "ror"
};
// Print the register shift operands for the instruction. Generally used for
// data processing instructions.
-void Decoder::PrintShiftRm(Instr* instr) {
- Shift shift = instr->ShiftField();
- int shift_amount = instr->ShiftAmountField();
- int rm = instr->RmField();
+void Decoder::PrintShiftRm(Instruction* instr) {
+ ShiftOp shift = instr->ShiftField();
+ int shift_index = instr->ShiftValue();
+ int shift_amount = instr->ShiftAmountValue();
+ int rm = instr->RmValue();
PrintRegister(rm);
- if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) {
+ if ((instr->RegShiftValue() == 0) && (shift == LSL) && (shift_amount == 0)) {
// Special case for using rm only.
return;
}
- if (instr->RegShiftField() == 0) {
+ if (instr->RegShiftValue() == 0) {
// by immediate
if ((shift == ROR) && (shift_amount == 0)) {
Print(", RRX");
} else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
shift_amount = 32;
}
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- ", %s #%d",
- shift_names[shift], shift_amount);
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ ", %s #%d",
+ shift_names[shift_index],
+ shift_amount);
} else {
// by register
- int rs = instr->RsField();
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- ", %s ", shift_names[shift]);
+ int rs = instr->RsValue();
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ ", %s ", shift_names[shift_index]);
PrintRegister(rs);
}
}
// Print the immediate operand for the instruction. Generally used for data
// processing instructions.
-void Decoder::PrintShiftImm(Instr* instr) {
- int rotate = instr->RotateField() * 2;
- int immed8 = instr->Immed8Field();
+void Decoder::PrintShiftImm(Instruction* instr) {
+ int rotate = instr->RotateValue() * 2;
+ int immed8 = instr->Immed8Value();
int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "#%d", imm);
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "#%d", imm);
}
// Print the optional shift and immediate used by saturating instructions.
-void Decoder::PrintShiftSat(Instr* instr) {
+void Decoder::PrintShiftSat(Instruction* instr) {
int shift = instr->Bits(11, 7);
if (shift > 0) {
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- ", %s #%d",
- shift_names[instr->Bit(6) * 2],
- instr->Bits(11, 7));
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ ", %s #%d",
+ shift_names[instr->Bit(6) * 2],
+ instr->Bits(11, 7));
}
}
// Print PU formatting to reduce complexity of FormatOption.
-void Decoder::PrintPU(Instr* instr) {
+void Decoder::PrintPU(Instruction* instr) {
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
Print("da");
break;
}
- case 1: {
+ case ia_x: {
Print("ia");
break;
}
- case 2: {
+ case db_x: {
Print("db");
break;
}
- case 3: {
+ case ib_x: {
Print("ib");
break;
}
// the FormatOption method.
void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
switch (svc) {
- case call_rt_redirected:
- Print("call_rt_redirected");
+ case kCallRtRedirected:
+ Print("call rt redirected");
return;
- case break_point:
- Print("break_point");
+ case kBreakpoint:
+ Print("breakpoint");
return;
default:
- if (svc >= stop) {
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%d - 0x%x",
- svc & kStopCodeMask,
- svc & kStopCodeMask);
+ if (svc >= kStopCode) {
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%d - 0x%x",
+ svc & kStopCodeMask,
+ svc & kStopCodeMask);
} else {
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%d",
- svc);
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%d",
+ svc);
}
return;
}
// Handle all register based formatting in this function to reduce the
// complexity of FormatOption.
-int Decoder::FormatRegister(Instr* instr, const char* format) {
+int Decoder::FormatRegister(Instruction* instr, const char* format) {
ASSERT(format[0] == 'r');
if (format[1] == 'n') { // 'rn: Rn register
- int reg = instr->RnField();
+ int reg = instr->RnValue();
PrintRegister(reg);
return 2;
} else if (format[1] == 'd') { // 'rd: Rd register
- int reg = instr->RdField();
+ int reg = instr->RdValue();
PrintRegister(reg);
return 2;
} else if (format[1] == 's') { // 'rs: Rs register
- int reg = instr->RsField();
+ int reg = instr->RsValue();
PrintRegister(reg);
return 2;
} else if (format[1] == 'm') { // 'rm: Rm register
- int reg = instr->RmField();
+ int reg = instr->RmValue();
PrintRegister(reg);
return 2;
} else if (format[1] == 't') { // 'rt: Rt register
- int reg = instr->RtField();
+ int reg = instr->RtValue();
PrintRegister(reg);
return 2;
} else if (format[1] == 'l') {
// 'rlist: register list for load and store multiple instructions
ASSERT(STRING_STARTS_WITH(format, "rlist"));
- int rlist = instr->RlistField();
+ int rlist = instr->RlistValue();
int reg = 0;
Print("{");
// Print register list in ascending order, by scanning the bit mask.
// Handle all VFP register based formatting in this function to reduce the
// complexity of FormatOption.
-int Decoder::FormatVFPRegister(Instr* instr, const char* format) {
+int Decoder::FormatVFPRegister(Instruction* instr, const char* format) {
ASSERT((format[0] == 'S') || (format[0] == 'D'));
if (format[1] == 'n') {
- int reg = instr->VnField();
- if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->NField()));
+ int reg = instr->VnValue();
+ if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->NValue()));
if (format[0] == 'D') PrintDRegister(reg);
return 2;
} else if (format[1] == 'm') {
- int reg = instr->VmField();
- if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->MField()));
+ int reg = instr->VmValue();
+ if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->MValue()));
if (format[0] == 'D') PrintDRegister(reg);
return 2;
} else if (format[1] == 'd') {
- int reg = instr->VdField();
- if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->DField()));
+ int reg = instr->VdValue();
+ if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->DValue()));
if (format[0] == 'D') PrintDRegister(reg);
return 2;
}
}
-int Decoder::FormatVFPinstruction(Instr* instr, const char* format) {
+int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) {
Print(format);
return 0;
}
// Print the movw or movt instruction.
-void Decoder::PrintMovwMovt(Instr* instr) {
- int imm = instr->ImmedMovwMovtField();
- int rd = instr->RdField();
+void Decoder::PrintMovwMovt(Instruction* instr) {
+ int imm = instr->ImmedMovwMovtValue();
+ int rd = instr->RdValue();
PrintRegister(rd);
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- ", #%d", imm);
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ ", #%d", imm);
}
// character of the option string (the option escape has already been
// consumed by the caller.) FormatOption returns the number of
// characters that were consumed from the formatting string.
-int Decoder::FormatOption(Instr* instr, const char* format) {
+int Decoder::FormatOption(Instruction* instr, const char* format) {
switch (format[0]) {
case 'a': { // 'a: accumulate multiplies
if (instr->Bit(21) == 0) {
}
case 'd': { // 'd: vmov double immediate.
double d = instr->DoubleImmedVmov();
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "#%g", d);
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "#%g", d);
return 1;
}
case 'f': { // 'f: bitfield instructions - v7 and above.
ASSERT(width > 0);
}
ASSERT((width + lsbit) <= 32);
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "#%d, #%d", lsbit, width);
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "#%d, #%d", lsbit, width);
return 1;
}
case 'h': { // 'h: halfword operation for extra loads and stores
ASSERT((lsb >= 0) && (lsb <= 31));
ASSERT((width + lsb) <= 32);
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%d",
- instr->Bits(width + lsb - 1, lsb));
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%d",
+ instr->Bits(width + lsb - 1, lsb));
return 8;
}
case 'l': { // 'l: branch and link
ASSERT(STRING_STARTS_WITH(format, "msg"));
byte* str =
reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%s", converter_.NameInCode(str));
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%s", converter_.NameInCode(str));
return 3;
}
case 'o': {
if ((format[3] == '1') && (format[4] == '2')) {
// 'off12: 12-bit offset for load and store instructions
ASSERT(STRING_STARTS_WITH(format, "off12"));
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%d", instr->Offset12Field());
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%d", instr->Offset12Value());
return 5;
} else if (format[3] == '0') {
// 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0.
ASSERT(STRING_STARTS_WITH(format, "off0to3and8to19"));
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%d",
- (instr->Bits(19, 8) << 4) +
- instr->Bits(3, 0));
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%d",
+ (instr->Bits(19, 8) << 4) +
+ instr->Bits(3, 0));
return 15;
}
// 'off8: 8-bit offset for extra load and store instructions
ASSERT(STRING_STARTS_WITH(format, "off8"));
- int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%d", offs8);
+ int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%d", offs8);
return 4;
}
case 'p': { // 'pu: P and U bits for load and store instructions
if (format[1] == 'h') { // 'shift_op or 'shift_rm or 'shift_sat.
if (format[6] == 'o') { // 'shift_op
ASSERT(STRING_STARTS_WITH(format, "shift_op"));
- if (instr->TypeField() == 0) {
+ if (instr->TypeValue() == 0) {
PrintShiftRm(instr);
} else {
- ASSERT(instr->TypeField() == 1);
+ ASSERT(instr->TypeValue() == 1);
PrintShiftImm(instr);
}
return 8;
}
} else if (format[1] == 'v') { // 'svc
ASSERT(STRING_STARTS_WITH(format, "svc"));
- PrintSoftwareInterrupt(instr->SvcField());
+ PrintSoftwareInterrupt(instr->SvcValue());
return 3;
} else if (format[1] == 'i') { // 'sign: signed extra loads and stores
ASSERT(STRING_STARTS_WITH(format, "sign"));
}
case 't': { // 'target: target of branch instructions
ASSERT(STRING_STARTS_WITH(format, "target"));
- int off = (instr->SImmed24Field() << 2) + 8;
- out_buffer_pos_ += v8i::OS::SNPrintF(
- out_buffer_ + out_buffer_pos_,
- "%+d -> %s",
- off,
- converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
+ int off = (instr->SImmed24Value() << 2) + 8;
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%+d -> %s",
+ off,
+ converter_.NameOfAddress(
+ reinterpret_cast<byte*>(instr) + off));
return 6;
}
case 'u': { // 'u: signed or unsigned multiplies
// Format takes a formatting string for a whole instruction and prints it into
// the output buffer. All escaped options are handed to FormatOption to be
// parsed further.
-void Decoder::Format(Instr* instr, const char* format) {
+void Decoder::Format(Instruction* instr, const char* format) {
char cur = *format++;
while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
if (cur == '\'') { // Single quote is used as the formatting escape.
// For currently unimplemented decodings the disassembler calls Unknown(instr)
// which will just print "unknown" of the instruction bits.
-void Decoder::Unknown(Instr* instr) {
+void Decoder::Unknown(Instruction* instr) {
Format(instr, "unknown");
}
-void Decoder::DecodeType01(Instr* instr) {
- int type = instr->TypeField();
+void Decoder::DecodeType01(Instruction* instr) {
+ int type = instr->TypeValue();
if ((type == 0) && instr->IsSpecialType0()) {
// multiply instruction or extra loads and stores
if (instr->Bits(7, 4) == 9) {
} else if ((instr->Bit(20) == 0) && ((instr->Bits(7, 4) & 0xd) == 0xd)) {
// ldrd, strd
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond's 'rd, ['rn], -'rm");
} else {
}
break;
}
- case 1: {
+ case ia_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond's 'rd, ['rn], +'rm");
} else {
}
break;
}
- case 2: {
+ case db_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond's 'rd, ['rn, -'rm]'w");
} else {
}
break;
}
- case 3: {
+ case ib_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond's 'rd, ['rn, +'rm]'w");
} else {
} else {
// extra load/store instructions
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
} else {
}
break;
}
- case 1: {
+ case ia_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
} else {
}
break;
}
- case 2: {
+ case db_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
} else {
}
break;
}
- case 3: {
+ case ib_x: {
if (instr->Bit(22) == 0) {
Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
} else {
}
} else if ((type == 0) && instr->IsMiscType0()) {
if (instr->Bits(22, 21) == 1) {
- switch (instr->Bits(7, 4)) {
+ switch (instr->BitField(7, 4)) {
case BX:
Format(instr, "bx'cond 'rm");
break;
break;
}
} else if (instr->Bits(22, 21) == 3) {
- switch (instr->Bits(7, 4)) {
+ switch (instr->BitField(7, 4)) {
case CLZ:
Format(instr, "clz'cond 'rd, 'rm");
break;
}
-void Decoder::DecodeType2(Instr* instr) {
+void Decoder::DecodeType2(Instruction* instr) {
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
if (instr->HasW()) {
Unknown(instr); // not used in V8
}
Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
break;
}
- case 1: {
+ case ia_x: {
if (instr->HasW()) {
Unknown(instr); // not used in V8
}
Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
break;
}
- case 2: {
+ case db_x: {
Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
break;
}
- case 3: {
+ case ib_x: {
Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
break;
}
}
-void Decoder::DecodeType3(Instr* instr) {
+void Decoder::DecodeType3(Instruction* instr) {
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
ASSERT(!instr->HasW());
Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
break;
}
- case 1: {
+ case ia_x: {
if (instr->HasW()) {
ASSERT(instr->Bits(5, 4) == 0x1);
if (instr->Bit(22) == 0x1) {
}
break;
}
- case 2: {
+ case db_x: {
Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
break;
}
- case 3: {
+ case ib_x: {
if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
if (msbit >= lsbit) {
- if (instr->RmField() == 15) {
+ if (instr->RmValue() == 15) {
Format(instr, "bfc'cond 'rd, 'f");
} else {
Format(instr, "bfi'cond 'rd, 'rm, 'f");
}
-void Decoder::DecodeType4(Instr* instr) {
+void Decoder::DecodeType4(Instruction* instr) {
ASSERT(instr->Bit(22) == 0); // Privileged mode currently not supported.
if (instr->HasL()) {
Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
}
-void Decoder::DecodeType5(Instr* instr) {
+void Decoder::DecodeType5(Instruction* instr) {
Format(instr, "b'l'cond 'target");
}
-void Decoder::DecodeType6(Instr* instr) {
+void Decoder::DecodeType6(Instruction* instr) {
DecodeType6CoprocessorIns(instr);
}
-int Decoder::DecodeType7(Instr* instr) {
+int Decoder::DecodeType7(Instruction* instr) {
if (instr->Bit(24) == 1) {
- if (instr->SvcField() >= stop) {
+ if (instr->SvcValue() >= kStopCode) {
Format(instr, "stop'cond 'svc");
// Also print the stop message. Its address is encoded
// in the following 4 bytes.
- out_buffer_pos_ +=
- v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "\n %p %08x stop message: %s",
- reinterpret_cast<int32_t*>(instr + Instr::kInstrSize),
- *reinterpret_cast<char**>(instr + Instr::kInstrSize),
- *reinterpret_cast<char**>(instr + Instr::kInstrSize));
- // We have decoded 2 * Instr::kInstrSize bytes.
- return 2 * Instr::kInstrSize;
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "\n %p %08x stop message: %s",
+ reinterpret_cast<int32_t*>(instr
+ + Instruction::kInstrSize),
+ *reinterpret_cast<char**>(instr
+ + Instruction::kInstrSize),
+ *reinterpret_cast<char**>(instr
+ + Instruction::kInstrSize));
+ // We have decoded 2 * Instruction::kInstrSize bytes.
+ return 2 * Instruction::kInstrSize;
} else {
Format(instr, "svc'cond 'svc");
}
} else {
DecodeTypeVFP(instr);
}
- return Instr::kInstrSize;
+ return Instruction::kInstrSize;
}
-// void Decoder::DecodeTypeVFP(Instr* instr)
+// void Decoder::DecodeTypeVFP(Instruction* instr)
// vmov: Sn = Rt
// vmov: Rt = Sn
// vcvt: Dd = Sm
// vmrs
// vmsr
// Dd = vsqrt(Dm)
-void Decoder::DecodeTypeVFP(Instr* instr) {
- ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
+void Decoder::DecodeTypeVFP(Instruction* instr) {
+ ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
ASSERT(instr->Bits(11, 9) == 0x5);
if (instr->Bit(4) == 0) {
- if (instr->Opc1Field() == 0x7) {
+ if (instr->Opc1Value() == 0x7) {
// Other data processing instructions
- if ((instr->Opc2Field() == 0x0) && (instr->Opc3Field() == 0x1)) {
+ if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
// vmov register to register.
- if (instr->SzField() == 0x1) {
+ if (instr->SzValue() == 0x1) {
Format(instr, "vmov.f64'cond 'Dd, 'Dm");
} else {
Format(instr, "vmov.f32'cond 'Sd, 'Sm");
}
- } else if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) {
+ } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
DecodeVCVTBetweenDoubleAndSingle(instr);
- } else if ((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) {
+ } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if (((instr->Opc2Field() >> 1) == 0x6) &&
- (instr->Opc3Field() & 0x1)) {
+ } else if (((instr->Opc2Value() >> 1) == 0x6) &&
+ (instr->Opc3Value() & 0x1)) {
DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
- (instr->Opc3Field() & 0x1)) {
+ } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
+ (instr->Opc3Value() & 0x1)) {
DecodeVCMP(instr);
- } else if (((instr->Opc2Field() == 0x1)) && (instr->Opc3Field() == 0x3)) {
+ } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
Format(instr, "vsqrt.f64'cond 'Dd, 'Dm");
- } else if (instr->Opc3Field() == 0x0) {
- if (instr->SzField() == 0x1) {
+ } else if (instr->Opc3Value() == 0x0) {
+ if (instr->SzValue() == 0x1) {
Format(instr, "vmov.f64'cond 'Dd, 'd");
} else {
Unknown(instr); // Not used by V8.
} else {
Unknown(instr); // Not used by V8.
}
- } else if (instr->Opc1Field() == 0x3) {
- if (instr->SzField() == 0x1) {
- if (instr->Opc3Field() & 0x1) {
+ } else if (instr->Opc1Value() == 0x3) {
+ if (instr->SzValue() == 0x1) {
+ if (instr->Opc3Value() & 0x1) {
Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
} else {
Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
}
- } else if ((instr->Opc1Field() == 0x2) && !(instr->Opc3Field() & 0x1)) {
- if (instr->SzField() == 0x1) {
+ } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
+ if (instr->SzValue() == 0x1) {
Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
}
- } else if ((instr->Opc1Field() == 0x4) && !(instr->Opc3Field() & 0x1)) {
- if (instr->SzField() == 0x1) {
+ } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
+ if (instr->SzValue() == 0x1) {
Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
Unknown(instr); // Not used by V8.
}
} else {
- if ((instr->VCField() == 0x0) &&
- (instr->VAField() == 0x0)) {
+ if ((instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x0)) {
DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
- } else if ((instr->VCField() == 0x0) &&
- (instr->VAField() == 0x7) &&
+ } else if ((instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x7) &&
(instr->Bits(19, 16) == 0x1)) {
- if (instr->VLField() == 0) {
+ if (instr->VLValue() == 0) {
if (instr->Bits(15, 12) == 0xF) {
Format(instr, "vmsr'cond FPSCR, APSR");
} else {
}
-void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr) {
- ASSERT((instr->Bit(4) == 1) && (instr->VCField() == 0x0) &&
- (instr->VAField() == 0x0));
+void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
+ Instruction* instr) {
+ ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x0));
- bool to_arm_register = (instr->VLField() == 0x1);
+ bool to_arm_register = (instr->VLValue() == 0x1);
if (to_arm_register) {
Format(instr, "vmov'cond 'rt, 'Sn");
}
-void Decoder::DecodeVCMP(Instr* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
- ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
- (instr->Opc3Field() & 0x1));
+void Decoder::DecodeVCMP(Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
+ (instr->Opc3Value() & 0x1));
// Comparison.
- bool dp_operation = (instr->SzField() == 1);
+ bool dp_operation = (instr->SzValue() == 1);
bool raise_exception_for_qnan = (instr->Bit(7) == 0x1);
if (dp_operation && !raise_exception_for_qnan) {
- if (instr->Opc2Field() == 0x4) {
+ if (instr->Opc2Value() == 0x4) {
Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
- } else if (instr->Opc2Field() == 0x5) {
+ } else if (instr->Opc2Value() == 0x5) {
Format(instr, "vcmp.f64'cond 'Dd, #0.0");
} else {
Unknown(instr); // invalid
}
-void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instr* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
- ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3));
+void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
- bool double_to_single = (instr->SzField() == 1);
+ bool double_to_single = (instr->SzValue() == 1);
if (double_to_single) {
Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm");
}
-void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
- ASSERT(((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) ||
- (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1)));
+void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
+ (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
bool to_integer = (instr->Bit(18) == 1);
- bool dp_operation = (instr->SzField() == 1);
+ bool dp_operation = (instr->SzValue() == 1);
if (to_integer) {
bool unsigned_integer = (instr->Bit(16) == 0);
// <Rt, Rt2> = vmov(Dm)
// Ddst = MEM(Rbase + 4*offset).
// MEM(Rbase + 4*offset) = Dsrc.
-void Decoder::DecodeType6CoprocessorIns(Instr* instr) {
- ASSERT((instr->TypeField() == 6));
+void Decoder::DecodeType6CoprocessorIns(Instruction* instr) {
+ ASSERT(instr->TypeValue() == 6);
- if (instr->CoprocessorField() == 0xA) {
- switch (instr->OpcodeField()) {
+ if (instr->CoprocessorValue() == 0xA) {
+ switch (instr->OpcodeValue()) {
case 0x8:
case 0xA:
if (instr->HasL()) {
Unknown(instr); // Not used by V8.
break;
}
- } else if (instr->CoprocessorField() == 0xB) {
- switch (instr->OpcodeField()) {
+ } else if (instr->CoprocessorValue() == 0xB) {
+ switch (instr->OpcodeValue()) {
case 0x2:
// Load and store double to two GP registers
if (instr->Bits(7, 4) != 0x1) {
// Disassemble the instruction at *instr_ptr into the output buffer.
int Decoder::InstructionDecode(byte* instr_ptr) {
- Instr* instr = Instr::At(instr_ptr);
+ Instruction* instr = Instruction::At(instr_ptr);
// Print raw instruction bytes.
- out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
- "%08x ",
- instr->InstructionBits());
- if (instr->ConditionField() == special_condition) {
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+ "%08x ",
+ instr->InstructionBits());
+ if (instr->ConditionField() == kSpecialCondition) {
UNIMPLEMENTED();
- return Instr::kInstrSize;
+ return Instruction::kInstrSize;
}
- switch (instr->TypeField()) {
+ switch (instr->TypeValue()) {
case 0:
case 1: {
DecodeType01(instr);
break;
}
}
- return Instr::kInstrSize;
+ return Instruction::kInstrSize;
}
-} } // namespace assembler::arm
+} } // namespace v8::internal
namespace disasm {
-namespace v8i = v8::internal;
-
const char* NameConverter::NameOfAddress(byte* addr) const {
static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
const char* NameConverter::NameOfCPURegister(int reg) const {
- return assembler::arm::Registers::Name(reg);
+ return v8::internal::Registers::Name(reg);
}
int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
byte* instruction) {
- assembler::arm::Decoder d(converter_, buffer);
+ v8::internal::Decoder d(converter_, buffer);
return d.InstructionDecode(instruction);
}
}
-void FullCodeGenerator::Split(Condition cc,
+void FullCodeGenerator::Split(Condition cond,
Label* if_true,
Label* if_false,
Label* fall_through) {
if (if_false == fall_through) {
- __ b(cc, if_true);
+ __ b(cond, if_true);
} else if (if_true == fall_through) {
- __ b(NegateCondition(cc), if_false);
+ __ b(NegateCondition(cond), if_false);
} else {
- __ b(cc, if_true);
+ __ b(cond, if_true);
__ b(if_false);
}
}
default: {
VisitForAccumulatorValue(expr->right());
- Condition cc = eq;
+ Condition cond = eq;
bool strict = false;
switch (op) {
case Token::EQ_STRICT:
strict = true;
// Fall through
case Token::EQ:
- cc = eq;
+ cond = eq;
__ pop(r1);
break;
case Token::LT:
- cc = lt;
+ cond = lt;
__ pop(r1);
break;
case Token::GT:
// Reverse left and right sides to obtain ECMA-262 conversion order.
- cc = lt;
+ cond = lt;
__ mov(r1, result_register());
__ pop(r0);
break;
case Token::LTE:
// Reverse left and right sides to obtain ECMA-262 conversion order.
- cc = ge;
+ cond = ge;
__ mov(r1, result_register());
__ pop(r0);
break;
case Token::GTE:
- cc = ge;
+ cond = ge;
__ pop(r1);
break;
case Token::IN:
__ orr(r2, r0, Operand(r1));
__ JumpIfNotSmi(r2, &slow_case);
__ cmp(r1, r0);
- Split(cc, if_true, if_false, NULL);
+ Split(cond, if_true, if_false, NULL);
__ bind(&slow_case);
}
CompareFlags flags = inline_smi_code
? NO_SMI_COMPARE_IN_STUB
: NO_COMPARE_FLAGS;
- CompareStub stub(cc, strict, flags, r1, r0);
+ CompareStub stub(cond, strict, flags, r1, r0);
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
__ cmp(r0, Operand(0, RelocInfo::NONE));
- Split(cc, if_true, if_false, fall_through);
+ Split(cond, if_true, if_false, fall_through);
}
}
__ ldrb(t1, FieldMemOperand(t0, Map::kBitFieldOffset));
__ tst(t1, Operand((1 << Map::kIsAccessCheckNeeded) |
(1 << Map::kHasNamedInterceptor)));
- __ b(nz, miss);
+ __ b(ne, miss);
__ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHashTableMapRootIndex);
__ cmp(t1, ip);
- __ b(nz, miss);
+ __ b(ne, miss);
}
__ ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
__ tst(scratch,
Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)));
- __ b(nz, slow);
+ __ b(ne, slow);
// Check that the object is some kind of JS object EXCEPT JS Value type.
// In the case that the object is a value-wrapper object,
// we enter the runtime system to make sure that indexing into string
return ge;
default:
UNREACHABLE();
- return no_condition;
+ return kNoCondition;
}
}
}
-void JumpTarget::DoBranch(Condition cc, Hint ignored) {
+void JumpTarget::DoBranch(Condition cond, Hint ignored) {
ASSERT(cgen()->has_valid_frame());
if (entry_frame_set_) {
ASSERT(entry_frame_.IsCompatibleWith(cgen()->frame()));
}
// We have an expected frame to merge to on the backward edge.
- cgen()->frame()->MergeTo(&entry_frame_, cc);
+ cgen()->frame()->MergeTo(&entry_frame_, cond);
} else {
// Clone the current frame to use as the expected one at the target.
set_entry_frame(cgen()->frame());
// frame with less precise type info branches to them.
ASSERT(direction_ != FORWARD_ONLY);
}
- __ b(cc, &entry_label_);
- if (cc == al) {
+ __ b(cond, &entry_label_);
+ if (cond == al) {
cgen()->DeleteFrame();
}
}
return;
}
- if (cc == no_condition) {
+ if (cc == kNoCondition) {
if (FLAG_trap_on_deopt) __ stop("trap_on_deopt");
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
} else {
__ b(ne, &done);
if (instr->InputAt(1)->IsConstantOperand()) {
if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) < 0) {
- DeoptimizeIf(no_condition, instr->environment());
+ DeoptimizeIf(kNoCondition, instr->environment());
}
} else {
// Test the non-zero operand for negative sign.
if (r.IsInteger32()) {
Register reg = ToRegister(instr->InputAt(0));
__ cmp(reg, Operand(0));
- EmitBranch(true_block, false_block, nz);
+ EmitBranch(true_block, false_block, ne);
} else if (r.IsDouble()) {
DoubleRegister reg = ToDoubleRegister(instr->InputAt(0));
Register scratch = scratch0();
__ CallStub(&stub);
__ cmp(reg, Operand(0));
__ ldm(ia_w, sp, saved_regs);
- EmitBranch(true_block, false_block, nz);
+ EmitBranch(true_block, false_block, ne);
}
}
}
Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
- Condition cond = no_condition;
+ Condition cond = kNoCondition;
switch (op) {
case Token::EQ:
case Token::EQ_STRICT:
return ge;
default:
UNREACHABLE();
- return no_condition;
+ return kNoCondition;
}
}
Label* false_label,
Register input,
Handle<String> type_name) {
- Condition final_branch_condition = no_condition;
+ Condition final_branch_condition = kNoCondition;
Register scratch = scratch0();
if (type_name->Equals(Heap::number_symbol())) {
__ tst(input, Operand(kSmiTagMask));
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
- DeoptimizeIf(no_condition, instr->environment());
+ DeoptimizeIf(kNoCondition, instr->environment());
}
CheckConstPool(true, true);
add(pc, pc, Operand(index,
LSL,
- assembler::arm::Instr::kInstrSizeLog2 - kSmiTagSize));
+ Instruction::kInstrSizeLog2 - kSmiTagSize));
BlockConstPoolBefore(pc_offset() + (targets.length() + 1) * kInstrSize);
nop(); // Jump table alignment.
for (int i = 0; i < targets.length(); i++) {
void MacroAssembler::InNewSpace(Register object,
Register scratch,
- Condition cc,
+ Condition cond,
Label* branch) {
- ASSERT(cc == eq || cc == ne);
+ ASSERT(cond == eq || cond == ne);
and_(scratch, object, Operand(ExternalReference::new_space_mask()));
cmp(scratch, Operand(ExternalReference::new_space_start()));
- b(cc, branch);
+ b(cond, branch);
}
ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
tst(scratch, Operand(kIsNotStringMask));
- b(nz, fail);
+ b(ne, fail);
}
}
-void MacroAssembler::Assert(Condition cc, const char* msg) {
+void MacroAssembler::Assert(Condition cond, const char* msg) {
if (FLAG_debug_code)
- Check(cc, msg);
+ Check(cond, msg);
}
}
-void MacroAssembler::Check(Condition cc, const char* msg) {
+void MacroAssembler::Check(Condition cond, const char* msg) {
Label L;
- b(cc, &L);
+ b(cond, &L);
Abort(msg);
// will not return here
bind(&L);
// scratch can be object itself, but it will be clobbered.
void InNewSpace(Register object,
Register scratch,
- Condition cc, // eq for new space, ne otherwise
+ Condition cond, // eq for new space, ne otherwise
Label* branch);
// ---------------------------------------------------------------------------
// Debugging
- // Calls Abort(msg) if the condition cc is not satisfied.
+ // Calls Abort(msg) if the condition cond is not satisfied.
// Use --debug_code to enable.
- void Assert(Condition cc, const char* msg);
+ void Assert(Condition cond, const char* msg);
void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
void AssertFastElements(Register elements);
// Like Assert(), but always enabled.
- void Check(Condition cc, const char* msg);
+ void Check(Condition cond, const char* msg);
// Print a message to stdout and abort execution.
void Abort(const char* msg);
#if defined(USE_SIMULATOR)
// Only build the simulator if not compiling for real ARM hardware.
-namespace assembler {
-namespace arm {
-
-using ::v8::internal::Object;
-using ::v8::internal::PrintF;
-using ::v8::internal::OS;
-using ::v8::internal::ReadLine;
-using ::v8::internal::DeleteArray;
+namespace v8 {
+namespace internal {
// This macro provides a platform independent use of sscanf. The reason for
// SScanF not being implemented in a platform independent way through
explicit Debugger(Simulator* sim);
~Debugger();
- void Stop(Instr* instr);
+ void Stop(Instruction* instr);
void Debug();
private:
- static const instr_t kBreakpointInstr =
- ((AL << 28) | (7 << 25) | (1 << 24) | break_point);
- static const instr_t kNopInstr =
- ((AL << 28) | (13 << 21));
+ static const Instr kBreakpointInstr =
+ (al | (7*B25) | (1*B24) | kBreakpoint);
+ static const Instr kNopInstr = (al | (13*B21));
Simulator* sim_;
bool GetVFPDoubleValue(const char* desc, double* value);
// Set or delete a breakpoint. Returns true if successful.
- bool SetBreakpoint(Instr* breakpc);
- bool DeleteBreakpoint(Instr* breakpc);
+ bool SetBreakpoint(Instruction* breakpc);
+ bool DeleteBreakpoint(Instruction* breakpc);
// Undo and redo all breakpoints. This is needed to bracket disassembly and
// execution to skip past breakpoints when run from the debugger.
}
-void Debugger::Stop(Instr* instr) {
+void Debugger::Stop(Instruction* instr) {
// Get the stop code.
- uint32_t code = instr->SvcField() & kStopCodeMask;
+ uint32_t code = instr->SvcValue() & kStopCodeMask;
// Retrieve the encoded address, which comes just after this stop.
char** msg_address =
- reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
+ reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
char* msg = *msg_address;
ASSERT(msg != NULL);
}
// Overwrite the instruction and address with nops.
instr->SetInstructionBits(kNopInstr);
- reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
+ reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
}
- sim_->set_pc(sim_->get_pc() + 2 * Instr::kInstrSize);
+ sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
}
#else // ndef GENERATED_CODE_COVERAGE
}
-void Debugger::Stop(Instr* instr) {
+void Debugger::Stop(Instruction* instr) {
// Get the stop code.
- uint32_t code = instr->SvcField() & kStopCodeMask;
+ uint32_t code = instr->SvcValue() & kStopCodeMask;
// Retrieve the encoded address, which comes just after this stop.
- char* msg = *reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
+ char* msg = *reinterpret_cast<char**>(sim_->get_pc()
+ + Instruction::kInstrSize);
// Update this stop description.
if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) {
sim_->watched_stops[code].desc = msg;
} else {
PrintF("Simulator hit %s\n", msg);
}
- sim_->set_pc(sim_->get_pc() + 2 * Instr::kInstrSize);
+ sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
Debug();
}
#endif
}
-bool Debugger::SetBreakpoint(Instr* breakpc) {
+bool Debugger::SetBreakpoint(Instruction* breakpc) {
// Check if a breakpoint can be set. If not return without any side-effects.
if (sim_->break_pc_ != NULL) {
return false;
}
-bool Debugger::DeleteBreakpoint(Instr* breakpc) {
+bool Debugger::DeleteBreakpoint(Instruction* breakpc) {
if (sim_->break_pc_ != NULL) {
sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
}
"%" XSTR(ARG_SIZE) "s",
cmd, arg1, arg2);
if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
- sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+ sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
} else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
// Execute the one instruction we broke at with breakpoints disabled.
- sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
+ sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
// Leave the debugger shell.
done = true;
} else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
if (argc == 1) {
cur = reinterpret_cast<byte*>(sim_->get_pc());
- end = cur + (10 * Instr::kInstrSize);
+ end = cur + (10 * Instruction::kInstrSize);
} else if (argc == 2) {
int32_t value;
if (GetValue(arg1, &value)) {
cur = reinterpret_cast<byte*>(sim_->get_pc());
// Disassemble <arg1> instructions.
- end = cur + (value * Instr::kInstrSize);
+ end = cur + (value * Instruction::kInstrSize);
}
} else {
int32_t value1;
int32_t value2;
if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
cur = reinterpret_cast<byte*>(value1);
- end = cur + (value2 * Instr::kInstrSize);
+ end = cur + (value2 * Instruction::kInstrSize);
}
}
if (argc == 2) {
int32_t value;
if (GetValue(arg1, &value)) {
- if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) {
+ if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
PrintF("setting breakpoint failed\n");
}
} else {
PrintF("INEXACT flag: %d;\n", sim_->inexact_vfp_flag_);
} else if (strcmp(cmd, "stop") == 0) {
int32_t value;
- intptr_t stop_pc = sim_->get_pc() - 2 * Instr::kInstrSize;
- Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
- Instr* msg_address =
- reinterpret_cast<Instr*>(stop_pc + Instr::kInstrSize);
+ intptr_t stop_pc = sim_->get_pc() - 2 * Instruction::kInstrSize;
+ Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
+ Instruction* msg_address =
+ reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize);
if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
// Remove the current stop.
if (sim_->isStopInstruction(stop_instr)) {
}
-void Simulator::CheckICache(Instr* instr) {
+void Simulator::CheckICache(Instruction* instr) {
intptr_t address = reinterpret_cast<intptr_t>(instr);
void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
// Check that the data in memory matches the contents of the I-cache.
CHECK(memcmp(reinterpret_cast<void*>(instr),
cache_page->CachedData(offset),
- Instr::kInstrSize) == 0);
+ Instruction::kInstrSize) == 0);
} else {
// Cache miss. Load memory into the cache.
memcpy(cached_line, line, CachePage::kLineLength);
public:
Redirection(void* external_function, bool fp_return)
: external_function_(external_function),
- swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
+ swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
fp_return_(fp_return),
next_(list_) {
Simulator::current()->
FlushICache(reinterpret_cast<void*>(&swi_instruction_),
- Instr::kInstrSize);
+ Instruction::kInstrSize);
list_ = this;
}
return new Redirection(external_function, fp_return);
}
- static Redirection* FromSwiInstruction(Instr* swi_instruction) {
+ static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
char* addr_of_redirection =
addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
// See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
if (reg >= num_registers) return 0;
// End stupid code.
- return registers_[reg] + ((reg == pc) ? Instr::kPCReadOffset : 0);
+ return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
}
// targets that don't support unaligned loads and stores.
-int Simulator::ReadW(int32_t addr, Instr* instr) {
+int Simulator::ReadW(int32_t addr, Instruction* instr) {
#if V8_TARGET_CAN_READ_UNALIGNED
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
return *ptr;
}
-void Simulator::WriteW(int32_t addr, int value, Instr* instr) {
+void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
#if V8_TARGET_CAN_READ_UNALIGNED
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
*ptr = value;
}
-uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) {
+uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
#if V8_TARGET_CAN_READ_UNALIGNED
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
return *ptr;
}
-int16_t Simulator::ReadH(int32_t addr, Instr* instr) {
+int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
#if V8_TARGET_CAN_READ_UNALIGNED
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
return *ptr;
}
-void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) {
+void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
#if V8_TARGET_CAN_READ_UNALIGNED
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
*ptr = value;
}
-void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) {
+void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
#if V8_TARGET_CAN_READ_UNALIGNED
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
*ptr = value;
// Unsupported instructions use Format to print an error and stop execution.
-void Simulator::Format(Instr* instr, const char* format) {
+void Simulator::Format(Instruction* instr, const char* format) {
PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
reinterpret_cast<intptr_t>(instr), format);
UNIMPLEMENTED();
// Checks if the current instruction should be executed based on its
// condition bits.
-bool Simulator::ConditionallyExecute(Instr* instr) {
+bool Simulator::ConditionallyExecute(Instruction* instr) {
switch (instr->ConditionField()) {
- case EQ: return z_flag_;
- case NE: return !z_flag_;
- case CS: return c_flag_;
- case CC: return !c_flag_;
- case MI: return n_flag_;
- case PL: return !n_flag_;
- case VS: return v_flag_;
- case VC: return !v_flag_;
- case HI: return c_flag_ && !z_flag_;
- case LS: return !c_flag_ || z_flag_;
- case GE: return n_flag_ == v_flag_;
- case LT: return n_flag_ != v_flag_;
- case GT: return !z_flag_ && (n_flag_ == v_flag_);
- case LE: return z_flag_ || (n_flag_ != v_flag_);
- case AL: return true;
+ case eq: return z_flag_;
+ case ne: return !z_flag_;
+ case cs: return c_flag_;
+ case cc: return !c_flag_;
+ case mi: return n_flag_;
+ case pl: return !n_flag_;
+ case vs: return v_flag_;
+ case vc: return !v_flag_;
+ case hi: return c_flag_ && !z_flag_;
+ case ls: return !c_flag_ || z_flag_;
+ case ge: return n_flag_ == v_flag_;
+ case lt: return n_flag_ != v_flag_;
+ case gt: return !z_flag_ && (n_flag_ == v_flag_);
+ case le: return z_flag_ || (n_flag_ != v_flag_);
+ case al: return true;
default: UNREACHABLE();
}
return false;
// Addressing Mode 1 - Data-processing operands:
// Get the value based on the shifter_operand with register.
-int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) {
- Shift shift = instr->ShiftField();
- int shift_amount = instr->ShiftAmountField();
- int32_t result = get_register(instr->RmField());
+int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
+ ShiftOp shift = instr->ShiftField();
+ int shift_amount = instr->ShiftAmountValue();
+ int32_t result = get_register(instr->RmValue());
if (instr->Bit(4) == 0) {
// by immediate
if ((shift == ROR) && (shift_amount == 0)) {
}
} else {
// by register
- int rs = instr->RsField();
+ int rs = instr->RsValue();
shift_amount = get_register(rs) &0xff;
switch (shift) {
case ASR: {
// Addressing Mode 1 - Data-processing operands:
// Get the value based on the shifter_operand with immediate.
-int32_t Simulator::GetImm(Instr* instr, bool* carry_out) {
- int rotate = instr->RotateField() * 2;
- int immed8 = instr->Immed8Field();
+int32_t Simulator::GetImm(Instruction* instr, bool* carry_out) {
+ int rotate = instr->RotateValue() * 2;
+ int immed8 = instr->Immed8Value();
int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
*carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
return imm;
// Addressing Mode 4 - Load and Store Multiple
-void Simulator::HandleRList(Instr* instr, bool load) {
- int rn = instr->RnField();
+void Simulator::HandleRList(Instruction* instr, bool load) {
+ int rn = instr->RnValue();
int32_t rn_val = get_register(rn);
- int rlist = instr->RlistField();
+ int rlist = instr->RlistValue();
int num_regs = count_bits(rlist);
intptr_t start_address = 0;
intptr_t end_address = 0;
switch (instr->PUField()) {
- case 0: {
- // Print("da");
+ case da_x: {
UNIMPLEMENTED();
break;
}
- case 1: {
- // Print("ia");
+ case ia_x: {
start_address = rn_val;
end_address = rn_val + (num_regs * 4) - 4;
rn_val = rn_val + (num_regs * 4);
break;
}
- case 2: {
- // Print("db");
+ case db_x: {
start_address = rn_val - (num_regs * 4);
end_address = rn_val - 4;
rn_val = start_address;
break;
}
- case 3: {
- // Print("ib");
+ case ib_x: {
start_address = rn_val + 4;
end_address = rn_val + (num_regs * 4);
rn_val = end_address;
// Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime.
-void Simulator::SoftwareInterrupt(Instr* instr) {
- int svc = instr->SvcField();
+void Simulator::SoftwareInterrupt(Instruction* instr) {
+ int svc = instr->SvcValue();
switch (svc) {
- case call_rt_redirected: {
+ case kCallRtRedirected: {
// Check if stack is aligned. Error if not aligned is reported below to
// include information on the function called.
bool stack_aligned =
set_pc(get_register(lr));
break;
}
- case break_point: {
+ case kBreakpoint: {
Debugger dbg(this);
dbg.Debug();
break;
Debugger dbg(this);
dbg.Stop(instr);
} else {
- set_pc(get_pc() + 2 * Instr::kInstrSize);
+ set_pc(get_pc() + 2 * Instruction::kInstrSize);
}
} else {
// This is not a valid svc code.
// Stop helper functions.
-bool Simulator::isStopInstruction(Instr* instr) {
- return (instr->Bits(27, 24) == 0xF) && (instr->SvcField() >= stop);
+bool Simulator::isStopInstruction(Instruction* instr) {
+ return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
}
// Instruction types 0 and 1 are both rolled into one function because they
// only differ in the handling of the shifter_operand.
-void Simulator::DecodeType01(Instr* instr) {
- int type = instr->TypeField();
+void Simulator::DecodeType01(Instruction* instr) {
+ int type = instr->TypeValue();
if ((type == 0) && instr->IsSpecialType0()) {
// multiply instruction or extra loads and stores
if (instr->Bits(7, 4) == 9) {
if (instr->Bit(24) == 0) {
// Raw field decoding here. Multiply instructions have their Rd in
// funny places.
- int rn = instr->RnField();
- int rm = instr->RmField();
- int rs = instr->RsField();
+ int rn = instr->RnValue();
+ int rm = instr->RmValue();
+ int rs = instr->RsValue();
int32_t rs_val = get_register(rs);
int32_t rm_val = get_register(rm);
if (instr->Bit(23) == 0) {
// at a very detailed level.)
// Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm");
int rd_hi = rn; // Remap the rn field to the RdHi register.
- int rd_lo = instr->RdField();
+ int rd_lo = instr->RdValue();
int32_t hi_res = 0;
int32_t lo_res = 0;
if (instr->Bit(22) == 1) {
}
} else {
// extra load/store instructions
- int rd = instr->RdField();
- int rn = instr->RnField();
+ int rd = instr->RdValue();
+ int rn = instr->RnValue();
int32_t rn_val = get_register(rn);
int32_t addr = 0;
if (instr->Bit(22) == 0) {
- int rm = instr->RmField();
+ int rm = instr->RmValue();
int32_t rm_val = get_register(rm);
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
ASSERT(!instr->HasW());
addr = rn_val;
set_register(rn, rn_val);
break;
}
- case 1: {
+ case ia_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
ASSERT(!instr->HasW());
addr = rn_val;
set_register(rn, rn_val);
break;
}
- case 2: {
+ case db_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
rn_val -= rm_val;
addr = rn_val;
}
break;
}
- case 3: {
+ case ib_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
rn_val += rm_val;
addr = rn_val;
}
}
} else {
- int32_t imm_val = (instr->ImmedHField() << 4) | instr->ImmedLField();
+ int32_t imm_val = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
ASSERT(!instr->HasW());
addr = rn_val;
set_register(rn, rn_val);
break;
}
- case 1: {
+ case ia_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
ASSERT(!instr->HasW());
addr = rn_val;
set_register(rn, rn_val);
break;
}
- case 2: {
+ case db_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
rn_val -= imm_val;
addr = rn_val;
}
break;
}
- case 3: {
+ case ib_x: {
// Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
rn_val += imm_val;
addr = rn_val;
}
} else if ((type == 0) && instr->IsMiscType0()) {
if (instr->Bits(22, 21) == 1) {
- int rm = instr->RmField();
- switch (instr->Bits(7, 4)) {
+ int rm = instr->RmValue();
+ switch (instr->BitField(7, 4)) {
case BX:
set_pc(get_register(rm));
break;
case BLX: {
uint32_t old_pc = get_pc();
set_pc(get_register(rm));
- set_register(lr, old_pc + Instr::kInstrSize);
+ set_register(lr, old_pc + Instruction::kInstrSize);
break;
}
case BKPT: {
UNIMPLEMENTED();
}
} else if (instr->Bits(22, 21) == 3) {
- int rm = instr->RmField();
- int rd = instr->RdField();
- switch (instr->Bits(7, 4)) {
+ int rm = instr->RmValue();
+ int rd = instr->RdValue();
+ switch (instr->BitField(7, 4)) {
case CLZ: {
uint32_t bits = get_register(rm);
int leading_zeros = 0;
UNIMPLEMENTED();
}
} else {
- int rd = instr->RdField();
- int rn = instr->RnField();
+ int rd = instr->RdValue();
+ int rn = instr->RnValue();
int32_t rn_val = get_register(rn);
int32_t shifter_operand = 0;
bool shifter_carry_out = 0;
if (type == 0) {
shifter_operand = GetShiftRm(instr, &shifter_carry_out);
} else {
- ASSERT(instr->TypeField() == 1);
+ ASSERT(instr->TypeValue() == 1);
shifter_operand = GetImm(instr, &shifter_carry_out);
}
int32_t alu_out;
SetCFlag(shifter_carry_out);
} else {
// Format(instr, "movw'cond 'rd, 'imm").
- alu_out = instr->ImmedMovwMovtField();
+ alu_out = instr->ImmedMovwMovtValue();
set_register(rd, alu_out);
}
break;
} else {
// Format(instr, "movt'cond 'rd, 'imm").
alu_out = (get_register(rd) & 0xffff) |
- (instr->ImmedMovwMovtField() << 16);
+ (instr->ImmedMovwMovtValue() << 16);
set_register(rd, alu_out);
}
break;
}
-void Simulator::DecodeType2(Instr* instr) {
- int rd = instr->RdField();
- int rn = instr->RnField();
+void Simulator::DecodeType2(Instruction* instr) {
+ int rd = instr->RdValue();
+ int rn = instr->RnValue();
int32_t rn_val = get_register(rn);
- int32_t im_val = instr->Offset12Field();
+ int32_t im_val = instr->Offset12Value();
int32_t addr = 0;
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
// Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
ASSERT(!instr->HasW());
addr = rn_val;
set_register(rn, rn_val);
break;
}
- case 1: {
+ case ia_x: {
// Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
ASSERT(!instr->HasW());
addr = rn_val;
set_register(rn, rn_val);
break;
}
- case 2: {
+ case db_x: {
// Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
rn_val -= im_val;
addr = rn_val;
}
break;
}
- case 3: {
+ case ib_x: {
// Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
rn_val += im_val;
addr = rn_val;
}
-void Simulator::DecodeType3(Instr* instr) {
- int rd = instr->RdField();
- int rn = instr->RnField();
+void Simulator::DecodeType3(Instruction* instr) {
+ int rd = instr->RdValue();
+ int rn = instr->RnValue();
int32_t rn_val = get_register(rn);
bool shifter_carry_out = 0;
int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
int32_t addr = 0;
switch (instr->PUField()) {
- case 0: {
+ case da_x: {
ASSERT(!instr->HasW());
Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
UNIMPLEMENTED();
break;
}
- case 1: {
+ case ia_x: {
if (instr->HasW()) {
ASSERT(instr->Bits(5, 4) == 0x1);
int32_t sat_val = (1 << sat_pos) - 1;
int32_t shift = instr->Bits(11, 7);
int32_t shift_type = instr->Bit(6);
- int32_t rm_val = get_register(instr->RmField());
+ int32_t rm_val = get_register(instr->RmValue());
if (shift_type == 0) { // LSL
rm_val <<= shift;
} else { // ASR
}
break;
}
- case 2: {
+ case db_x: {
// Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
addr = rn_val - shifter_operand;
if (instr->HasW()) {
}
break;
}
- case 3: {
+ case ib_x: {
if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
if (instr->Bit(22)) {
// ubfx - unsigned bitfield extract.
uint32_t rm_val =
- static_cast<uint32_t>(get_register(instr->RmField()));
+ static_cast<uint32_t>(get_register(instr->RmValue()));
uint32_t extr_val = rm_val << (31 - msbit);
extr_val = extr_val >> (31 - widthminus1);
- set_register(instr->RdField(), extr_val);
+ set_register(instr->RdValue(), extr_val);
} else {
// sbfx - signed bitfield extract.
- int32_t rm_val = get_register(instr->RmField());
+ int32_t rm_val = get_register(instr->RmValue());
int32_t extr_val = rm_val << (31 - msbit);
extr_val = extr_val >> (31 - widthminus1);
- set_register(instr->RdField(), extr_val);
+ set_register(instr->RdValue(), extr_val);
}
} else {
UNREACHABLE();
if (msbit >= lsbit) {
// bfc or bfi - bitfield clear/insert.
uint32_t rd_val =
- static_cast<uint32_t>(get_register(instr->RdField()));
+ static_cast<uint32_t>(get_register(instr->RdValue()));
uint32_t bitcount = msbit - lsbit + 1;
uint32_t mask = (1 << bitcount) - 1;
rd_val &= ~(mask << lsbit);
- if (instr->RmField() != 15) {
+ if (instr->RmValue() != 15) {
// bfi - bitfield insert.
uint32_t rm_val =
- static_cast<uint32_t>(get_register(instr->RmField()));
+ static_cast<uint32_t>(get_register(instr->RmValue()));
rm_val &= mask;
rd_val |= rm_val << lsbit;
}
- set_register(instr->RdField(), rd_val);
+ set_register(instr->RdValue(), rd_val);
} else {
UNREACHABLE();
}
}
-void Simulator::DecodeType4(Instr* instr) {
+void Simulator::DecodeType4(Instruction* instr) {
ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode
if (instr->HasL()) {
// Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
}
-void Simulator::DecodeType5(Instr* instr) {
+void Simulator::DecodeType5(Instruction* instr) {
// Format(instr, "b'l'cond 'target");
- int off = (instr->SImmed24Field() << 2);
+ int off = (instr->SImmed24Value() << 2);
intptr_t pc_address = get_pc();
if (instr->HasLink()) {
- set_register(lr, pc_address + Instr::kInstrSize);
+ set_register(lr, pc_address + Instruction::kInstrSize);
}
int pc_reg = get_register(pc);
set_pc(pc_reg + off);
}
-void Simulator::DecodeType6(Instr* instr) {
+void Simulator::DecodeType6(Instruction* instr) {
DecodeType6CoprocessorIns(instr);
}
-void Simulator::DecodeType7(Instr* instr) {
+void Simulator::DecodeType7(Instruction* instr) {
if (instr->Bit(24) == 1) {
SoftwareInterrupt(instr);
} else {
}
-// void Simulator::DecodeTypeVFP(Instr* instr)
+// void Simulator::DecodeTypeVFP(Instruction* instr)
// The Following ARMv7 VFPv instructions are currently supported.
// vmov :Sn = Rt
// vmov :Rt = Sn
// vcmp(Dd, Dm)
// vmrs
// Dd = vsqrt(Dm)
-void Simulator::DecodeTypeVFP(Instr* instr) {
- ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
+void Simulator::DecodeTypeVFP(Instruction* instr) {
+ ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
ASSERT(instr->Bits(11, 9) == 0x5);
// Obtain double precision register codes.
- int vm = instr->VFPMRegCode(kDoublePrecision);
- int vd = instr->VFPDRegCode(kDoublePrecision);
- int vn = instr->VFPNRegCode(kDoublePrecision);
+ int vm = instr->VFPMRegValue(kDoublePrecision);
+ int vd = instr->VFPDRegValue(kDoublePrecision);
+ int vn = instr->VFPNRegValue(kDoublePrecision);
if (instr->Bit(4) == 0) {
- if (instr->Opc1Field() == 0x7) {
+ if (instr->Opc1Value() == 0x7) {
// Other data processing instructions
- if ((instr->Opc2Field() == 0x0) && (instr->Opc3Field() == 0x1)) {
+ if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
// vmov register to register.
- if (instr->SzField() == 0x1) {
- int m = instr->VFPMRegCode(kDoublePrecision);
- int d = instr->VFPDRegCode(kDoublePrecision);
+ if (instr->SzValue() == 0x1) {
+ int m = instr->VFPMRegValue(kDoublePrecision);
+ int d = instr->VFPDRegValue(kDoublePrecision);
set_d_register_from_double(d, get_double_from_d_register(m));
} else {
- int m = instr->VFPMRegCode(kSinglePrecision);
- int d = instr->VFPDRegCode(kSinglePrecision);
+ int m = instr->VFPMRegValue(kSinglePrecision);
+ int d = instr->VFPDRegValue(kSinglePrecision);
set_s_register_from_float(d, get_float_from_s_register(m));
}
- } else if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) {
+ } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
DecodeVCVTBetweenDoubleAndSingle(instr);
- } else if ((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) {
+ } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if (((instr->Opc2Field() >> 1) == 0x6) &&
- (instr->Opc3Field() & 0x1)) {
+ } else if (((instr->Opc2Value() >> 1) == 0x6) &&
+ (instr->Opc3Value() & 0x1)) {
DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
- (instr->Opc3Field() & 0x1)) {
+ } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
+ (instr->Opc3Value() & 0x1)) {
DecodeVCMP(instr);
- } else if (((instr->Opc2Field() == 0x1)) && (instr->Opc3Field() == 0x3)) {
+ } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
// vsqrt
double dm_value = get_double_from_d_register(vm);
double dd_value = sqrt(dm_value);
set_d_register_from_double(vd, dd_value);
- } else if (instr->Opc3Field() == 0x0) {
+ } else if (instr->Opc3Value() == 0x0) {
// vmov immediate.
- if (instr->SzField() == 0x1) {
+ if (instr->SzValue() == 0x1) {
set_d_register_from_double(vd, instr->DoubleImmedVmov());
} else {
UNREACHABLE(); // Not used by v8.
} else {
UNREACHABLE(); // Not used by V8.
}
- } else if (instr->Opc1Field() == 0x3) {
- if (instr->SzField() != 0x1) {
+ } else if (instr->Opc1Value() == 0x3) {
+ if (instr->SzValue() != 0x1) {
UNREACHABLE(); // Not used by V8.
}
- if (instr->Opc3Field() & 0x1) {
+ if (instr->Opc3Value() & 0x1) {
// vsub
double dn_value = get_double_from_d_register(vn);
double dm_value = get_double_from_d_register(vm);
double dd_value = dn_value + dm_value;
set_d_register_from_double(vd, dd_value);
}
- } else if ((instr->Opc1Field() == 0x2) && !(instr->Opc3Field() & 0x1)) {
+ } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
// vmul
- if (instr->SzField() != 0x1) {
+ if (instr->SzValue() != 0x1) {
UNREACHABLE(); // Not used by V8.
}
double dm_value = get_double_from_d_register(vm);
double dd_value = dn_value * dm_value;
set_d_register_from_double(vd, dd_value);
- } else if ((instr->Opc1Field() == 0x4) && !(instr->Opc3Field() & 0x1)) {
+ } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
// vdiv
- if (instr->SzField() != 0x1) {
+ if (instr->SzValue() != 0x1) {
UNREACHABLE(); // Not used by V8.
}
UNIMPLEMENTED(); // Not used by V8.
}
} else {
- if ((instr->VCField() == 0x0) &&
- (instr->VAField() == 0x0)) {
+ if ((instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x0)) {
DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
- } else if ((instr->VLField() == 0x1) &&
- (instr->VCField() == 0x0) &&
- (instr->VAField() == 0x7) &&
+ } else if ((instr->VLValue() == 0x1) &&
+ (instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x7) &&
(instr->Bits(19, 16) == 0x1)) {
// vmrs
- uint32_t rt = instr->RtField();
+ uint32_t rt = instr->RtValue();
if (rt == 0xF) {
Copy_FPSCR_to_APSR();
} else {
(FPSCR_rounding_mode_ << 22);
set_register(rt, fpscr);
}
- } else if ((instr->VLField() == 0x0) &&
- (instr->VCField() == 0x0) &&
- (instr->VAField() == 0x7) &&
+ } else if ((instr->VLValue() == 0x0) &&
+ (instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x7) &&
(instr->Bits(19, 16) == 0x1)) {
// vmsr
- uint32_t rt = instr->RtField();
+ uint32_t rt = instr->RtValue();
if (rt == pc) {
UNREACHABLE();
} else {
}
-void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr) {
- ASSERT((instr->Bit(4) == 1) && (instr->VCField() == 0x0) &&
- (instr->VAField() == 0x0));
+void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
+ Instruction* instr) {
+ ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
+ (instr->VAValue() == 0x0));
- int t = instr->RtField();
- int n = instr->VFPNRegCode(kSinglePrecision);
- bool to_arm_register = (instr->VLField() == 0x1);
+ int t = instr->RtValue();
+ int n = instr->VFPNRegValue(kSinglePrecision);
+ bool to_arm_register = (instr->VLValue() == 0x1);
if (to_arm_register) {
int32_t int_value = get_sinteger_from_s_register(n);
}
-void Simulator::DecodeVCMP(Instr* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
- ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
- (instr->Opc3Field() & 0x1));
+void Simulator::DecodeVCMP(Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
+ (instr->Opc3Value() & 0x1));
// Comparison.
VFPRegPrecision precision = kSinglePrecision;
- if (instr->SzField() == 1) {
+ if (instr->SzValue() == 1) {
precision = kDoublePrecision;
}
- int d = instr->VFPDRegCode(precision);
+ int d = instr->VFPDRegValue(precision);
int m = 0;
- if (instr->Opc2Field() == 0x4) {
- m = instr->VFPMRegCode(precision);
+ if (instr->Opc2Value() == 0x4) {
+ m = instr->VFPMRegValue(precision);
}
if (precision == kDoublePrecision) {
double dd_value = get_double_from_d_register(d);
double dm_value = 0.0;
- if (instr->Opc2Field() == 0x4) {
+ if (instr->Opc2Value() == 0x4) {
dm_value = get_double_from_d_register(m);
}
}
-void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instr* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
- ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3));
+void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
VFPRegPrecision dst_precision = kDoublePrecision;
VFPRegPrecision src_precision = kSinglePrecision;
- if (instr->SzField() == 1) {
+ if (instr->SzValue() == 1) {
dst_precision = kSinglePrecision;
src_precision = kDoublePrecision;
}
- int dst = instr->VFPDRegCode(dst_precision);
- int src = instr->VFPMRegCode(src_precision);
+ int dst = instr->VFPDRegValue(dst_precision);
+ int src = instr->VFPMRegValue(src_precision);
if (dst_precision == kSinglePrecision) {
double val = get_double_from_d_register(src);
}
-void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
- ASSERT(((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) ||
- (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1)));
+void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
+ (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
// Conversion between floating-point and integer.
bool to_integer = (instr->Bit(18) == 1);
VFPRegPrecision src_precision = kSinglePrecision;
- if (instr->SzField() == 1) {
+ if (instr->SzValue() == 1) {
src_precision = kDoublePrecision;
}
mode = RZ;
}
- int dst = instr->VFPDRegCode(kSinglePrecision);
- int src = instr->VFPMRegCode(src_precision);
+ int dst = instr->VFPDRegValue(kSinglePrecision);
+ int src = instr->VFPMRegValue(src_precision);
int32_t kMaxInt = v8::internal::kMaxInt;
int32_t kMinInt = v8::internal::kMinInt;
switch (mode) {
} else {
bool unsigned_integer = (instr->Bit(7) == 0);
- int dst = instr->VFPDRegCode(src_precision);
- int src = instr->VFPMRegCode(kSinglePrecision);
+ int dst = instr->VFPDRegValue(src_precision);
+ int src = instr->VFPMRegValue(kSinglePrecision);
int val = get_sinteger_from_s_register(src);
}
-// void Simulator::DecodeType6CoprocessorIns(Instr* instr)
+// void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
// Decode Type 6 coprocessor instructions.
// Dm = vmov(Rt, Rt2)
// <Rt, Rt2> = vmov(Dm)
// Ddst = MEM(Rbase + 4*offset).
// MEM(Rbase + 4*offset) = Dsrc.
-void Simulator::DecodeType6CoprocessorIns(Instr* instr) {
- ASSERT((instr->TypeField() == 6));
+void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
+ ASSERT((instr->TypeValue() == 6));
- if (instr->CoprocessorField() == 0xA) {
- switch (instr->OpcodeField()) {
+ if (instr->CoprocessorValue() == 0xA) {
+ switch (instr->OpcodeValue()) {
case 0x8:
case 0xA:
case 0xC:
case 0xE: { // Load and store single precision float to memory.
- int rn = instr->RnField();
- int vd = instr->VFPDRegCode(kSinglePrecision);
- int offset = instr->Immed8Field();
+ int rn = instr->RnValue();
+ int vd = instr->VFPDRegValue(kSinglePrecision);
+ int offset = instr->Immed8Value();
if (!instr->HasU()) {
offset = -offset;
}
UNIMPLEMENTED(); // Not used by V8.
break;
}
- } else if (instr->CoprocessorField() == 0xB) {
- switch (instr->OpcodeField()) {
+ } else if (instr->CoprocessorValue() == 0xB) {
+ switch (instr->OpcodeValue()) {
case 0x2:
// Load and store double to two GP registers
if (instr->Bits(7, 4) != 0x1) {
UNIMPLEMENTED(); // Not used by V8.
} else {
- int rt = instr->RtField();
- int rn = instr->RnField();
- int vm = instr->VmField();
+ int rt = instr->RtValue();
+ int rn = instr->RnValue();
+ int vm = instr->VmValue();
if (instr->HasL()) {
int32_t rt_int_value = get_sinteger_from_s_register(2*vm);
int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1);
break;
case 0x8:
case 0xC: { // Load and store double to memory.
- int rn = instr->RnField();
- int vd = instr->VdField();
- int offset = instr->Immed8Field();
+ int rn = instr->RnValue();
+ int vd = instr->VdValue();
+ int offset = instr->Immed8Value();
if (!instr->HasU()) {
offset = -offset;
}
// Executes the current instruction.
-void Simulator::InstructionDecode(Instr* instr) {
+void Simulator::InstructionDecode(Instruction* instr) {
if (v8::internal::FLAG_check_icache) {
CheckICache(instr);
}
reinterpret_cast<byte*>(instr));
PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
}
- if (instr->ConditionField() == special_condition) {
+ if (instr->ConditionField() == kSpecialCondition) {
UNIMPLEMENTED();
} else if (ConditionallyExecute(instr)) {
- switch (instr->TypeField()) {
+ switch (instr->TypeValue()) {
case 0:
case 1: {
DecodeType01(instr);
// If the instruction is a non taken conditional stop, we need to skip the
// inlined message address.
} else if (instr->IsStop()) {
- set_pc(get_pc() + 2 * Instr::kInstrSize);
+ set_pc(get_pc() + 2 * Instruction::kInstrSize);
}
if (!pc_modified_) {
- set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
+ set_register(pc, reinterpret_cast<int32_t>(instr)
+ + Instruction::kInstrSize);
}
}
// Fast version of the dispatch loop without checking whether the simulator
// should be stopping at a particular executed instruction.
while (program_counter != end_sim_pc) {
- Instr* instr = reinterpret_cast<Instr*>(program_counter);
+ Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
icount_++;
InstructionDecode(instr);
program_counter = get_pc();
// FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
// we reach the particular instuction count.
while (program_counter != end_sim_pc) {
- Instr* instr = reinterpret_cast<Instr*>(program_counter);
+ Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
icount_++;
if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
Debugger dbg(this);
return address;
}
-} } // namespace assembler::arm
+} } // namespace v8::internal
#endif // USE_SIMULATOR
#include "constants-arm.h"
#include "hashmap.h"
-namespace assembler {
-namespace arm {
+namespace v8 {
+namespace internal {
class CachePage {
public:
};
// Unsupported instructions use Format to print an error and stop execution.
- void Format(Instr* instr, const char* format);
+ void Format(Instruction* instr, const char* format);
// Checks if the current instruction should be executed based on its
// condition bits.
- bool ConditionallyExecute(Instr* instr);
+ bool ConditionallyExecute(Instruction* instr);
// Helper functions to set the conditional flags in the architecture state.
void SetNZFlags(int32_t val);
void Copy_FPSCR_to_APSR();
// Helper functions to decode common "addressing" modes
- int32_t GetShiftRm(Instr* instr, bool* carry_out);
- int32_t GetImm(Instr* instr, bool* carry_out);
- void HandleRList(Instr* instr, bool load);
- void SoftwareInterrupt(Instr* instr);
+ int32_t GetShiftRm(Instruction* instr, bool* carry_out);
+ int32_t GetImm(Instruction* instr, bool* carry_out);
+ void HandleRList(Instruction* instr, bool load);
+ void SoftwareInterrupt(Instruction* instr);
// Stop helper functions.
- inline bool isStopInstruction(Instr* instr);
+ inline bool isStopInstruction(Instruction* instr);
inline bool isWatchedStop(uint32_t bkpt_code);
inline bool isEnabledStop(uint32_t bkpt_code);
inline void EnableStop(uint32_t bkpt_code);
inline void WriteB(int32_t addr, uint8_t value);
inline void WriteB(int32_t addr, int8_t value);
- inline uint16_t ReadHU(int32_t addr, Instr* instr);
- inline int16_t ReadH(int32_t addr, Instr* instr);
+ inline uint16_t ReadHU(int32_t addr, Instruction* instr);
+ inline int16_t ReadH(int32_t addr, Instruction* instr);
// Note: Overloaded on the sign of the value.
- inline void WriteH(int32_t addr, uint16_t value, Instr* instr);
- inline void WriteH(int32_t addr, int16_t value, Instr* instr);
+ inline void WriteH(int32_t addr, uint16_t value, Instruction* instr);
+ inline void WriteH(int32_t addr, int16_t value, Instruction* instr);
- inline int ReadW(int32_t addr, Instr* instr);
- inline void WriteW(int32_t addr, int value, Instr* instr);
+ inline int ReadW(int32_t addr, Instruction* instr);
+ inline void WriteW(int32_t addr, int value, Instruction* instr);
int32_t* ReadDW(int32_t addr);
void WriteDW(int32_t addr, int32_t value1, int32_t value2);
// Executing is handled based on the instruction type.
- void DecodeType01(Instr* instr); // both type 0 and type 1 rolled into one
- void DecodeType2(Instr* instr);
- void DecodeType3(Instr* instr);
- void DecodeType4(Instr* instr);
- void DecodeType5(Instr* instr);
- void DecodeType6(Instr* instr);
- void DecodeType7(Instr* instr);
+ // Both type 0 and type 1 rolled into one.
+ void DecodeType01(Instruction* instr);
+ void DecodeType2(Instruction* instr);
+ void DecodeType3(Instruction* instr);
+ void DecodeType4(Instruction* instr);
+ void DecodeType5(Instruction* instr);
+ void DecodeType6(Instruction* instr);
+ void DecodeType7(Instruction* instr);
// Support for VFP.
- void DecodeTypeVFP(Instr* instr);
- void DecodeType6CoprocessorIns(Instr* instr);
+ void DecodeTypeVFP(Instruction* instr);
+ void DecodeType6CoprocessorIns(Instruction* instr);
- void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr);
- void DecodeVCMP(Instr* instr);
- void DecodeVCVTBetweenDoubleAndSingle(Instr* instr);
- void DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr);
+ void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
+ void DecodeVCMP(Instruction* instr);
+ void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
+ void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
// Executes one instruction.
- void InstructionDecode(Instr* instr);
+ void InstructionDecode(Instruction* instr);
// ICache.
- static void CheckICache(Instr* instr);
+ static void CheckICache(Instruction* instr);
static void FlushOnePage(intptr_t start, int size);
static CachePage* GetCachePage(void* page);
static v8::internal::HashMap* i_cache_;
// Registered breakpoints.
- Instr* break_pc_;
- instr_t break_instr_;
+ Instruction* break_pc_;
+ Instr break_instr_;
// A stop is watched if its code is less than kNumOfWatchedStops.
// Only watched stops support enabling/disabling and the counter feature.
// instruction, if bit 31 of watched_stops[code].count is unset.
// The value watched_stops[code].count & ~(1 << 31) indicates how many times
// the breakpoint was hit or gone through.
- struct StopCoundAndDesc {
+ struct StopCountAndDesc {
uint32_t count;
char* desc;
};
- StopCoundAndDesc watched_stops[kNumOfWatchedStops];
+ StopCountAndDesc watched_stops[kNumOfWatchedStops];
};
-} } // namespace assembler::arm
-
-
-namespace v8 {
-namespace internal {
// When running with the simulator transition into simulated execution at this
// point.
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
- reinterpret_cast<Object*>(assembler::arm::Simulator::current()->Call( \
+ reinterpret_cast<Object*>(Simulator::current()->Call( \
FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
- assembler::arm::Simulator::current()->Call( \
+ Simulator::current()->Call( \
FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
class SimulatorStack : public v8::internal::AllStatic {
public:
static inline uintptr_t JsLimitFromCLimit(uintptr_t c_limit) {
- return assembler::arm::Simulator::current()->StackLimit();
+ return Simulator::current()->StackLimit();
}
static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
- assembler::arm::Simulator* sim = assembler::arm::Simulator::current();
+ Simulator* sim = Simulator::current();
return sim->PushAddress(try_catch_address);
}
static inline void UnregisterCTryCatch() {
- assembler::arm::Simulator::current()->PopAddress();
+ Simulator::current()->PopAddress();
}
};
handler_ = 0;
#ifdef USE_SIMULATOR
#ifdef V8_TARGET_ARCH_ARM
- simulator_ = assembler::arm::Simulator::current();
+ simulator_ = Simulator::current();
#elif V8_TARGET_ARCH_MIPS
simulator_ = assembler::mips::Simulator::current();
#endif
// thread_local_ is restored on a separate OS thread.
#ifdef USE_SIMULATOR
#ifdef V8_TARGET_ARCH_ARM
- thread_local_.simulator_ = assembler::arm::Simulator::current();
+ thread_local_.simulator_ = Simulator::current();
#elif V8_TARGET_ARCH_MIPS
thread_local_.simulator_ = assembler::mips::Simulator::current();
#endif
#ifdef USE_SIMULATOR
#ifdef V8_TARGET_ARCH_ARM
- assembler::arm::Simulator* simulator_;
+ Simulator* simulator_;
#elif V8_TARGET_ARCH_MIPS
assembler::mips::Simulator* simulator_;
#endif
// Initialize other runtime facilities
#if defined(USE_SIMULATOR)
#if defined(V8_TARGET_ARCH_ARM)
- ::assembler::arm::Simulator::Initialize();
+ Simulator::Initialize();
#elif defined(V8_TARGET_ARCH_MIPS)
::assembler::mips::Simulator::Initialize();
#endif