| Index: src/ia32/lithium-codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/lithium-codegen-ia32.cc (revision 10035)
|
| +++ src/ia32/lithium-codegen-ia32.cc (working copy)
|
| @@ -33,6 +33,7 @@
|
| #include "code-stubs.h"
|
| #include "deoptimizer.h"
|
| #include "stub-cache.h"
|
| +#include "codegen.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -1683,6 +1684,31 @@
|
| }
|
|
|
|
|
| +Condition LCodeGen::EmitIsString(Register input,
|
| + Register temp1,
|
| + Label* is_not_string) {
|
| + __ JumpIfSmi(input, is_not_string);
|
| +
|
| + Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
|
| +
|
| + return cond;
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
|
| + Register reg = ToRegister(instr->InputAt(0));
|
| + Register temp = ToRegister(instr->TempAt(0));
|
| +
|
| + int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| + int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| + Label* false_label = chunk_->GetAssemblyLabel(false_block);
|
| +
|
| + Condition true_cond = EmitIsString(reg, temp, false_label);
|
| +
|
| + EmitBranch(true_block, false_block, true_cond);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
|
| Operand input = ToOperand(instr->InputAt(0));
|
|
|
| @@ -1710,6 +1736,41 @@
|
| }
|
|
|
|
|
| +static Condition ComputeCompareCondition(Token::Value op) {
|
| + switch (op) {
|
| + case Token::EQ_STRICT:
|
| + case Token::EQ:
|
| + return equal;
|
| + case Token::LT:
|
| + return less;
|
| + case Token::GT:
|
| + return greater;
|
| + case Token::LTE:
|
| + return less_equal;
|
| + case Token::GTE:
|
| + return greater_equal;
|
| + default:
|
| + UNREACHABLE();
|
| + return no_condition;
|
| + }
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
| + Token::Value op = instr->op();
|
| + int true_block = chunk_->LookupDestination(instr->true_block_id());
|
| + int false_block = chunk_->LookupDestination(instr->false_block_id());
|
| +
|
| + Handle<Code> ic = CompareIC::GetUninitialized(op);
|
| + CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
| +
|
| + Condition condition = ComputeCompareCondition(op);
|
| + __ test(eax, Operand(eax));
|
| +
|
| + EmitBranch(true_block, false_block, condition);
|
| +}
|
| +
|
| +
|
| static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
|
| InstanceType from = instr->from();
|
| InstanceType to = instr->to();
|
| @@ -1987,26 +2048,6 @@
|
| }
|
|
|
|
|
| -static Condition ComputeCompareCondition(Token::Value op) {
|
| - switch (op) {
|
| - case Token::EQ_STRICT:
|
| - case Token::EQ:
|
| - return equal;
|
| - case Token::LT:
|
| - return less;
|
| - case Token::GT:
|
| - return greater;
|
| - case Token::LTE:
|
| - return less_equal;
|
| - case Token::GTE:
|
| - return greater_equal;
|
| - default:
|
| - UNREACHABLE();
|
| - return no_condition;
|
| - }
|
| -}
|
| -
|
| -
|
| void LCodeGen::DoCmpT(LCmpT* instr) {
|
| Token::Value op = instr->op();
|
|
|
| @@ -3371,85 +3412,15 @@
|
| LStringCharCodeAt* instr_;
|
| };
|
|
|
| - Register string = ToRegister(instr->string());
|
| - Register index = ToRegister(instr->index());
|
| - Register result = ToRegister(instr->result());
|
| -
|
| DeferredStringCharCodeAt* deferred =
|
| new DeferredStringCharCodeAt(this, instr);
|
|
|
| - // Fetch the instance type of the receiver into result register.
|
| - __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
|
| - __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
|
| -
|
| - // We need special handling for indirect strings.
|
| - Label check_sequential;
|
| - __ test(result, Immediate(kIsIndirectStringMask));
|
| - __ j(zero, &check_sequential, Label::kNear);
|
| -
|
| - // Dispatch on the indirect string shape: slice or cons.
|
| - Label cons_string;
|
| - __ test(result, Immediate(kSlicedNotConsMask));
|
| - __ j(zero, &cons_string, Label::kNear);
|
| -
|
| - // Handle slices.
|
| - Label indirect_string_loaded;
|
| - __ mov(result, FieldOperand(string, SlicedString::kOffsetOffset));
|
| - __ SmiUntag(result);
|
| - __ add(index, Operand(result));
|
| - __ mov(string, FieldOperand(string, SlicedString::kParentOffset));
|
| - __ jmp(&indirect_string_loaded, Label::kNear);
|
| -
|
| - // Handle conses.
|
| - // Check whether the right hand side is the empty string (i.e. if
|
| - // this is really a flat string in a cons string). If that is not
|
| - // the case we would rather go to the runtime system now to flatten
|
| - // the string.
|
| - __ bind(&cons_string);
|
| - __ cmp(FieldOperand(string, ConsString::kSecondOffset),
|
| - Immediate(factory()->empty_string()));
|
| - __ j(not_equal, deferred->entry());
|
| - __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
|
| -
|
| - __ bind(&indirect_string_loaded);
|
| - __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
|
| - __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
|
| -
|
| - // Check whether the string is sequential. The only non-sequential
|
| - // shapes we support have just been unwrapped above.
|
| - // Note that if the original string is a cons or slice with an external
|
| - // string as underlying string, we pass that unpacked underlying string with
|
| - // the adjusted index to the runtime function.
|
| - __ bind(&check_sequential);
|
| - STATIC_ASSERT(kSeqStringTag == 0);
|
| - __ test(result, Immediate(kStringRepresentationMask));
|
| - __ j(not_zero, deferred->entry());
|
| -
|
| - // Dispatch on the encoding: ASCII or two-byte.
|
| - Label ascii_string;
|
| - STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
|
| - STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
|
| - __ test(result, Immediate(kStringEncodingMask));
|
| - __ j(not_zero, &ascii_string, Label::kNear);
|
| -
|
| - // Two-byte string.
|
| - // Load the two-byte character code into the result register.
|
| - Label done;
|
| - STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
|
| - __ movzx_w(result, FieldOperand(string,
|
| - index,
|
| - times_2,
|
| - SeqTwoByteString::kHeaderSize));
|
| - __ jmp(&done, Label::kNear);
|
| -
|
| - // ASCII string.
|
| - // Load the byte into the result register.
|
| - __ bind(&ascii_string);
|
| - __ movzx_b(result, FieldOperand(string,
|
| - index,
|
| - times_1,
|
| - SeqAsciiString::kHeaderSize));
|
| - __ bind(&done);
|
| + StringCharLoadGenerator::Generate(masm(),
|
| + factory(),
|
| + ToRegister(instr->string()),
|
| + ToRegister(instr->index()),
|
| + ToRegister(instr->result()),
|
| + deferred->entry());
|
| __ bind(deferred->exit());
|
| }
|
|
|
|
|