case kCheckedStoreFloat64:
ASSEMBLE_CHECKED_STORE_FLOAT(64);
break;
+ case kCheckedLoadWord64:
+ case kCheckedStoreWord64:
+ UNREACHABLE(); // currently unsupported checked int64 load/store.
+ break;
}
} // NOLINT(readability/fn_size)
} while (0)
+#define ASSEMBLE_CHECKED_LOAD_INTEGER_64(asm_instr) \
+ do { \
+ auto result = i.OutputRegister(); \
+ auto buffer = i.InputRegister(0); \
+ auto offset = i.InputRegister32(1); \
+ auto length = i.InputOperand32(2); \
+ __ Cmp(offset, length); \
+ auto ool = new (zone()) OutOfLineLoadZero(this, result); \
+ __ B(hs, ool->entry()); \
+ __ asm_instr(result, MemOperand(buffer, offset, UXTW)); \
+ __ Bind(ool->exit()); \
+ } while (0)
+
+
#define ASSEMBLE_CHECKED_STORE_FLOAT(width) \
do { \
auto buffer = i.InputRegister(0); \
} while (0)
+#define ASSEMBLE_CHECKED_STORE_INTEGER_64(asm_instr) \
+ do { \
+ auto buffer = i.InputRegister(0); \
+ auto offset = i.InputRegister32(1); \
+ auto length = i.InputOperand32(2); \
+ auto value = i.InputRegister(3); \
+ __ Cmp(offset, length); \
+ Label done; \
+ __ B(hs, &done); \
+ __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \
+ __ Bind(&done); \
+ } while (0)
+
+
#define ASSEMBLE_SHIFT(asm_instr, width) \
do { \
if (instr->InputAt(1)->IsRegister()) { \
case kCheckedLoadWord32:
ASSEMBLE_CHECKED_LOAD_INTEGER(Ldr);
break;
+ case kCheckedLoadWord64:
+ ASSEMBLE_CHECKED_LOAD_INTEGER_64(Ldr);
+ break;
case kCheckedLoadFloat32:
ASSEMBLE_CHECKED_LOAD_FLOAT(32);
break;
case kCheckedStoreWord32:
ASSEMBLE_CHECKED_STORE_INTEGER(Str);
break;
+ case kCheckedStoreWord64:
+ ASSEMBLE_CHECKED_STORE_INTEGER_64(Str);
+ break;
case kCheckedStoreFloat32:
ASSEMBLE_CHECKED_STORE_FLOAT(32);
break;
case kRepWord32:
opcode = kCheckedLoadWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedLoadWord64;
+ break;
case kRepFloat32:
opcode = kCheckedLoadFloat32;
break;
case kRepWord32:
opcode = kCheckedStoreWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedStoreWord64;
+ break;
case kRepFloat32:
opcode = kCheckedStoreFloat32;
break;
__ cmp(esp, Operand::StaticVariable(stack_limit));
break;
}
+ case kCheckedLoadWord64:
+ case kCheckedStoreWord64:
+ UNREACHABLE(); // currently unsupported checked int64 load/store.
+ break;
}
} // NOLINT(readability/fn_size)
V(CheckedLoadInt16) \
V(CheckedLoadUint16) \
V(CheckedLoadWord32) \
+ V(CheckedLoadWord64) \
V(CheckedLoadFloat32) \
V(CheckedLoadFloat64) \
V(CheckedStoreWord8) \
V(CheckedStoreWord16) \
V(CheckedStoreWord32) \
+ V(CheckedStoreWord64) \
V(CheckedStoreFloat32) \
V(CheckedStoreFloat64) \
TARGET_ARCH_OPCODE_LIST(V)
case kCheckedStoreFloat64:
ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
break;
+ case kCheckedLoadWord64:
+ case kCheckedStoreWord64:
+ UNREACHABLE(); // currently unsupported checked int64 load/store.
+ break;
}
}
case kCheckedLoadWord32:
ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
break;
+ case kCheckedLoadWord64:
+ ASSEMBLE_CHECKED_LOAD_INTEGER(ld);
+ break;
case kCheckedLoadFloat32:
ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
break;
case kCheckedStoreWord32:
ASSEMBLE_CHECKED_STORE_INTEGER(sw);
break;
+ case kCheckedStoreWord64:
+ ASSEMBLE_CHECKED_STORE_INTEGER(sd);
+ break;
case kCheckedStoreFloat32:
ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
break;
case kRepWord32:
opcode = kCheckedLoadWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedLoadWord64;
+ break;
case kRepFloat32:
opcode = kCheckedLoadFloat32;
break;
case kRepWord32:
opcode = kCheckedStoreWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedStoreWord64;
+ break;
case kRepFloat32:
opcode = kCheckedStoreFloat32;
break;
case kCheckedLoadWord32:
ASSEMBLE_CHECKED_LOAD_INTEGER(lwa, lwax);
break;
+ case kCheckedLoadWord64:
+#if V8_TARGET_ARCH_PPC64
+ ASSEMBLE_CHECKED_LOAD_INTEGER(ld, ldx);
+#else
+ UNREACHABLE();
+#endif
+ break;
case kCheckedLoadFloat32:
ASSEMBLE_CHECKED_LOAD_FLOAT(lfs, lfsx, 32);
break;
case kCheckedStoreWord32:
ASSEMBLE_CHECKED_STORE_INTEGER(stw, stwx);
break;
+ case kCheckedStoreWord64:
+#if V8_TARGET_ARCH_PPC64
+ ASSEMBLE_CHECKED_STORE_INTEGER(std, stdx);
+#else
+ UNREACHABLE();
+#endif
+ break;
case kCheckedStoreFloat32:
ASSEMBLE_CHECKED_STORE_FLOAT32();
break;
case kRepWord32:
opcode = kCheckedLoadWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedLoadWord64;
+ break;
case kRepFloat32:
opcode = kCheckedLoadFloat32;
break;
case kRepWord32:
opcode = kCheckedStoreWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedStoreWord64;
+ break;
case kRepFloat32:
opcode = kCheckedStoreFloat32;
break;
case kCheckedLoadWord32:
ASSEMBLE_CHECKED_LOAD_INTEGER(movl);
break;
+ case kCheckedLoadWord64:
+ ASSEMBLE_CHECKED_LOAD_INTEGER(movq);
+ break;
case kCheckedLoadFloat32:
ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
break;
case kCheckedStoreWord32:
ASSEMBLE_CHECKED_STORE_INTEGER(movl);
break;
+ case kCheckedStoreWord64:
+ ASSEMBLE_CHECKED_STORE_INTEGER(movq);
+ break;
case kCheckedStoreFloat32:
ASSEMBLE_CHECKED_STORE_FLOAT(movss);
break;
case kRepWord32:
opcode = kCheckedLoadWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedLoadWord64;
+ break;
case kRepFloat32:
opcode = kCheckedLoadFloat32;
break;
case kRepWord32:
opcode = kCheckedStoreWord32;
break;
+ case kRepWord64:
+ opcode = kCheckedStoreWord64;
+ break;
case kRepFloat32:
opcode = kCheckedStoreFloat32;
break;
__ cmp(esp, Operand::StaticVariable(stack_limit));
break;
}
+ case kCheckedLoadWord64:
+ case kCheckedStoreWord64:
+ UNREACHABLE(); // currently unsupported checked int64 load/store.
+ break;
}
} // NOLINT(readability/fn_size)
CHECK_EQ(x * 8, m.Call(x));
}
}
-
#endif // USE_SIMULATOR
+
+#if V8_TARGET_ARCH_64_BIT
+TEST(RunCheckedLoadInt64) {
+ int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL};
+ RawMachineAssemblerTester<int64_t> m(kMachInt32);
+ Node* base = m.PointerConstant(buffer);
+ Node* index = m.Parameter(0);
+ Node* length = m.Int32Constant(16);
+ Node* load =
+ m.NewNode(m.machine()->CheckedLoad(kMachInt64), base, index, length);
+ m.Return(load);
+
+ CHECK_EQ(buffer[0], m.Call(0));
+ CHECK_EQ(buffer[1], m.Call(8));
+ CHECK_EQ(0, m.Call(16));
+}
+
+
+TEST(RunCheckedStoreInt64) {
+ const int64_t write = 0x5566778899aabbLL;
+ const int64_t before = 0x33bbccddeeff0011LL;
+ int64_t buffer[] = {before, before};
+ RawMachineAssemblerTester<int32_t> m(kMachInt32);
+ Node* base = m.PointerConstant(buffer);
+ Node* index = m.Parameter(0);
+ Node* length = m.Int32Constant(16);
+ Node* value = m.Int64Constant(write);
+ Node* store = m.NewNode(m.machine()->CheckedStore(kMachInt64), base, index,
+ length, value);
+ USE(store);
+ m.Return(m.Int32Constant(11));
+
+ CHECK_EQ(11, m.Call(16));
+ CHECK_EQ(before, buffer[0]);
+ CHECK_EQ(before, buffer[1]);
+
+ CHECK_EQ(11, m.Call(0));
+ CHECK_EQ(write, buffer[0]);
+ CHECK_EQ(before, buffer[1]);
+
+ CHECK_EQ(11, m.Call(8));
+ CHECK_EQ(write, buffer[0]);
+ CHECK_EQ(write, buffer[1]);
+}
+#endif