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