void Assembler::mov_b(Register dst, const Operand& src) {
+ ASSERT(dst.code() < 4);
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0x8A);
void Assembler::mov_b(const Operand& dst, Register src) {
+ ASSERT(src.code() < 4);
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0x88);
void Assembler::subb(Register dst, const Operand& src) {
+ ASSERT(dst.code() < 4);
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0x2A);
}
-void Assembler::loope(Label* L) {
- EnsureSpace ensure_space(this);
- last_pc_ = pc_;
- // Only short backward jumps.
- ASSERT(L->is_bound());
- int offs = L->pos() - pc_offset();
- const int kLoopInstructionSize = 2;
- ASSERT(is_int8(offs - kLoopInstructionSize));
- EMIT(0xE1);
- EMIT((offs - kLoopInstructionSize) & 0xFF);
-}
-
// FPU instructions
-
void Assembler::fld(int i) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
void j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint = no_hint);
void j(Condition cc, Handle<Code> code, Hint hint = no_hint);
- // Loop instruction using ecx as counter.
- void loope(Label* L);
-
// Floating-point operations
void fld(int i);
void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
Register left,
Register right,
- Register counter,
Register scratch1,
- Register scratch2) {
- ASSERT(counter.is(ecx));
+ Register scratch2,
+ Register scratch3) {
Label compare_lengths, compare_lengths_1;
// Find minimum length. If either length is zero just compare lengths.
- __ mov(counter, FieldOperand(left, String::kLengthOffset));
- __ test(counter, Operand(counter));
- __ j(zero, &compare_lengths_1);
- __ mov(scratch1, FieldOperand(right, String::kLengthOffset));
+ __ mov(scratch1, FieldOperand(left, String::kLengthOffset));
__ test(scratch1, Operand(scratch1));
__ j(zero, &compare_lengths_1);
- __ cmp(counter, Operand(scratch1));
+ __ mov(scratch2, FieldOperand(right, String::kLengthOffset));
+ __ test(scratch2, Operand(scratch2));
+ __ j(zero, &compare_lengths_1);
+ __ cmp(scratch1, Operand(scratch2));
if (CpuFeatures::IsSupported(CMOV)) {
CpuFeatures::Scope use_cmov(CMOV);
- __ cmov(greater, counter, Operand(scratch1));
+ __ cmov(greater, scratch1, Operand(scratch2));
} else {
Label l;
__ j(less, &l);
- __ mov(counter, scratch1);
+ __ mov(scratch1, scratch2);
__ bind(&l);
}
Label result_greater, result_less;
Label loop;
// Compare next character.
- __ mov(scratch2, Immediate(-1)); // Index into strings.
+ __ mov(scratch3, Immediate(-1)); // Index into strings.
__ bind(&loop);
// Compare characters.
- __ add(Operand(scratch2), Immediate(1));
- __ mov_b(scratch1, Operand(left,
- scratch2,
+ Label character_compare_done;
+ __ add(Operand(scratch3), Immediate(1));
+ __ mov_b(scratch2, Operand(left,
+ scratch3,
times_1,
SeqAsciiString::kHeaderSize - kHeapObjectTag));
- __ subb(scratch1, Operand(right,
- scratch2,
+ __ subb(scratch2, Operand(right,
+ scratch3,
times_1,
SeqAsciiString::kHeaderSize - kHeapObjectTag));
- __ loope(&loop);
+ __ j(not_equal, &character_compare_done);
+ __ sub(Operand(scratch1), Immediate(1));
+ __ j(not_zero, &loop);
// If min length characters match compare lengths otherwise last character
// compare is the result.
+ __ bind(&character_compare_done);
__ j(equal, &compare_lengths);
__ j(less, &result_less);
__ jmp(&result_greater);
// Compare lengths.
Label result_not_equal;
__ bind(&compare_lengths);
- __ mov(counter, FieldOperand(left, String::kLengthOffset));
+ __ mov(scratch1, FieldOperand(left, String::kLengthOffset));
__ bind(&compare_lengths_1);
- __ sub(counter, FieldOperand(right, String::kLengthOffset));
+ __ sub(scratch1, FieldOperand(right, String::kLengthOffset));
__ j(not_zero, &result_not_equal);
// Result is EQUAL.
}
// Compare two flat ascii strings and returns result in eax after popping two
- // arguments from the stack. Due to the instructions used there are certain
- // constraints on the registers that can be passed.
- // counter must be ecx
- // scratch1 most be one of eax, ebx or edx
+ // arguments from the stack.
static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
Register left,
Register right,
- Register counter,
Register scratch1,
- Register scratch2);
+ Register scratch2,
+ Register scratch3);
private:
Major MajorKey() { return StringCompare; }
};
-static const char* loop_mnem[] = {
- "loopne", "loope", "loop"
-};
-
-
static const char* set_conditional_mnem[] = {
/*0*/ "seto", "setno", "setc", "setnc",
/*4*/ "setz", "setnz", "setna", "seta",
ZERO_OPERANDS_INSTR,
TWO_OPERANDS_INSTR,
JUMP_CONDITIONAL_SHORT_INSTR,
- LOOP_INSTR,
REGISTER_INSTR,
MOVE_REG_INSTR,
CALL_JUMP_INSTR,
byte end,
const char* mnem);
void AddJumpConditionalShort();
- void AddLoop();
};
CopyTable(call_jump_instr, CALL_JUMP_INSTR);
CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
AddJumpConditionalShort();
- AddLoop();
SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
}
-void InstructionTable::AddLoop() {
- for (byte b = 0xE0; b <= 0xE2; b++) {
- InstructionDesc* id = &instructions_[b];
- ASSERT_EQ(NO_INSTR, id->type); // Information not already entered.
- id->mnem = loop_mnem[b & 0x03];
- id->type = LOOP_INSTR;
- }
-}
-
-
static InstructionTable instruction_table;
int JumpShort(byte* data);
int JumpConditional(byte* data, const char* comment);
int JumpConditionalShort(byte* data, const char* comment);
- int Loop(byte* data);
int SetCC(byte* data);
int CMov(byte* data);
int FPUInstruction(byte* data);
// Returns number of bytes used, including *data.
-int DisassemblerIA32::Loop(byte* data) {
- byte cond = *data & 0x03;
- byte b = *(data+1);
- byte* dest = data + static_cast<int8_t>(b) + 2;
- const char* mnem = loop_mnem[cond];
- AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
- return 2;
-}
-
-
-// Returns number of bytes used, including *data.
int DisassemblerIA32::SetCC(byte* data) {
ASSERT_EQ(0x0F, *data);
byte cond = *(data+1) & 0x0F;
data += JumpConditionalShort(data, branch_hint);
break;
- case LOOP_INSTR:
- data += Loop(data);
- break;
-
case REGISTER_INSTR:
AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
data++;
case 0x80:
{ data++;
- AppendToBuffer("%s ", "cmpb");
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ const char* mnem = NULL;
+ printf("%d\n", regop);
+ switch (regop) {
+ case 5: mnem = "subb"; break;
+ case 7: mnem = "cmpb"; break;
+ default: UnimplementedInstruction();
+ }
+ AppendToBuffer("%s ", mnem);
data += PrintRightOperand(data);
int32_t imm = *data;
AppendToBuffer(",0x%x", imm);
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
+ } else if (*data == 0x6F) {
+ data++;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("movdqa %s,", NameOfXMMRegister(regop));
+ data += PrintRightOperand(data);
+ } else if (*data == 0x7F) {
+ AppendToBuffer("movdqa ");
+ data++;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ data += PrintRightOperand(data);
+ AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else {
UnimplementedInstruction();
}
data += 2;
break;
+ case 0x2C:
+ AppendToBuffer("subb eax,0x%x", *reinterpret_cast<uint8_t*>(data+1));
+ data += 2;
+ break;
+
case 0xA9:
AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1));
data += 5;
break;
case 0xF3:
- if (*(data+1) == 0x0F && *(data+2) == 0x2C) {
- data += 3;
- data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data);
+ if (*(data+1) == 0x0F) {
+ if (*(data+2) == 0x2C) {
+ data += 3;
+ data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data);
+ } else if (*(data+2) == 0x6F) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop));
+ data += PrintRightOperand(data);
+ } else if (*(data+2) == 0x7F) {
+ AppendToBuffer("movdqu ");
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ data += PrintRightOperand(data);
+ AppendToBuffer(",%s", NameOfXMMRegister(regop));
+ } else {
+ UnimplementedInstruction();
+ }
+ } else if (*(data+1) == 0xA5) {
+ data += 2;
+ AppendToBuffer("rep_movs");
} else {
UnimplementedInstruction();
}
}
int instr_len = data - instr;
+ if (instr_len == 0) {
+ printf("%02x", *data);
+ }
ASSERT(instr_len > 0); // Ensure progress.
int outp = 0;
TEST(DisasmIa320) {
InitializeVM();
v8::HandleScope scope;
- v8::internal::byte buffer[1024];
+ v8::internal::byte buffer[2048];
Assembler assm(buffer, sizeof buffer);
DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging)
__ sub(Operand(ebx), Immediate(12));
__ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
+ __ subb(Operand(edx, ecx, times_4, 10000), 100);
+ __ subb(Operand(eax), 100);
+ __ subb(eax, Operand(edx, ecx, times_4, 10000));
__ xor_(ebx, 12345);
__ imul(edx, ecx, 12);
__ imul(edx, ecx, 1000);
-
+ __ rep_movs();
__ sub(edx, Operand(ebx, ecx, times_4, 10000));
__ sub(edx, Operand(ebx));
__ movdbl(xmm1, Operand(ebx, ecx, times_4, 10000));
__ movdbl(Operand(ebx, ecx, times_4, 10000), xmm1);
__ comisd(xmm0, xmm1);
+
+ // 128 bit move instructions.
+ __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
+ __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
+ __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
+ __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
}
// cmov.