1537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// Copyright 2016 the V8 project authors. All rights reserved. Use of this 2537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// source code is governed by a BSD-style license that can be found in the 3537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// LICENSE file. 4537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 5537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include <cmath> 6537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include <functional> 7537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include <limits> 8537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 9537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "src/base/bits.h" 10537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "src/base/utils/random-number-generator.h" 11537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "src/codegen.h" 12537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "test/cctest/cctest.h" 13537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "test/cctest/compiler/codegen-tester.h" 14537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "test/cctest/compiler/graph-builder-tester.h" 15537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#include "test/cctest/compiler/value-helper.h" 16537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 17537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochusing namespace v8::base; 18537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 19537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochnamespace { 20537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <typename Type> 21537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid CheckOobValue(Type val) { 22537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch UNREACHABLE(); 23537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 24537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 25537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <> 26537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid CheckOobValue(int32_t val) { 27537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, val); 28537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 29537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 30537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <> 31537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid CheckOobValue(int64_t val) { 32537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, val); 33537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 34537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 35537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <> 36537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid CheckOobValue(float val) { 37537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK(std::isnan(val)); 38537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 39537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 40537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <> 41537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid CheckOobValue(double val) { 42537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK(std::isnan(val)); 43537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 44537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} // namespace 45537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 46537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochnamespace v8 { 47537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochnamespace internal { 48537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochnamespace compiler { 49537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 50537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// This is a America! 51537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#define A_BILLION 1000000000ULL 52537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#define A_GIG (1024ULL * 1024ULL * 1024ULL) 53537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 54537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadInt32) { 55537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 56537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 57537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t p1 = 0; // loads directly from this location. 58537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.LoadFromPointer(&p1, MachineType::Int32())); 59537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 60537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_INT32_INPUTS(i) { 61537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch p1 = *i; 62537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(p1, m.Call()); 63537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 64537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 65537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 66537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadInt32Offset) { 67537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t p1 = 0; // loads directly from this location. 68537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 69537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offsets[] = {-2000000, -100, -101, 1, 3, 70537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 7, 120, 2000, 2000000000, 0xff}; 71537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 72537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (size_t i = 0; i < arraysize(offsets); i++) { 73537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 74537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = offsets[i]; 75537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* pointer = reinterpret_cast<byte*>(&p1) - offset; 76537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // generate load [#base + #index] 77537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset)); 78537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 79537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_INT32_INPUTS(j) { 80537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch p1 = *j; 81537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(p1, m.Call()); 82537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 83537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 84537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 85537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 86537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreFloat32Offset) { 87537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch float p1 = 0.0f; // loads directly from this location. 88537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch float p2 = 0.0f; // and stores directly into this location. 89537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 90537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_INT32_INPUTS(i) { 91537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t magic = 0x2342aabb + *i * 3; 92537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 93537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = *i; 94537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* from = reinterpret_cast<byte*>(&p1) - offset; 95537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* to = reinterpret_cast<byte*>(&p2) - offset; 96537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // generate load [#base + #index] 97537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), 98537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.IntPtrConstant(offset)); 99537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to), 100537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.IntPtrConstant(offset), load, kNoWriteBarrier); 101537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.Int32Constant(magic)); 102537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 103537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_FLOAT32_INPUTS(j) { 104537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch p1 = *j; 105537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch p2 = *j - 5; 106537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(magic, m.Call()); 107537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckDoubleEq(p1, p2); 108537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 109537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 110537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 111537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 112537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreFloat64Offset) { 113537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch double p1 = 0; // loads directly from this location. 114537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch double p2 = 0; // and stores directly into this location. 115537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 116537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_INT32_INPUTS(i) { 117537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t magic = 0x2342aabb + *i * 3; 118537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 119537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = *i; 120537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* from = reinterpret_cast<byte*>(&p1) - offset; 121537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* to = reinterpret_cast<byte*>(&p2) - offset; 122537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // generate load [#base + #index] 123537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), 124537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.IntPtrConstant(offset)); 125537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to), 126537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.IntPtrConstant(offset), load, kNoWriteBarrier); 127537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.Int32Constant(magic)); 128537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 129537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_FLOAT64_INPUTS(j) { 130537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch p1 = *j; 131537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch p2 = *j - 5; 132537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(magic, m.Call()); 133537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckDoubleEq(p1, p2); 134537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 135537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 136537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 137537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 138537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochnamespace { 139537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <typename Type> 140537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid RunLoadImmIndex(MachineType rep) { 141537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int kNumElems = 3; 142537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Type buffer[kNumElems]; 143537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 144537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // initialize the buffer with some raw data. 145537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* raw = reinterpret_cast<byte*>(buffer); 146537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (size_t i = 0; i < sizeof(buffer); i++) { 147537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); 148537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 149537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 150537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Test with various large and small offsets. 151537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int offset = -1; offset <= 200000; offset *= -5) { 152537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int i = 0; i < kNumElems; i++) { 153537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch BufferedRawMachineAssemblerTester<Type> m; 154537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer - offset); 155537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0])); 156537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.Load(rep, base, index)); 157537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 158537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch volatile Type expected = buffer[i]; 159537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch volatile Type actual = m.Call(); 160537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(expected, actual); 161537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 162537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 163537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 164537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 165537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <typename CType> 166537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid RunLoadStore(MachineType rep) { 167537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int kNumElems = 4; 168537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CType buffer[kNumElems]; 169537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 170537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t x = 0; x < kNumElems; x++) { 171537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t y = kNumElems - x - 1; 172537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // initialize the buffer with raw data. 173537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch byte* raw = reinterpret_cast<byte*>(buffer); 174537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (size_t i = 0; i < sizeof(buffer); i++) { 175537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); 176537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 177537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 178537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 179537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t OK = 0x29000 + x; 180537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 181537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0])); 182537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load = m.Load(rep, base, index0); 183537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0])); 184537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Store(rep.representation(), base, index1, load, kNoWriteBarrier); 185537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.Int32Constant(OK)); 186537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 187537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK(buffer[x] != buffer[y]); 188537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(OK, m.Call()); 189537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK(buffer[x] == buffer[y]); 190537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 191537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 192537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} // namespace 193537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 194537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadImmIndex) { 195537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<int8_t>(MachineType::Int8()); 196537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<uint8_t>(MachineType::Uint8()); 197537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<int16_t>(MachineType::Int16()); 198537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<uint16_t>(MachineType::Uint16()); 199537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<int32_t>(MachineType::Int32()); 200537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<uint32_t>(MachineType::Uint32()); 201537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<int32_t*>(MachineType::AnyTagged()); 202537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<float>(MachineType::Float32()); 203537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<double>(MachineType::Float64()); 204537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#if V8_TARGET_ARCH_64_BIT 205537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadImmIndex<int64_t>(MachineType::Int64()); 206537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#endif 207537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // TODO(titzer): test various indexing modes. 208537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 209537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 210537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStore) { 211537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<int8_t>(MachineType::Int8()); 212537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<uint8_t>(MachineType::Uint8()); 213537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<int16_t>(MachineType::Int16()); 214537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<uint16_t>(MachineType::Uint16()); 215537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<int32_t>(MachineType::Int32()); 216537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<uint32_t>(MachineType::Uint32()); 217537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<void*>(MachineType::AnyTagged()); 218537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<float>(MachineType::Float32()); 219537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<double>(MachineType::Float64()); 220537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#if V8_TARGET_ARCH_64_BIT 221537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RunLoadStore<int64_t>(MachineType::Int64()); 222537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#endif 223537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 224537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 225537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#if V8_TARGET_LITTLE_ENDIAN 226537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#define LSB(addr, bytes) addr 227537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#elif V8_TARGET_BIG_ENDIAN 228537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#define LSB(addr, bytes) reinterpret_cast<byte*>(addr + 1) - bytes 229537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#else 230537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#error "Unknown Architecture" 231537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#endif 232537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 233537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreSignExtend32) { 234537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t buffer[4]; 235537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 236537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Int8()); 237537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); 238537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load32 = m.LoadFromPointer(&buffer[0], MachineType::Int32()); 239537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); 240537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[2], MachineRepresentation::kWord32, load16); 241537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[3], MachineRepresentation::kWord32, load32); 242537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(load8); 243537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 244537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_INT32_INPUTS(i) { 245537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch buffer[0] = *i; 246537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 247537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int8_t>(*i & 0xff), m.Call()); 248537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int8_t>(*i & 0xff), buffer[1]); 249537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int16_t>(*i & 0xffff), buffer[2]); 250537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(*i, buffer[3]); 251537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 252537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 253537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 254537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreZeroExtend32) { 255537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t buffer[4]; 256537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<uint32_t> m; 257537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Uint8()); 258537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); 259537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load32 = m.LoadFromPointer(&buffer[0], MachineType::Uint32()); 260537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); 261537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[2], MachineRepresentation::kWord32, load16); 262537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[3], MachineRepresentation::kWord32, load32); 263537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(load8); 264537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 265537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_UINT32_INPUTS(i) { 266537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch buffer[0] = *i; 267537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 268537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xff), m.Call()); 269537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xff), buffer[1]); 270537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xffff), buffer[2]); 271537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(*i, buffer[3]); 272537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 273537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 274537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 275537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#if V8_TARGET_ARCH_64_BIT 276537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunCheckedLoadInt64) { 277537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL}; 278537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int64_t> m(MachineType::Int32()); 279537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 280537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* index = m.Parameter(0); 281537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* length = m.Int32Constant(16); 282537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base, 283537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch index, length); 284537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(load); 285537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 286537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(buffer[0], m.Call(0)); 287537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(buffer[1], m.Call(8)); 288537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(m.Call(16)); 289537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 290537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 291537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreSignExtend64) { 292537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (true) return; // TODO(titzer): sign extension of loads to 64-bit. 293537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int64_t buffer[5]; 294537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int64_t> m; 295537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Int8()); 296537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); 297537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load32 = m.LoadFromPointer(LSB(&buffer[0], 4), MachineType::Int32()); 298537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load64 = m.LoadFromPointer(&buffer[0], MachineType::Int64()); 299537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); 300537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[2], MachineRepresentation::kWord64, load16); 301537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[3], MachineRepresentation::kWord64, load32); 302537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[4], MachineRepresentation::kWord64, load64); 303537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(load8); 304537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 305537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_INT64_INPUTS(i) { 306537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch buffer[0] = *i; 307537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 308537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int8_t>(*i & 0xff), m.Call()); 309537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int8_t>(*i & 0xff), buffer[1]); 310537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int16_t>(*i & 0xffff), buffer[2]); 311537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<int32_t>(*i & 0xffffffff), buffer[3]); 312537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(*i, buffer[4]); 313537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 314537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 315537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 316537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreZeroExtend64) { 317537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (kPointerSize < 8) return; 318537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t buffer[5]; 319537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int64_t> m; 320537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Uint8()); 321537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); 322537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load32 = m.LoadFromPointer(LSB(&buffer[0], 4), MachineType::Uint32()); 323537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* load64 = m.LoadFromPointer(&buffer[0], MachineType::Uint64()); 324537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); 325537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[2], MachineRepresentation::kWord64, load16); 326537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[3], MachineRepresentation::kWord64, load32); 327537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&buffer[4], MachineRepresentation::kWord64, load64); 328537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(load8); 329537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 330537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch FOR_UINT64_INPUTS(i) { 331537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch buffer[0] = *i; 332537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 333537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xff), m.Call()); 334537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xff), buffer[1]); 335537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xffff), buffer[2]); 336537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ((*i & 0xffffffff), buffer[3]); 337537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(*i, buffer[4]); 338537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 339537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 340537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 341537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunCheckedStoreInt64) { 342537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int64_t write = 0x5566778899aabbLL; 343537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int64_t before = 0x33bbccddeeff0011LL; 344537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int64_t buffer[] = {before, before}; 345537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 346537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 347537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* index = m.Parameter(0); 348537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* length = m.Int32Constant(16); 349537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* value = m.Int64Constant(write); 350537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* store = 351537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base, 352537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch index, length, value); 353537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(store); 354537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.Int32Constant(11)); 355537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 356537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(11, m.Call(16)); 357537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(before, buffer[0]); 358537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(before, buffer[1]); 359537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 360537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(11, m.Call(0)); 361537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(write, buffer[0]); 362537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(before, buffer[1]); 363537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 364537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(11, m.Call(8)); 365537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(write, buffer[0]); 366537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(write, buffer[1]); 367537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 368537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#endif 369537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 370537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochnamespace { 371537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <typename IntType> 372537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid LoadStoreTruncation(MachineType kRepresentation) { 373537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch IntType input; 374537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 375537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m; 376537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* a = m.LoadFromPointer(&input, kRepresentation); 377537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* ap1 = m.Int32Add(a, m.Int32Constant(1)); 378537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.StoreToPointer(&input, kRepresentation.representation(), ap1); 379537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(ap1); 380537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 381537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const IntType max = std::numeric_limits<IntType>::max(); 382537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const IntType min = std::numeric_limits<IntType>::min(); 383537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 384537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Test upper bound. 385537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch input = max; 386537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(max + 1, m.Call()); 387537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(min, input); 388537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 389537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Test lower bound. 390537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch input = min; 391537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<IntType>(max + 2), m.Call()); 392537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(min + 1, input); 393537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 394537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Test all one byte values that are not one byte bounds. 395537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int i = -127; i < 127; i++) { 396537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch input = i; 397537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int expected = i >= 0 ? i + 1 : max + (i - min) + 2; 398537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<IntType>(expected), m.Call()); 399537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(static_cast<IntType>(i + 1), input); 400537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 401537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 402537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} // namespace 403537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 404537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunLoadStoreTruncation) { 405537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch LoadStoreTruncation<int8_t>(MachineType::Int8()); 406537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch LoadStoreTruncation<int16_t>(MachineType::Int16()); 407537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 408537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 409537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid TestRunOobCheckedLoad(bool length_is_immediate) { 410537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(CheckOobValue<int32_t>); 411537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(CheckOobValue<int64_t>); 412537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(CheckOobValue<float>); 413537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(CheckOobValue<double>); 414537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 415537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 416537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineType::Int32()); 417537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineOperatorBuilder machine(m.zone()); 418537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int32_t kNumElems = 27; 419537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int32_t kLength = kNumElems * 4; 420537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 421537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t buffer[kNumElems]; 422537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 423537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* offset = m.Parameter(0); 424537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* len = length_is_immediate ? m.Int32Constant(kLength) : m.Parameter(1); 425537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* node = 426537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.AddNode(machine.CheckedLoad(MachineType::Int32()), base, offset, len); 427537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(node); 428537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 429537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch { 430537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // randomize memory. 431537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch v8::base::RandomNumberGenerator rng; 432537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.SetSeed(100); 433537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.NextBytes(&buffer[0], sizeof(buffer)); 434537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 435537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 436537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses. 437537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t i = 0; i < kNumElems; i++) { 438537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = static_cast<int32_t>(i * sizeof(int32_t)); 439537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t expected = buffer[i]; 440537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(expected, m.Call(offset, kLength)); 441537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 442537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 443537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // slightly out-of-bounds accesses. 444537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t i = kLength; i < kNumElems + 30; i++) { 445537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = static_cast<int32_t>(i * sizeof(int32_t)); 446537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(m.Call(offset, kLength)); 447537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 448537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 449537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // way out-of-bounds accesses. 450537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t offset = -2000000000; offset <= 2000000000; 451537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch offset += 100000000) { 452537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (offset == 0) continue; 453537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(m.Call(offset, kLength)); 454537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 455537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 456537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 457537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad) { TestRunOobCheckedLoad(false); } 458537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 459537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadImm) { TestRunOobCheckedLoad(true); } 460537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 461537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid TestRunOobCheckedStore(bool length_is_immediate) { 462537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 463537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineType::Int32()); 464537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineOperatorBuilder machine(m.zone()); 465537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int32_t kNumElems = 29; 466537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int32_t kValue = -78227234; 467537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int32_t kLength = kNumElems * 4; 468537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 469537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t buffer[kNumElems + kNumElems]; 470537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 471537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* offset = m.Parameter(0); 472537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* len = length_is_immediate ? m.Int32Constant(kLength) : m.Parameter(1); 473537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* val = m.Int32Constant(kValue); 474537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.AddNode(machine.CheckedStore(MachineRepresentation::kWord32), base, offset, 475537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch len, val); 476537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(val); 477537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 478537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses. 479537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t i = 0; i < kNumElems; i++) { 480537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch memset(buffer, 0, sizeof(buffer)); 481537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = static_cast<int32_t>(i * sizeof(int32_t)); 482537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, kLength)); 483537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t j = 0; j < kNumElems + kNumElems; j++) { 484537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (i == j) { 485537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, buffer[j]); 486537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } else { 487537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, buffer[j]); 488537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 489537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 490537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 491537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 492537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch memset(buffer, 0, sizeof(buffer)); 493537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 494537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // slightly out-of-bounds accesses. 495537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t i = kLength; i < kNumElems + 30; i++) { 496537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t offset = static_cast<int32_t>(i * sizeof(int32_t)); 497537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, kLength)); 498537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t j = 0; j < kNumElems + kNumElems; j++) { 499537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, buffer[j]); 500537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 501537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 502537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 503537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // way out-of-bounds accesses. 504537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t offset = -2000000000; offset <= 2000000000; 505537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch offset += 100000000) { 506537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (offset == 0) continue; 507537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, kLength)); 508537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t j = 0; j < kNumElems + kNumElems; j++) { 509537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, buffer[j]); 510537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 511537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 512537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 513537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 514537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStore) { TestRunOobCheckedStore(false); } 515537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 516537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStoreImm) { TestRunOobCheckedStore(true); } 517537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 518537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// TODO(titzer): CheckedLoad/CheckedStore don't support 64-bit offsets. 519537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#define ALLOW_64_BIT_OFFSETS 0 520537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 521537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#if V8_TARGET_ARCH_64_BIT && ALLOW_64_BIT_OFFSETS 522537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 523537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid TestRunOobCheckedLoad64(uint32_t pseudo_base, bool length_is_immediate) { 524537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Uint64(), 525537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineType::Uint64()); 526537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineOperatorBuilder machine(m.zone()); 527537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kNumElems = 25; 528537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kLength = kNumElems * 4; 529537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t real_buffer[kNumElems]; 530537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 531537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Simulate the end of a large buffer. 532537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t* buffer = real_buffer - (pseudo_base / 4); 533537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t length = kLength + pseudo_base; 534537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 535537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 536537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* offset = m.Parameter(0); 537537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* len = length_is_immediate ? m.Int64Constant(length) : m.Parameter(1); 538537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* node = 539537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.AddNode(machine.CheckedLoad(MachineType::Int32()), base, offset, len); 540537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(node); 541537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 542537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch { 543537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // randomize memory. 544537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch v8::base::RandomNumberGenerator rng; 545537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.SetSeed(100); 546537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.NextBytes(&real_buffer[0], sizeof(real_buffer)); 547537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 548537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 549537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses. 550537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t i = 0; i < kNumElems; i++) { 551537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t offset = pseudo_base + i * 4; 552537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t expected = real_buffer[i]; 553537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(expected, m.Call(offset, length)); 554537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 555537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 556537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses w.r.t lower 32-bits, but upper bits set. 557537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint64_t i = 0x100000000ULL; i != 0; i <<= 1) { 558537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t offset = pseudo_base + i; 559537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(m.Call(offset, length)); 560537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 561537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 562537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // slightly out-of-bounds accesses. 563537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t i = kLength; i < kNumElems + 30; i++) { 564537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t offset = pseudo_base + i * 4; 565537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(0, m.Call(offset, length)); 566537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 567537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 568537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // way out-of-bounds accesses. 569537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint64_t offset = length; offset < 100 * A_BILLION; offset += A_GIG) { 570537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (offset < length) continue; 571537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(0, m.Call(offset, length)); 572537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 573537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 574537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 575537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad64_0) { 576537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(0, false); 577537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(0, true); 578537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 579537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 580537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad64_1) { 581537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(1 * A_BILLION, false); 582537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(1 * A_BILLION, true); 583537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 584537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 585537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad64_2) { 586537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(2 * A_BILLION, false); 587537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(2 * A_BILLION, true); 588537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 589537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 590537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad64_3) { 591537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(3 * A_BILLION, false); 592537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(3 * A_BILLION, true); 593537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 594537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 595537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad64_4) { 596537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(4 * A_BILLION, false); 597537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad64(4 * A_BILLION, true); 598537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 599537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 600537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid TestRunOobCheckedStore64(uint32_t pseudo_base, bool length_is_immediate) { 601537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Uint64(), 602537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineType::Uint64()); 603537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineOperatorBuilder machine(m.zone()); 604537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kNumElems = 21; 605537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kLength = kNumElems * 4; 606537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kValue = 897234987; 607537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t real_buffer[kNumElems + kNumElems]; 608537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 609537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // Simulate the end of a large buffer. 610537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t* buffer = real_buffer - (pseudo_base / 4); 611537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t length = kLength + pseudo_base; 612537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 613537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(buffer); 614537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* offset = m.Parameter(0); 615537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* len = length_is_immediate ? m.Int64Constant(length) : m.Parameter(1); 616537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* val = m.Int32Constant(kValue); 617537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.AddNode(machine.CheckedStore(MachineRepresentation::kWord32), base, offset, 618537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch len, val); 619537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(val); 620537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 621537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses. 622537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t i = 0; i < kNumElems; i++) { 623537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch memset(real_buffer, 0, sizeof(real_buffer)); 624537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t offset = pseudo_base + i * 4; 625537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, length)); 626537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t j = 0; j < kNumElems + kNumElems; j++) { 627537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (i == j) { 628537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, real_buffer[j]); 629537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } else { 630537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, real_buffer[j]); 631537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 632537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 633537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 634537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 635537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch memset(real_buffer, 0, sizeof(real_buffer)); 636537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 637537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses w.r.t lower 32-bits, but upper bits set. 638537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint64_t i = 0x100000000ULL; i != 0; i <<= 1) { 639537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t offset = pseudo_base + i; 640537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, length)); 641537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t j = 0; j < kNumElems + kNumElems; j++) { 642537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, real_buffer[j]); 643537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 644537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 645537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 646537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // slightly out-of-bounds accesses. 647537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t i = kLength; i < kNumElems + 30; i++) { 648537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint64_t offset = pseudo_base + i * 4; 649537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, length)); 650537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t j = 0; j < kNumElems + kNumElems; j++) { 651537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, real_buffer[j]); 652537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 653537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 654537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 655537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // way out-of-bounds accesses. 656537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint64_t offset = length; offset < 100 * A_BILLION; offset += A_GIG) { 657537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch if (offset < length) continue; 658537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kValue, m.Call(offset, length)); 659537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t j = 0; j < kNumElems + kNumElems; j++) { 660537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(0, real_buffer[j]); 661537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 662537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 663537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 664537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 665537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStore64_0) { 666537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(0, false); 667537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(0, true); 668537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 669537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 670537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStore64_1) { 671537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(1 * A_BILLION, false); 672537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(1 * A_BILLION, true); 673537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 674537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 675537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStore64_2) { 676537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(2 * A_BILLION, false); 677537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(2 * A_BILLION, true); 678537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 679537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 680537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStore64_3) { 681537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(3 * A_BILLION, false); 682537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(3 * A_BILLION, true); 683537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 684537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 685537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedStore64_4) { 686537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(4 * A_BILLION, false); 687537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedStore64(4 * A_BILLION, true); 688537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 689537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 690537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch#endif 691537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 692537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid TestRunOobCheckedLoad_pseudo(uint64_t x, bool length_is_immediate) { 693537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(), 694537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineType::Uint32()); 695537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 696537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t pseudo_base = static_cast<uint32_t>(x); 697537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineOperatorBuilder machine(m.zone()); 698537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kNumElems = 29; 699537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kLength = pseudo_base + kNumElems * 4; 700537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 701537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch int32_t buffer[kNumElems]; 702537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(reinterpret_cast<byte*>(buffer) - pseudo_base); 703537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* offset = m.Parameter(0); 704537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* len = length_is_immediate ? m.Int32Constant(kLength) : m.Parameter(1); 705537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* node = 706537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.AddNode(machine.CheckedLoad(MachineType::Int32()), base, offset, len); 707537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(node); 708537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 709537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch { 710537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // randomize memory. 711537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch v8::base::RandomNumberGenerator rng; 712537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.SetSeed(100); 713537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.NextBytes(&buffer[0], sizeof(buffer)); 714537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 715537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 716537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses. 717537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t i = 0; i < kNumElems; i++) { 718537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t offset = static_cast<uint32_t>(i * sizeof(int32_t)); 719537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t expected = buffer[i]; 720537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(expected, m.Call(offset + pseudo_base, kLength)); 721537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 722537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 723537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // slightly out-of-bounds accesses. 724537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t i = kNumElems; i < kNumElems + 30; i++) { 725537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t offset = static_cast<uint32_t>(i * sizeof(int32_t)); 726537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(m.Call(offset + pseudo_base, kLength)); 727537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 728537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 729537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // way out-of-bounds accesses. 730537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint64_t i = pseudo_base + sizeof(buffer); i < 0xFFFFFFFF; 731537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch i += A_BILLION) { 732537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t offset = static_cast<uint32_t>(i); 733537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(m.Call(offset, kLength)); 734537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 735537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 736537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 737537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo0) { 738537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(0, false); 739537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(0, true); 740537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 741537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 742537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo1) { 743537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(100000, false); 744537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(100000, true); 745537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 746537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 747537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo2) { 748537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(A_BILLION, false); 749537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(A_BILLION, true); 750537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 751537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 752537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo3) { 753537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(A_GIG, false); 754537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(A_GIG, true); 755537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 756537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 757537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo4) { 758537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(2 * A_BILLION, false); 759537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(2 * A_BILLION, true); 760537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 761537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 762537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo5) { 763537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(2 * A_GIG, false); 764537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(2 * A_GIG, true); 765537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 766537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 767537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo6) { 768537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(3 * A_BILLION, false); 769537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(3 * A_BILLION, true); 770537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 771537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 772537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo7) { 773537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(3 * A_GIG, false); 774537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(3 * A_GIG, true); 775537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 776537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 777537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoad_pseudo8) { 778537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(4 * A_BILLION, false); 779537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoad_pseudo(4 * A_BILLION, true); 780537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 781537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 782537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochtemplate <typename MemType> 783537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid TestRunOobCheckedLoadT_pseudo(uint64_t x, bool length_is_immediate) { 784537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const int32_t kReturn = 11999; 785537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kNumElems = 29; 786537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MemType buffer[kNumElems]; 787537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t pseudo_base = static_cast<uint32_t>(x); 788537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch const uint32_t kLength = static_cast<uint32_t>(pseudo_base + sizeof(buffer)); 789537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 790537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MemType result; 791537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 792537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RawMachineAssemblerTester<int32_t> m(MachineType::Uint32(), 793537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineType::Uint32()); 794537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MachineOperatorBuilder machine(m.zone()); 795537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* base = m.PointerConstant(reinterpret_cast<byte*>(buffer) - pseudo_base); 796537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* offset = m.Parameter(0); 797537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* len = length_is_immediate ? m.Int32Constant(kLength) : m.Parameter(1); 798537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* node = m.AddNode(machine.CheckedLoad(MachineTypeForC<MemType>()), base, 799537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch offset, len); 800537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch Node* store = m.StoreToPointer( 801537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch &result, MachineTypeForC<MemType>().representation(), node); 802537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch USE(store); 803537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch m.Return(m.Int32Constant(kReturn)); 804537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 805537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch { 806537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // randomize memory. 807537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch v8::base::RandomNumberGenerator rng; 808537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.SetSeed(103); 809537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch rng.NextBytes(&buffer[0], sizeof(buffer)); 810537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 811537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 812537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // in-bounds accesses. 813537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint32_t i = 0; i < kNumElems; i++) { 814537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t offset = static_cast<uint32_t>(i * sizeof(MemType)); 815537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch MemType expected = buffer[i]; 816537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kReturn, m.Call(offset + pseudo_base, kLength)); 817537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(expected, result); 818537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 819537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 820537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // slightly out-of-bounds accesses. 821537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (int32_t i = kNumElems; i < kNumElems + 30; i++) { 822537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t offset = static_cast<uint32_t>(i * sizeof(MemType)); 823537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kReturn, m.Call(offset + pseudo_base, kLength)); 824537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(result); 825537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 826537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 827537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // way out-of-bounds accesses. 828537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch for (uint64_t i = pseudo_base + sizeof(buffer); i < 0xFFFFFFFF; 829537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch i += A_BILLION) { 830537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch uint32_t offset = static_cast<uint32_t>(i); 831537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CHECK_EQ(kReturn, m.Call(offset, kLength)); 832537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch CheckOobValue(result); 833537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch } 834537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 835537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 836537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo0) { 837537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(0, false); 838537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(0, true); 839537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(0, false); 840537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(0, true); 841537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(0, false); 842537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(0, true); 843537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 844537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 845537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo1) { 846537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(100000, false); 847537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(100000, true); 848537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(100000, false); 849537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(100000, true); 850537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(100000, false); 851537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(100000, true); 852537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 853537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 854537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo2) { 855537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(A_BILLION, false); 856537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(A_BILLION, true); 857537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(A_BILLION, false); 858537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(A_BILLION, true); 859537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(A_BILLION, false); 860537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(A_BILLION, true); 861537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 862537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 863537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo3) { 864537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(A_GIG, false); 865537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(A_GIG, true); 866537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(A_GIG, false); 867537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(A_GIG, true); 868537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(A_GIG, false); 869537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(A_GIG, true); 870537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 871537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 872537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo4) { 873537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(2 * A_BILLION, false); 874537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(2 * A_BILLION, true); 875537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(2 * A_BILLION, false); 876537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(2 * A_BILLION, true); 877537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(2 * A_BILLION, false); 878537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(2 * A_BILLION, true); 879537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 880537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 881537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo5) { 882537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(2 * A_GIG, false); 883537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(2 * A_GIG, true); 884537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(2 * A_GIG, false); 885537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(2 * A_GIG, true); 886537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(2 * A_GIG, false); 887537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(2 * A_GIG, true); 888537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 889537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 890537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo6) { 891537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(3 * A_BILLION, false); 892537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(3 * A_BILLION, true); 893537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(3 * A_BILLION, false); 894537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(3 * A_BILLION, true); 895537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(3 * A_BILLION, false); 896537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(3 * A_BILLION, true); 897537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 898537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 899537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo7) { 900537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(3 * A_GIG, false); 901537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(3 * A_GIG, true); 902537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(3 * A_GIG, false); 903537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(3 * A_GIG, true); 904537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(3 * A_GIG, false); 905537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(3 * A_GIG, true); 906537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 907537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 908537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochTEST(RunOobCheckedLoadT_pseudo8) { 909537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(4 * A_BILLION, false); 910537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<int32_t>(4 * A_BILLION, true); 911537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(4 * A_BILLION, false); 912537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<float>(4 * A_BILLION, true); 913537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(4 * A_BILLION, false); 914537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch TestRunOobCheckedLoadT_pseudo<double>(4 * A_BILLION, true); 915537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 916537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 917537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} // namespace compiler 918537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} // namespace internal 919537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} // namespace v8 920