Commit 391f05ae authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Use SmiTst and TrySmiTag MacroAssembler instructions.

BUG=
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/78403002

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17941 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c33cbd9f
......@@ -122,7 +122,7 @@ void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Initial map for the builtin InternalArray functions should be maps.
__ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
__ And(t0, a2, Operand(kSmiTagMask));
__ SmiTst(a2, t0);
__ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction,
t0, Operand(zero_reg));
__ GetObjectType(a2, a3, t0);
......@@ -152,7 +152,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Initial map for the builtin Array functions should be maps.
__ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
__ And(t0, a2, Operand(kSmiTagMask));
__ SmiTst(a2, t0);
__ Assert(ne, kUnexpectedInitialMapForArrayFunction1,
t0, Operand(zero_reg));
__ GetObjectType(a2, a3, t0);
......
......@@ -2969,7 +2969,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Check that the RegExp has been compiled (data contains a fixed array).
__ lw(regexp_data, FieldMemOperand(a0, JSRegExp::kDataOffset));
if (FLAG_debug_code) {
__ And(t0, regexp_data, Operand(kSmiTagMask));
__ SmiTst(regexp_data, t0);
__ Check(nz,
kUnexpectedTypeForRegExpDataFixedArrayExpected,
t0,
......@@ -6164,7 +6164,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
// Initial map for the builtin Array function should be a map.
__ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a NULL and a Smi.
__ And(at, a3, Operand(kSmiTagMask));
__ SmiTst(a3, at);
__ Assert(ne, kUnexpectedInitialMapForArrayFunction,
at, Operand(zero_reg));
__ GetObjectType(a3, a3, t0);
......@@ -6253,7 +6253,7 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
// Initial map for the builtin Array function should be a map.
__ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a NULL and a Smi.
__ And(at, a3, Operand(kSmiTagMask));
__ SmiTst(a3, at);
__ Assert(ne, kUnexpectedInitialMapForArrayFunction,
at, Operand(zero_reg));
__ GetObjectType(a3, a3, t0);
......
......@@ -2914,7 +2914,7 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
&if_true, &if_false, &fall_through);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ And(t0, v0, Operand(kSmiTagMask));
__ SmiTst(v0, t0);
Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
......@@ -2935,7 +2935,7 @@ void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
&if_true, &if_false, &fall_through);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ And(at, v0, Operand(kSmiTagMask | 0x80000000));
__ NonNegativeSmiTst(v0, at);
Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
......@@ -3528,9 +3528,9 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
__ Pop(index, value);
if (FLAG_debug_code) {
__ And(at, value, Operand(kSmiTagMask));
__ SmiTst(value, at);
__ ThrowIf(ne, kNonSmiValue, at, Operand(zero_reg));
__ And(at, index, Operand(kSmiTagMask));
__ SmiTst(index, at);
__ ThrowIf(ne, kNonSmiIndex, at, Operand(zero_reg));
__ SmiUntag(index, index);
static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
......@@ -3565,9 +3565,9 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
__ Pop(index, value);
if (FLAG_debug_code) {
__ And(at, value, Operand(kSmiTagMask));
__ SmiTst(value, at);
__ ThrowIf(ne, kNonSmiValue, at, Operand(zero_reg));
__ And(at, index, Operand(kSmiTagMask));
__ SmiTst(index, at);
__ ThrowIf(ne, kNonSmiIndex, at, Operand(zero_reg));
__ SmiUntag(index, index);
static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
......
......@@ -1704,7 +1704,7 @@ void LCodeGen::DoDateField(LDateField* instr) {
ASSERT(!scratch.is(scratch0()));
ASSERT(!scratch.is(object));
__ And(at, object, Operand(kSmiTagMask));
__ SmiTst(object, at);
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
__ GetObjectType(object, scratch, scratch);
DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_DATE_TYPE));
......@@ -2115,7 +2115,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ JumpIfSmi(reg, instr->TrueLabel(chunk_));
} else if (expected.NeedsMap()) {
// If we need a map later and have a Smi -> deopt.
__ And(at, reg, Operand(kSmiTagMask));
__ SmiTst(reg, at);
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
}
......@@ -3208,7 +3208,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
__ And(scratch, result, Operand(kSmiTagMask));
__ SmiTst(result, scratch);
DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
} else {
__ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
......@@ -3357,7 +3357,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
__ Branch(&global_object, eq, receiver, Operand(scratch));
// Deoptimize if the receiver is not a JS object.
__ And(scratch, receiver, Operand(kSmiTagMask));
__ SmiTst(receiver, scratch);
DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
__ GetObjectType(receiver, scratch, scratch);
......@@ -4135,7 +4135,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
Register value = ToRegister(instr->value());
if (!instr->hydrogen()->value()->type().IsHeapObject()) {
__ And(scratch, value, Operand(kSmiTagMask));
__ SmiTst(value, scratch);
DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
}
} else if (FLAG_track_double_fields && representation.IsDouble()) {
......@@ -5130,7 +5130,7 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
LOperand* input = instr->value();
__ And(at, ToRegister(input), Operand(kSmiTagMask));
__ SmiTst(ToRegister(input), at);
DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg));
}
......@@ -5138,7 +5138,7 @@ void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
if (!instr->hydrogen()->value()->IsHeapObject()) {
LOperand* input = instr->value();
__ And(at, ToRegister(input), Operand(kSmiTagMask));
__ SmiTst(ToRegister(input), at);
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
}
}
......@@ -5211,7 +5211,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
__ StoreToSafepointRegisterSlot(v0, scratch0());
}
__ And(at, scratch0(), Operand(kSmiTagMask));
__ SmiTst(scratch0(), at);
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
}
......
......@@ -4845,7 +4845,7 @@ void MacroAssembler::AssertSmi(Register object) {
void MacroAssembler::AssertString(Register object) {
if (emit_debug_code()) {
STATIC_ASSERT(kSmiTag == 0);
And(t0, object, Operand(kSmiTagMask));
SmiTst(object, t0);
Check(ne, kOperandIsASmiAndNotAString, t0, Operand(zero_reg));
push(object);
lw(object, FieldMemOperand(object, HeapObject::kMapOffset));
......@@ -4859,7 +4859,7 @@ void MacroAssembler::AssertString(Register object) {
void MacroAssembler::AssertName(Register object) {
if (emit_debug_code()) {
STATIC_ASSERT(kSmiTag == 0);
And(t0, object, Operand(kSmiTagMask));
SmiTst(object, t0);
Check(ne, kOperandIsASmiAndNotAName, t0, Operand(zero_reg));
push(object);
lw(object, FieldMemOperand(object, HeapObject::kMapOffset));
......@@ -5059,7 +5059,7 @@ void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
Register scratch,
uint32_t encoding_mask) {
Label is_object;
And(at, string, Operand(kSmiTagMask));
SmiTst(string, at);
ThrowIf(eq, kNonObject, at, Operand(zero_reg));
lw(at, FieldMemOperand(string, HeapObject::kMapOffset));
......@@ -5073,9 +5073,7 @@ void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
// string length without using a temp register, it is restored at the end of
// this function.
Label index_tag_ok, index_tag_bad;
// On ARM TrySmiTag is used here.
AdduAndCheckForOverflow(index, index, index, scratch);
BranchOnOverflow(&index_tag_bad, scratch);
TrySmiTag(index, scratch, &index_tag_bad);
Branch(&index_tag_ok);
bind(&index_tag_bad);
Throw(kIndexIsTooLarge);
......
......@@ -1371,6 +1371,21 @@ class MacroAssembler: public Assembler {
Addu(dst, src, src);
}
// Try to convert int32 to smi. If the value is to large, preserve
// the original value and jump to not_a_smi. Destroys scratch and
// sets flags.
void TrySmiTag(Register reg, Register scratch, Label* not_a_smi) {
TrySmiTag(reg, reg, scratch, not_a_smi);
}
void TrySmiTag(Register dst,
Register src,
Register scratch,
Label* not_a_smi) {
SmiTagCheckOverflow(at, src, scratch);
BranchOnOverflow(not_a_smi, scratch);
mov(dst, at);
}
void SmiUntag(Register reg) {
sra(reg, reg, kSmiTagSize);
}
......@@ -1379,6 +1394,14 @@ class MacroAssembler: public Assembler {
sra(dst, src, kSmiTagSize);
}
// Test if the register contains a smi.
inline void SmiTst(Register value, Register scratch) {
And(scratch, value, Operand(kSmiTagMask));
}
inline void NonNegativeSmiTst(Register value, Register scratch) {
And(scratch, value, Operand(kSmiTagMask | kSmiSignMask));
}
// Untag the source value into destination and jump if source is a smi.
// Souce and destination can be the same register.
void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
......
......@@ -2316,7 +2316,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
// If the argument is a smi, just return.
STATIC_ASSERT(kSmiTag == 0);
__ And(t0, v0, Operand(kSmiTagMask));
__ SmiTst(v0, t0);
__ DropAndRet(argc + 1, eq, t0, Operand(zero_reg));
__ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment