// Push three registers. Pushes leftmost register first (to highest address).
void Push(Register src1, Register src2, Register src3, Condition cond = al) {
- DCHECK(!src1.is(src2));
- DCHECK(!src2.is(src3));
- DCHECK(!src1.is(src3));
+ DCHECK(!AreAliased(src1, src2, src3));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
Register src3,
Register src4,
Condition cond = al) {
- DCHECK(!src1.is(src2));
- DCHECK(!src2.is(src3));
- DCHECK(!src1.is(src3));
- DCHECK(!src1.is(src4));
- DCHECK(!src2.is(src4));
- DCHECK(!src3.is(src4));
+ DCHECK(!AreAliased(src1, src2, src3, src4));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
if (src3.code() > src4.code()) {
}
}
+ // Push five registers. Pushes leftmost register first (to highest address).
+ void Push(Register src1, Register src2, Register src3, Register src4,
+ Register src5, Condition cond = al) {
+ DCHECK(!AreAliased(src1, src2, src3, src4, src5));
+ if (src1.code() > src2.code()) {
+ if (src2.code() > src3.code()) {
+ if (src3.code() > src4.code()) {
+ if (src4.code() > src5.code()) {
+ stm(db_w, sp,
+ src1.bit() | src2.bit() | src3.bit() | src4.bit() | src5.bit(),
+ cond);
+ } else {
+ stm(db_w, sp, src1.bit() | src2.bit() | src3.bit() | src4.bit(),
+ cond);
+ str(src5, MemOperand(sp, 4, NegPreIndex), cond);
+ }
+ } else {
+ stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
+ Push(src4, src5, cond);
+ }
+ } else {
+ stm(db_w, sp, src1.bit() | src2.bit(), cond);
+ Push(src3, src4, src5, cond);
+ }
+ } else {
+ str(src1, MemOperand(sp, 4, NegPreIndex), cond);
+ Push(src2, src3, src4, src5, cond);
+ }
+ }
+
// Pop two registers. Pops rightmost register first (from lower address).
void Pop(Register src1, Register src2, Condition cond = al) {
DCHECK(!src1.is(src2));
// Pop three registers. Pops rightmost register first (from lower address).
void Pop(Register src1, Register src2, Register src3, Condition cond = al) {
- DCHECK(!src1.is(src2));
- DCHECK(!src2.is(src3));
- DCHECK(!src1.is(src3));
+ DCHECK(!AreAliased(src1, src2, src3));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
ldm(ia_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
Register src3,
Register src4,
Condition cond = al) {
- DCHECK(!src1.is(src2));
- DCHECK(!src2.is(src3));
- DCHECK(!src1.is(src3));
- DCHECK(!src1.is(src4));
- DCHECK(!src2.is(src4));
- DCHECK(!src3.is(src4));
+ DCHECK(!AreAliased(src1, src2, src3, src4));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
if (src3.code() > src4.code()) {
}
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ if (FLAG_vector_stores) {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister(),
+ VectorStoreICDescriptor::SlotRegister(),
+ VectorStoreICDescriptor::VectorRegister());
+ } else {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister());
+ }
+}
+
+
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // Push receiver, key and value for runtime call.
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
- __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1);
}
void StoreIC::GenerateMiss(MacroAssembler* masm) {
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
// Perform tail call to the entry.
- __ TailCallRuntime(Runtime::kStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1);
}
}
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ if (FLAG_vector_stores) {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister(),
+ VectorStoreICDescriptor::SlotRegister(),
+ VectorStoreICDescriptor::VectorRegister());
+ } else {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister());
+ }
+}
+
+
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
ASM_LOCATION("KeyedStoreIC::GenerateMiss");
+ StoreIC_PushArgs(masm);
- // Push receiver, key and value for runtime call.
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
-
- __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1);
}
void StoreIC::GenerateMiss(MacroAssembler* masm) {
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
// Tail call to the entry.
- __ TailCallRuntime(Runtime::kStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1);
}
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
- DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value));
-
- __ pop(ebx);
- __ push(receiver);
- __ push(name);
- __ push(value);
- __ push(ebx);
+ if (FLAG_vector_stores) {
+ Register slot = VectorStoreICDescriptor::SlotRegister();
+ Register vector = VectorStoreICDescriptor::VectorRegister();
+
+ __ xchg(receiver, Operand(esp, 0));
+ __ push(name);
+ __ push(value);
+ __ push(slot);
+ __ push(vector);
+ __ push(receiver); // Contains the return address.
+ } else {
+ DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value));
+ __ pop(ebx);
+ __ push(receiver);
+ __ push(name);
+ __ push(value);
+ __ push(ebx);
+ }
}
StoreIC_PushArgs(masm);
// Perform tail call to the entry.
- __ TailCallRuntime(Runtime::kStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1);
}
StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
- __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1);
}
Handle<Object> value = args.at<Object>(2);
Handle<Object> result;
- // Bailouts from transitioning stores may have the map to transition to as an
- // extra argument.
- DCHECK(args.length() < 4 || args.at<Object>(3)->IsMap());
-
if (FLAG_vector_stores) {
DCHECK(args.length() == 5 || args.length() == 6);
Handle<Smi> slot = args.at<Smi>(3);
}
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ if (FLAG_vector_stores) {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister(),
+ VectorStoreICDescriptor::SlotRegister(),
+ VectorStoreICDescriptor::VectorRegister());
+ } else {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister());
+ }
+}
+
+
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // Push receiver, key and value for runtime call.
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
- __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1);
}
void StoreIC::GenerateMiss(MacroAssembler* masm) {
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
+
// Perform tail call to the entry.
- __ TailCallRuntime(Runtime::kStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1);
}
}
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ if (FLAG_vector_stores) {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister(),
+ VectorStoreICDescriptor::SlotRegister(),
+ VectorStoreICDescriptor::VectorRegister());
+ } else {
+ __ Push(StoreDescriptor::ReceiverRegister(),
+ StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister());
+ }
+}
+
+
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // Push receiver, key and value for runtime call.
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
- __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1);
}
void StoreIC::GenerateMiss(MacroAssembler* masm) {
- __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
- StoreDescriptor::ValueRegister());
+ StoreIC_PushArgs(masm);
+
// Perform tail call to the entry.
- __ TailCallRuntime(Runtime::kStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1);
}
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
+ Register temp = r11;
+ DCHECK(!temp.is(receiver) && !temp.is(name) && !temp.is(value));
- DCHECK(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value));
-
- __ PopReturnAddressTo(rbx);
+ __ PopReturnAddressTo(temp);
__ Push(receiver);
__ Push(name);
__ Push(value);
- __ PushReturnAddressFrom(rbx);
+ if (FLAG_vector_stores) {
+ Register slot = VectorStoreICDescriptor::SlotRegister();
+ Register vector = VectorStoreICDescriptor::VectorRegister();
+ DCHECK(!temp.is(slot) && !temp.is(vector));
+ __ Push(slot);
+ __ Push(vector);
+ }
+ __ PushReturnAddressFrom(temp);
}
StoreIC_PushArgs(masm);
// Perform tail call to the entry.
- __ TailCallRuntime(Runtime::kStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1);
}
StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
- __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 3, 1);
+ int args = FLAG_vector_stores ? 5 : 3;
+ __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1);
}
sw(src4, MemOperand(sp, 0 * kPointerSize));
}
+ // Push five registers. Pushes leftmost register first (to highest address).
+ void Push(Register src1, Register src2, Register src3, Register src4,
+ Register src5) {
+ Subu(sp, sp, Operand(5 * kPointerSize));
+ sw(src1, MemOperand(sp, 4 * kPointerSize));
+ sw(src2, MemOperand(sp, 3 * kPointerSize));
+ sw(src3, MemOperand(sp, 2 * kPointerSize));
+ sw(src4, MemOperand(sp, 1 * kPointerSize));
+ sw(src5, MemOperand(sp, 0 * kPointerSize));
+ }
+
void Push(Register src, Condition cond, Register tst1, Register tst2) {
// Since we don't have conditional execution we use a Branch.
Branch(3, cond, tst1, Operand(tst2));
sd(src4, MemOperand(sp, 0 * kPointerSize));
}
+ // Push five registers. Pushes leftmost register first (to highest address).
+ void Push(Register src1, Register src2, Register src3, Register src4,
+ Register src5) {
+ Dsubu(sp, sp, Operand(5 * kPointerSize));
+ sd(src1, MemOperand(sp, 4 * kPointerSize));
+ sd(src2, MemOperand(sp, 3 * kPointerSize));
+ sd(src3, MemOperand(sp, 2 * kPointerSize));
+ sd(src4, MemOperand(sp, 1 * kPointerSize));
+ sd(src5, MemOperand(sp, 0 * kPointerSize));
+ }
+
void Push(Register src, Condition cond, Register tst1, Register tst2) {
// Since we don't have conditional execution we use a Branch.
Branch(3, cond, tst1, Operand(tst2));