1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met:
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions of source code must retain the above copyright
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       notice, this list of conditions and the following disclaimer.
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions in binary form must reproduce the above
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       copyright notice, this list of conditions and the following
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       disclaimer in the documentation and/or other materials provided
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       with the distribution.
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Neither the name of Google Inc. nor the names of its
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       contributors may be used to endorse or promote products derived
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       from this software without specific prior written permission.
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdlib.h>
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <iostream>  // NOLINT(readability/streams)
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h"
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/utils/random-number-generator.h"
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/macro-assembler-mips64.h"
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/simulator-mips64.h"
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef void* (*F)(int64_t x, int64_t y, int p2, int p3, int p4);
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ masm->
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic byte to_non_zero(int n) {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<unsigned>(n) % 255 + 1;
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool all_zeroes(const byte* beg, const byte* end) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(beg);
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(beg <= end);
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (beg < end) {
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (*beg++ != 0)
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(CopyBytes) {
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope handles(isolate);
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int data_size = 1 * KB;
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t act_size;
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate two blocks to copy data between.
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* src_buffer =
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(src_buffer);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(act_size >= static_cast<size_t>(data_size));
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* dest_buffer =
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<byte*>(v8::base::OS::Allocate(data_size, &act_size, 0));
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(dest_buffer);
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(act_size >= static_cast<size_t>(data_size));
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Storage for a0 and a1.
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* a0_;
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte* a1_;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, NULL, 0,
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MacroAssembler* masm = &assembler;
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code to be generated: The stuff in CopyBytes followed by a store of a0 and
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // a1, respectively.
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ CopyBytes(a0, a1, a2, a3);
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ li(a2, Operand(reinterpret_cast<int64_t>(&a0_)));
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ li(a3, Operand(reinterpret_cast<int64_t>(&a1_)));
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ sd(a0, MemOperand(a2));
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ jr(ra);
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ sd(a1, MemOperand(a3));
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeDesc desc;
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->GetCode(&desc);
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> code = isolate->factory()->NewCode(
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ::F f = FUNCTION_CAST< ::F>(code->entry());
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialise source data with non-zero bytes.
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < data_size; i++) {
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    src_buffer[i] = to_non_zero(i);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int fuzz = 11;
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int size = 0; size < 600; size++) {
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) {
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        memset(dest_buffer, 0, data_size);
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(dest + size < dest_buffer + data_size);
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int64_t>(src),
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  reinterpret_cast<int64_t>(dest), size, 0, 0);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // a0 and a1 should point at the first byte after the copied data.
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK_EQ(src + size, a0_);
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK_EQ(dest + size, a1_);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check that we haven't written outside the target area.
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(all_zeroes(dest_buffer, dest));
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(all_zeroes(dest + size, dest_buffer + data_size));
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check the target area.
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK_EQ(0, memcmp(src, dest, size));
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that the source data hasn't been clobbered.
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < data_size; i++) {
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(src_buffer[i] == to_non_zero(i));
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(LoadConstants) {
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope handles(isolate);
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t refConstants[64];
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t result[64];
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t mask = 1;
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < 64; i++) {
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    refConstants[i] = ~(mask << i);
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, NULL, 0,
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MacroAssembler* masm = &assembler;
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(a4, a0);
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < 64; i++) {
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Load constant.
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ li(a5, Operand(refConstants[i]));
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ sd(a5, MemOperand(a4));
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ Daddu(a4, a4, Operand(kPointerSize));
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ jr(ra);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ nop();
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeDesc desc;
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->GetCode(&desc);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> code = isolate->factory()->NewCode(
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ::F f = FUNCTION_CAST< ::F>(code->entry());
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int64_t>(result), 0, 0,
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            0, 0);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check results.
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < 64; i++) {
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(refConstants[i] == result[i]);
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(LoadAddress) {
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope handles(isolate);
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, NULL, 0,
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MacroAssembler* masm = &assembler;
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label to_jump, skip;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(a4, a0);
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ Branch(&skip);
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&to_jump);
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ nop();
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ nop();
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ jr(ra);
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ nop();
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&skip);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ li(a4, Operand(masm->jump_address(&to_jump)), ADDRESS_LOAD);
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int check_size = masm->InstructionsGeneratedSince(&skip);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_EQ(check_size, 4);
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ jr(a4);
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ nop();
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ stop("invalid");
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ stop("invalid");
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ stop("invalid");
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ stop("invalid");
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ stop("invalid");
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeDesc desc;
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->GetCode(&desc);
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> code = isolate->factory()->NewCode(
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ::F f = FUNCTION_CAST< ::F>(code->entry());
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (void)CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0);
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check results.
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(jump_tables4) {
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Similar to test-assembler-mips jump_tables1, with extra test for branch
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // trampoline required before emission of the dd table (where trampolines are
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // blocked), and proper transition to long-branch mode.
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Regression test for v8:4294.
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CcTest::InitializeVM();
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, NULL, 0,
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler* masm = &assembler;
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int kNumCases = 512;
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int values[kNumCases];
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate->random_number_generator()->NextBytes(values, sizeof(values));
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label labels[kNumCases];
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label near_start, end;
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ daddiu(sp, sp, -8);
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ sd(ra, MemOperand(sp));
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(v0, zero_reg);
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Branch(&end);
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&near_start);
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Generate slightly less than 32K instructions, which will soon require
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // trampoline for branch distance fixup.
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < 32768 - 256; ++i) {
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ addiu(v0, v0, 1);
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Align(8);
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label done;
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ BlockTrampolinePoolFor(kNumCases * 2 + 6);
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PredictableCodeSizeScope predictable(
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        masm, (kNumCases * 2 + 6) * Assembler::kInstrSize);
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label here;
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bal(&here);
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ dsll(at, a0, 3);  // In delay slot.
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&here);
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ daddu(at, at, ra);
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ld(at, MemOperand(at, 4 * Assembler::kInstrSize));
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ jr(at);
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ nop();  // Branch delay slot nop.
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < kNumCases; ++i) {
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dd(&labels[i]);
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < kNumCases; ++i) {
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&labels[i]);
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ lui(v0, (values[i] >> 16) & 0xffff);
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ori(v0, v0, values[i] & 0xffff);
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Branch(&done);
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&done);
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ld(ra, MemOperand(sp));
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ daddiu(sp, sp, 8);
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ jr(ra);
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ nop();
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&end);
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Branch(&near_start);
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm->GetCode(&desc);
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Code> code = isolate->factory()->NewCode(
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef OBJECT_PRINT
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  code->Print(std::cout);
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F1 f = FUNCTION_CAST<F1>(code->entry());
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < kNumCases; ++i) {
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t res = reinterpret_cast<int64_t>(
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ::printf("f(%d) = %" PRId64 "\n", i, res);
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_EQ(values[i], res);
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(jump_tables5) {
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kArchVariant != kMips64r6) return;
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Similar to test-assembler-mips jump_tables1, with extra test for emitting a
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // compact branch instruction before emission of the dd table.
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CcTest::InitializeVM();
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, nullptr, 0,
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler* masm = &assembler;
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int kNumCases = 512;
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int values[kNumCases];
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  isolate->random_number_generator()->NextBytes(values, sizeof(values));
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label labels[kNumCases];
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label done;
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ daddiu(sp, sp, -8);
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ sd(ra, MemOperand(sp));
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Align(8);
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ BlockTrampolinePoolFor(kNumCases * 2 + 7 + 1);
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PredictableCodeSizeScope predictable(
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        masm, kNumCases * kPointerSize + ((7 + 1) * Assembler::kInstrSize));
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label here;
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bal(&here);
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ dsll(at, a0, 3);  // In delay slot.
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&here);
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ daddu(at, at, ra);
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ld(at, MemOperand(at, 6 * Assembler::kInstrSize));
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ jalr(at);
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ nop();  // Branch delay slot nop.
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bc(&done);
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // A nop instruction must be generated by the forbidden slot guard
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // (Assembler::dd(Label*)) so the first label goes to an 8 bytes aligned
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // location.
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < kNumCases; ++i) {
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dd(&labels[i]);
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < kNumCases; ++i) {
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&labels[i]);
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ lui(v0, (values[i] >> 16) & 0xffff);
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ori(v0, v0, values[i] & 0xffff);
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ jr(ra);
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ nop();
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&done);
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ld(ra, MemOperand(sp));
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ daddiu(sp, sp, 8);
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ jr(ra);
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ nop();
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  masm->GetCode(&desc);
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Code> code = isolate->factory()->NewCode(
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef OBJECT_PRINT
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  code->Print(std::cout);
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F1 f = FUNCTION_CAST<F1>(code->entry());
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < kNumCases; ++i) {
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t res = reinterpret_cast<int64_t>(
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ::printf("f(%d) = %" PRId64 "\n", i, res);
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_EQ(values[i], res);
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic uint64_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, nullptr, 0,
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler* masm = &assembler;
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Lsa(v0, a0, a1, sa);
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ jr(ra);
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ nop();
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assembler.GetCode(&desc);
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Code> code = isolate->factory()->NewCode(
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  F1 f = FUNCTION_CAST<F1>(code->entry());
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t res = reinterpret_cast<uint64_t>(
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0));
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return res;
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Lsa) {
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CcTest::InitializeVM();
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct TestCaseLsa {
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t rt;
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t rs;
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint8_t sa;
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint64_t expected_res;
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 1, 0x6},
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 2, 0x8},
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 3, 0xc},
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 4, 0x14},
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 5, 0x24},
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 1, 0x2},
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 2, 0x4},
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 3, 0x8},
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 4, 0x10},
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 5, 0x20},
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 1, 0x4},
429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 2, 0x4},
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 3, 0x4},
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 4, 0x4},
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 5, 0x4},
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             // Shift overflow.
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT32_MAX, 1, 0x2},
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT32_MAX >> 1, 2, 0x0},
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT32_MAX >> 2, 3, 0xfffffffffffffffc},
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT32_MAX >> 3, 4, 0xfffffffffffffff4},
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT32_MAX >> 4, 5, 0xffffffffffffffe4},
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             // Signed addition overflow.
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT32_MAX - 1, 0x1, 1, 0xffffffff80000000},
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT32_MAX - 3, 0x1, 2, 0xffffffff80000000},
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT32_MAX - 7, 0x1, 3, 0xffffffff80000000},
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT32_MAX - 15, 0x1, 4, 0xffffffff80000000},
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT32_MAX - 31, 0x1, 5, 0xffffffff80000000},
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             // Addition overflow.
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-2, 0x1, 1, 0x0},
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-4, 0x1, 2, 0x0},
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-8, 0x1, 3, 0x0},
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-16, 0x1, 4, 0x0},
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-32, 0x1, 5, 0x0}};
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < nr_test_cases; ++i) {
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint64_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa);
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Lsa(v0, %x, %x, %hhu)\n",
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa);
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_EQ(tc[i].expected_res, res);
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic uint64_t run_dlsa(uint64_t rt, uint64_t rs, int8_t sa) {
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = CcTest::i_isolate();
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler assembler(isolate, nullptr, 0,
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           v8::internal::CodeObjectRequired::kYes);
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MacroAssembler* masm = &assembler;
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Dlsa(v0, a0, a1, sa);
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ jr(ra);
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ nop();
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodeDesc desc;
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assembler.GetCode(&desc);
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Code> code = isolate->factory()->NewCode(
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ::F f = FUNCTION_CAST<::F>(code->entry());
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t res = reinterpret_cast<uint64_t>(
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0));
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return res;
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTEST(Dlsa) {
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CcTest::InitializeVM();
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct TestCaseLsa {
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t rt;
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t rs;
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint8_t sa;
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint64_t expected_res;
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 1, 0x6},
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 2, 0x8},
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 3, 0xc},
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 4, 0x14},
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x1, 5, 0x24},
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 1, 0x2},
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 2, 0x4},
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 3, 0x8},
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 4, 0x10},
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x0, 0x1, 5, 0x20},
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 1, 0x4},
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 2, 0x4},
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 3, 0x4},
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 4, 0x4},
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, 0x0, 5, 0x4},
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             // Shift overflow.
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT64_MAX, 1, 0x2},
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT64_MAX >> 1, 2, 0x0},
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT64_MAX >> 2, 3, 0xfffffffffffffffc},
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT64_MAX >> 3, 4, 0xfffffffffffffff4},
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {0x4, INT64_MAX >> 4, 5, 0xffffffffffffffe4},
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             // Signed addition overflow.
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT64_MAX - 1, 0x1, 1, 0x8000000000000000},
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT64_MAX - 3, 0x1, 2, 0x8000000000000000},
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT64_MAX - 7, 0x1, 3, 0x8000000000000000},
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT64_MAX - 15, 0x1, 4, 0x8000000000000000},
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {INT64_MAX - 31, 0x1, 5, 0x8000000000000000},
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             // Addition overflow.
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-2, 0x1, 1, 0x0},
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-4, 0x1, 2, 0x0},
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-8, 0x1, 3, 0x0},
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-16, 0x1, 4, 0x0},
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             {-32, 0x1, 5, 0x0}};
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < nr_test_cases; ++i) {
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa);
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           ", %hhu)\n",
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa);
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_EQ(tc[i].expected_res, res);
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __
548