13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// Redistribution and use in source and binary forms, with or without
3402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// modification, are permitted provided that the following conditions are
4402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// met:
5402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//
6402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//     * Redistributions of source code must retain the above copyright
7402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//       notice, this list of conditions and the following disclaimer.
8402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//     * Redistributions in binary form must reproduce the above
9402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//       copyright notice, this list of conditions and the following
10402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//       disclaimer in the documentation and/or other materials provided
11402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//       with the distribution.
12402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//     * Neither the name of Google Inc. nor the names of its
13402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//       contributors may be used to endorse or promote products derived
14402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//       from this software without specific prior written permission.
15402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu//
16402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
28402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "v8.h"
29402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
30402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "disassembler.h"
31402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "factory.h"
32402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "macro-assembler.h"
33402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "mips/macro-assembler-mips.h"
34402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "mips/simulator-mips.h"
35402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
36402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "cctest.h"
37402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
38402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuusing namespace v8::internal;
39402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
40402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
41402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// Define these function prototypes to match JSEntryFunction in execution.cc.
42402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescutypedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
43402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescutypedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
44402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescutypedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
45402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
46402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
47402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic v8::Persistent<v8::Context> env;
48402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
49402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
50402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic void InitializeVM() {
516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Disable compilation of natives.
526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FLAG_disable_native_files = true;
53402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
54402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (env.IsEmpty()) {
55402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    env = v8::Context::New();
56402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
57402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
58402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
59402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
60402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#define __ assm.
61402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
63402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuTEST(MIPS0) {
64402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  InitializeVM();
65402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::HandleScope scope;
66402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
68402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
69402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Addition.
70402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addu(v0, a0, a1);
71402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ jr(ra);
72402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
73402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
74402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CodeDesc desc;
75402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  assm.GetCode(&desc);
7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
80402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CHECK(code->IsCode());
81402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
82402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
83402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ::printf("f() = %d\n", res);
84402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CHECK_EQ(0xabc, res);
85402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
86402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
87402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
88402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuTEST(MIPS1) {
89402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  InitializeVM();
90402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::HandleScope scope;
91402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
93402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Label L, C;
94402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
95402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ mov(a1, a0);
96402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(v0, 0);
97402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ b(&C);
98402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
99402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
100402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ bind(&L);
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(v0, v0, a1);
102402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addiu(a1, a1, -1);
103402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
104402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ bind(&C);
105402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ xori(v1, a1, 0);
10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&L, ne, v1, Operand(0));
107402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
108402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
109402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ jr(ra);
110402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
111402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
112402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CodeDesc desc;
113402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  assm.GetCode(&desc);
11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
118402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CHECK(code->IsCode());
119402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
120402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0));
121402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ::printf("f() = %d\n", res);
122402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CHECK_EQ(1275, res);
123402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
124402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
125402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
126402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuTEST(MIPS2) {
127402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  InitializeVM();
128402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::HandleScope scope;
129402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
131402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
132402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Label exit, error;
133402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
134402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // ----- Test all instructions.
135402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
136402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Test lui, ori, and addiu, used in the li pseudo-instruction.
137402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // This way we can then safely load registers with chosen values.
138402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
139402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ ori(t0, zero_reg, 0);
140402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ lui(t0, 0x1234);
141402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ ori(t0, t0, 0);
142402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ ori(t0, t0, 0x0f0f);
143402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ ori(t0, t0, 0xf0f0);
144402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addiu(t1, t0, 1);
145402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addiu(t2, t1, -0x10);
146402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
147402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Load values in temporary registers.
148402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t0, 0x00000004);
149402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t1, 0x00001234);
150402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t2, 0x12345678);
151402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t3, 0x7fffffff);
152402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t4, 0xfffffffc);
153402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t5, 0xffffedcc);
154402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t6, 0xedcba988);
155402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(t7, 0x80000000);
156402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
157402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // SPECIAL class.
158402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ srl(v0, t2, 8);    // 0x00123456
159402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ sll(v0, v0, 11);   // 0x91a2b000
160402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ sra(v0, v0, 3);    // 0xf2345600
161402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ srav(v0, v0, t0);  // 0xff234560
162402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ sllv(v0, v0, t0);  // 0xf2345600
163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ srlv(v0, v0, t0);  // 0x0f234560
16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x0f234560));
165402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
166402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(v0, t0, t1);   // 0x00001238
16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ subu(v0, v0, t0);  // 0x00001234
16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x00001234));
170402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addu(v1, t3, t0);
17244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v1, Operand(0x80000003));
173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ subu(v1, t7, t0);  // 0x7ffffffc
17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v1, Operand(0x7ffffffc));
176402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
177402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
178402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ and_(v0, t1, t2);  // 0x00001230
179402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ or_(v0, v0, t1);   // 0x00001234
180402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ xor_(v0, v0, t2);  // 0x1234444c
181402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nor(v0, v0, t2);   // 0xedcba987
18244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0xedcba983));
183402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
184402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
185402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ slt(v0, t7, t3);
18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x1));
187402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
188402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ sltu(v0, t7, t3);
18944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x0));
190402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
191402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // End of SPECIAL class.
192402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
19344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addiu(v0, zero_reg, 0x7421);  // 0x00007421
19444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addiu(v0, v0, -0x1);  // 0x00007420
195402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addiu(v0, v0, -0x20);  // 0x00007400
19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x00007400));
197402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
198402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ addiu(v1, t3, 0x1);  // 0x80000000
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v1, Operand(0x80000000));
200402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
201402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
202402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ slti(v0, t1, 0x00002000);  // 0x1
203402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ slti(v0, v0, 0xffff8000);  // 0x0
20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x0));
205402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
206402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ sltiu(v0, t1, 0x00002000);  // 0x1
207402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ sltiu(v0, v0, 0x00008000);  // 0x1
20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x1));
209402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
210402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
211402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ andi(v0, t1, 0xf0f0);  // 0x00001030
212402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ ori(v0, v0, 0x8a00);  // 0x00009a30
213402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ xori(v0, v0, 0x83cc);  // 0x000019fc
21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(0x000019fc));
215402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
216402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ lui(v1, 0x8123);  // 0x81230000
21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v1, Operand(0x81230000));
218402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
219402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Bit twiddling instructions & conditional moves.
22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Uses t0-t7 as set above.
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Clz(v0, t0);       // 29
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Clz(v1, t1);       // 19
22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(v0, v0, v1);  // 48
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Clz(v1, t2);       // 3
22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(v0, v0, v1);  // 51
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Clz(v1, t7);       // 0
22844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(v0, v0, v1);  // 51
22944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, v0, Operand(51));
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Movn(a0, t3, t0);  // Move a0<-t3 (t0 is NOT 0).
23144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ins(a0, t1, 12, 8);  // 0x7ff34fff
23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, a0, Operand(0x7ff34fff));
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Movz(a0, t6, t7);    // a0 not updated (t7 is NOT 0).
23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ext(a1, a0, 8, 12);  // 0x34f
23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, a1, Operand(0x34f));
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Movz(a0, t6, v1);    // a0<-t6, v0 is 0, from 8 instr back.
23744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&error, ne, a0, Operand(t6));
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
239402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Everything was correctly executed. Load the expected result.
240402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ li(v0, 0x31415926);
241402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ b(&exit);
242402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
243402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
244402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ bind(&error);
245402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Got an error. Return a wrong result.
24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(v0, 666);
247402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
248402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ bind(&exit);
249402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ jr(ra);
250402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ nop();
251402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
252402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CodeDesc desc;
253402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  assm.GetCode(&desc);
25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
25644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
25744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
258402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CHECK(code->IsCode());
259402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
260402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0));
261402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ::printf("f() = %d\n", res);
262402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CHECK_EQ(0x31415926, res);
263402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
264402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
26544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
26644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS3) {
26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test floating point instructions.
26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
26944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
27044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
27144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
27244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double a;
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double b;
27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double c;
27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double d;
27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double e;
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double f;
27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double g;
27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Create a function that accepts &t, and loads, manipulates, and stores
28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the doubles t.a ... t.f.
284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label L, C;
28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (CpuFeatures::IsSupported(FPU)) {
28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ add_d(f8, f4, f6);
29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) );  // c = a + b.
29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mov_d(f10, f8);  // c
29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ neg_d(f12, f6);  // -b
29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sub_d(f10, f10, f12);
29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) );  // d = c - (-b).
29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) );   // b = a.
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ li(t0, 120);
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t0, f14);
30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_d_w(f14, f14);   // f14 = 120.0.
30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mul_d(f10, f10, f14);
30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) );  // e = d * 120 = 1.8066e16.
30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ div_d(f12, f10, f4);
30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) );  // f = e / a = 120.44.
31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sqrt_d(f14, f12);
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // g = sqrt(f) = 10.97451593465515908537
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
31644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
31744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
31944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
32244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.a = 1.5e14;
32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.b = 2.75e11;
32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.c = 0.0;
32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.d = 0.0;
33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.e = 0.0;
33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.f = 0.0;
33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.5e14, t.a);
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.5e14, t.b);
33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.50275e14, t.c);
33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.50550e14, t.d);
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.8066e16, t.e);
33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(120.44, t.f);
34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(10.97451593465515908537, t.g);
34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
34544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS4) {
34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test moves between floating point and integer registers.
34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double a;
35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double b;
35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double c;
35444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
35544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label L, C;
35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (CpuFeatures::IsSupported(FPU)) {
36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
36244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
36544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Swap f4 and f6, by using four integer registers, t0-t3.
36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t0, f4);
36844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t1, f5);
36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t2, f6);
37044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t3, f7);
37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
37244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t0, f6);
37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t1, f7);
37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t2, f4);
37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t3, f5);
37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Store the swapped f4 and f5 back to memory.
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
38244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
38344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
38444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
38544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
38944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
39044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.a = 1.5e22;
39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.b = 2.75e11;
39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.c = 17.17;
39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(2.75e11, t.a);
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(2.75e11, t.b);
40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.5e22, t.c);
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
40544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS5) {
40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test conversions between doubles and integers.
40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double a;
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double b;
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int i;
41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int j;
41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
41744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label L, C;
42044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (CpuFeatures::IsSupported(FPU)) {
42244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
42344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Load all structure elements to registers.
42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
42744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) );
42844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
43044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Convert double in f4 to int in element i.
43144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_w_d(f8, f4);
43244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t2, f8);
43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) );
43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Convert double in f6 to int in element j.
43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_w_d(f10, f6);
43744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t3, f10);
43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) );
43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Convert int in original i (t0) to double in a.
44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t0, f12);
44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_d_w(f0, f12);
44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
44444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Convert int in original j (t1) to double in b.
44644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t1, f14);
44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_d_w(f2, f14);
44844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
45244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
45744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
45844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
45944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.a = 1.5e4;
46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.b = 2.75e8;
46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.i = 12345678;
46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.j = -100000;
46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(12345678.0, t.a);
46944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(-100000.0, t.b);
47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(15000, t.i);
47144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(275000000, t.j);
47244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
47444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
47644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS6) {
47744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test simple memory loads and stores.
47844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
48044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
48144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    uint32_t ui;
48344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t si;
48444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t r1;
48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t r2;
48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t r3;
48744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t r4;
48844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t r5;
48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t r6;
49044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
49144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
49444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label L, C;
49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
49644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Basic word load/store.
49744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, ui)) );
49844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(a0, OFFSET_OF(T, r1)) );
49944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
50044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // lh with positive data.
50144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lh(t1, MemOperand(a0, OFFSET_OF(T, ui)) );
50244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, r2)) );
50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
50444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // lh with negative data.
50544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lh(t2, MemOperand(a0, OFFSET_OF(T, si)) );
50644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, r3)) );
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
50844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // lhu with negative data.
50944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lhu(t3, MemOperand(a0, OFFSET_OF(T, si)) );
51044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, r4)) );
51144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
51244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // lb with negative data.
51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lb(t4, MemOperand(a0, OFFSET_OF(T, si)) );
51444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t4, MemOperand(a0, OFFSET_OF(T, r5)) );
51544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
51644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // sh writes only 1/2 of word.
51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lui(t5, 0x3333);
51844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ ori(t5, t5, 0x3333);
51944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lhu(t5, MemOperand(a0, OFFSET_OF(T, si)) );
52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sh(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
52244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
52344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ jr(ra);
52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
52544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
52644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeDesc desc;
52744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  assm.GetCode(&desc);
52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
52944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
53044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
53144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK(code->IsCode());
53344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
53444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.ui = 0x11223344;
53544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.si = 0x99aabbcc;
53644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
53744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  USE(dummy);
53844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
53944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x11223344, t.r1);
54044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x3344, t.r2);
54144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xffffbbcc, t.r3);
54244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x0000bbcc, t.r4);
54344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xffffffcc, t.r5);
54444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x3333bbcc, t.r6);
54544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
54644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
54744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
54844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS7) {
54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test floating point compare and branch instructions.
55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
55144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
55444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double a;
55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double b;
55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double c;
55744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double d;
55844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double e;
55944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double f;
56044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result;
56144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Create a function that accepts &t, and loads, manipulates, and stores
56544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the doubles t.a ... t.f.
566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label neither_is_nan, less_than, outa_here;
56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (CpuFeatures::IsSupported(FPU)) {
57044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
57144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
57244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
57344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
57444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ c(UN, D, f4, f6);
57544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ bc1f(&neither_is_nan);
57644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
57744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
57844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ Branch(&outa_here);
57944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
58044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ bind(&neither_is_nan);
58144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (kArchVariant == kLoongson) {
5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      __ c(OLT, D, f6, f4);
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      __ bc1t(&less_than);
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      __ c(OLT, D, f6, f4, 2);
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      __ bc1t(&less_than, 2);
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
58944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
59044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ Branch(&outa_here);
59244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
59344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ bind(&less_than);
59444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ Addu(t0, zero_reg, Operand(1));
59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) );  // Set true.
59644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
59844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // This test-case should have additional tests.
59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
60044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ bind(&outa_here);
60144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
60444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
60544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
60644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
60744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
60944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
61044f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
61144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
61244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
61344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.a = 1.5e14;
61444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.b = 2.75e11;
61544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.c = 2.0;
61644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.d = -4.0;
61744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.e = 0.0;
61844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.f = 0.0;
61944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.result = 0;
62044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
62144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
62244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.5e14, t.a);
62344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(2.75e11, t.b);
62444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1, t.result);
62544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
62644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
62744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
62844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
62944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS8) {
63044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test ROTR and ROTRV instructions.
63144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
63344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
63444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t input;
63644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_4;
63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_8;
63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_12;
63944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_16;
64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_20;
64144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_24;
64244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotr_28;
64344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_4;
64444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_8;
64544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_12;
64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_16;
64744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_20;
64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_24;
64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t result_rotrv_28;
65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
653257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
65444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Basic word load.
65644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, input)) );
65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // ROTR instruction (called through the Ror macro).
65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t1, t0, 0x0004);
66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t2, t0, 0x0008);
66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t3, t0, 0x000c);
66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t4, t0, 0x0010);
66344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t5, t0, 0x0014);
66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t6, t0, 0x0018);
66544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t7, t0, 0x001c);
66644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
66744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Basic word store.
66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
67044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
67144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // ROTRV instruction (called through the Ror macro).
67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x0004);
67844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t1, t0, t7);
67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x0008);
68044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t2, t0, t7);
68144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x000C);
68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t3, t0, t7);
68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x0010);
68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t4, t0, t7);
68544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x0014);
68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t5, t0, t7);
68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x0018);
68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t6, t0, t7);
68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ li(t7, 0x001C);
69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Ror(t7, t0, t7);
69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
69244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Basic word store.
69344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
69444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
69744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
69844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
69944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
70044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
70144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ jr(ra);
70244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
70344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
70444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeDesc desc;
70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  assm.GetCode(&desc);
70644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
71044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK(code->IsCode());
71144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
71244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.input = 0x12345678;
71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0);
71444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  USE(dummy);
71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x81234567, t.result_rotr_4);
71644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x78123456, t.result_rotr_8);
71744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x67812345, t.result_rotr_12);
71844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x56781234, t.result_rotr_16);
71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x45678123, t.result_rotr_20);
72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x34567812, t.result_rotr_24);
72144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x23456781, t.result_rotr_28);
72244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
72344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x81234567, t.result_rotrv_4);
72444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x78123456, t.result_rotrv_8);
72544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x67812345, t.result_rotrv_12);
72644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x56781234, t.result_rotrv_16);
72744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x45678123, t.result_rotrv_20);
72844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x34567812, t.result_rotrv_24);
72944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x23456781, t.result_rotrv_28);
73044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
73144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
73244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
73344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS9) {
73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test BRANCH improvements.
73544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
73644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
73944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label exit, exit2, exit3;
74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&exit, ge, a0, Operand(0x00000000));
74244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&exit2, ge, a0, Operand(0x00001FFF));
74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Branch(&exit3, ge, a0, Operand(0x0001FFFF));
74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
74544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ bind(&exit);
74644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ bind(&exit2);
74744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ bind(&exit3);
74844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ jr(ra);
74944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
75044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
75144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeDesc desc;
75244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  assm.GetCode(&desc);
75344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
75444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
75644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
75744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK(code->IsCode());
75844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
75944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
76044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
76144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS10) {
76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test conversions between doubles and long integers.
76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test hos the long ints map to FP regs pairs.
76444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
76544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
76844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double a;
76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double b;
77044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t dbl_mant;
77144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t dbl_exp;
77244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t long_hi;
77344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t long_lo;
77444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t b_long_hi;
77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t b_long_lo;
77644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
77744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
77844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
78044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Label L, C;
78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (CpuFeatures::IsSupported(FPU) && kArchVariant == kMips32r2) {
78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
78544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Load all structure elements to registers.
78644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
78744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
78844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Save the raw bits of the double.
78944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t0, f0);
79044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t1, f1);
79144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
79244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
79344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Convert double in f0 to long, save hi/lo parts.
79544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_l_d(f0, f0);
79644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t0, f0);  // f0 has LS 32 bits of long.
79744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mfc1(t1, f1);  // f1 has MS 32 bits of long.
79844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t0, MemOperand(a0, OFFSET_OF(T, long_lo)));
79944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t1, MemOperand(a0, OFFSET_OF(T, long_hi)));
80044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Convert the b long integers to double b.
80244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
80344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ lw(t1, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
80444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t0, f8);  // f8 has LS 32-bits.
80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ mtc1(t1, f9);  // f9 has MS 32-bits.
80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cvt_d_l(f10, f8);
80744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
80844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
80944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
81044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
81144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
81244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
81444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
81544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
81644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
81744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
81844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
81944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.a = 2.147483647e9;       // 0x7fffffff -> 0x41DFFFFFFFC00000 as double.
82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.b_long_hi = 0x000000ff;  // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double.
82244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.b_long_lo = 0x00ff00ff;
82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
82544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
82644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(0x41DFFFFF, t.dbl_exp);
82744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(0xFFC00000, t.dbl_mant);
82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(0, t.long_hi);
82944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(0x7fffffff, t.long_lo);
83044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // 0xFF00FF00FF -> 1.095233372415e12.
83144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(1.095233372415e12, t.b);
83244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
83344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
83444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
83544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
83644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS11) {
83744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test LWL, LWR, SWL and SWR instructions.
83844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
83944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
84044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
84144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
84244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t reg_init;
84344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t mem_init;
84444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwl_0;
84544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwl_1;
84644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwl_2;
84744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwl_3;
84844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwr_0;
84944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwr_1;
85044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwr_2;
85144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t lwr_3;
85244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swl_0;
85344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swl_1;
85444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swl_2;
85544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swl_3;
85644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swr_0;
85744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swr_1;
85844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swr_2;
85944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int32_t swr_3;
86044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
86144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
86244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
86444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
86544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test all combinations of LWL and vAddr.
86644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
86744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwl(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
86844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwl_0)) );
86944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
87044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
87144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwl(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
87244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwl_1)) );
87344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
87444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
87544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwl(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
87644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwl_2)) );
87744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
87844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
87944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwl(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
88044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwl_3)) );
88144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
88244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test all combinations of LWR and vAddr.
88344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
88444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwr(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
88544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwr_0)) );
88644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
88744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
88844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwr(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
88944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwr_1)) );
89044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
89144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
89244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwr(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
89344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
89444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
89544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
89644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lwr(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
89744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
89844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
89944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test all combinations of SWL and vAddr.
90044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
90144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
90244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
90344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swl(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
90444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
90544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
90644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, swl_1)) );
90744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
90844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swl(t1, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) );
90944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
91044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
91144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, swl_2)) );
91244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
91344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swl(t2, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) );
91444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
91544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
91644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, swl_3)) );
91744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
91844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swl(t3, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) );
91944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
92044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test all combinations of SWR and vAddr.
92144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
92244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
92344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
92444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swr(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
92644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
92744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t1, MemOperand(a0, OFFSET_OF(T, swr_1)) );
92844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
92944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swr(t1, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) );
93044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
93144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
93244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t2, MemOperand(a0, OFFSET_OF(T, swr_2)) );
93344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
93444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swr(t2, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) );
93544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
93644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
93744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t3, MemOperand(a0, OFFSET_OF(T, swr_3)) );
93844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
93944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ swr(t3, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) );
94044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
94144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ jr(ra);
94244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
94344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
94444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeDesc desc;
94544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  assm.GetCode(&desc);
94644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
94744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
94844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
94944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
95044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK(code->IsCode());
95144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
95244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.reg_init = 0xaabbccdd;
95344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.mem_init = 0x11223344;
95444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
95544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
95644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  USE(dummy);
95744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
95844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x44bbccdd, t.lwl_0);
95944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x3344ccdd, t.lwl_1);
96044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x223344dd, t.lwl_2);
96144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x11223344, t.lwl_3);
96244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
96344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x11223344, t.lwr_0);
96444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xaa112233, t.lwr_1);
96544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xaabb1122, t.lwr_2);
96644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xaabbcc11, t.lwr_3);
96744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
96844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x112233aa, t.swl_0);
96944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x1122aabb, t.swl_1);
97044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0x11aabbcc, t.swl_2);
97144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xaabbccdd, t.swl_3);
97244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
97344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xaabbccdd, t.swr_0);
97444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xbbccdd44, t.swr_1);
97544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xccdd3344, t.swr_2);
97644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(0xdd223344, t.swr_3);
97744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
97844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
97944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
98044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS12) {
98144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
98244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
98344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
98444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
98544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int32_t  x;
98644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int32_t  y;
98744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int32_t  y1;
98844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int32_t  y2;
98944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int32_t  y3;
99044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int32_t  y4;
99144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
99244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
99344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
99544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ mov(t6, fp);  // Save frame pointer.
99744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ mov(fp, a0);  // Access struct T by fp.
99844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(a0, OFFSET_OF(T, y)) );
99944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t3, MemOperand(a0, OFFSET_OF(T, y4)) );
100044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
100144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(t1, t0, t3);
100244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ subu(t4, t0, t3);
100344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1004257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t0);  // These instructions disappear after opt.
100544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Pop();
100644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ addu(t0, t0, t0);
100744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
100844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ Pop();     // These instructions disappear after opt.
1009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t3);
101044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t3);  // These instructions disappear after opt.
1012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t3);
101344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1014257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t3);
1015257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t4);
101644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
101744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
101844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
101944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
102044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
102144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
102244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t1);
102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
1025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t1);
102644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t1);
102844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
1029257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t1);
103044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t1);
103244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
1033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t2);
103444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1035257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t2);
103644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
1037257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t1);
103844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
1039257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ push(t1);
104044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
1041257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  __ pop(t3);
104244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
104344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
104444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ mov(fp, t6);
104544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ jr(ra);
104644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ nop();
104744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
104844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CodeDesc desc;
104944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  assm.GetCode(&desc);
105044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* code = HEAP->CreateCode(
105144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      desc,
105244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Code::ComputeFlags(Code::STUB),
105344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
105444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK(code->IsCode());
105544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.x = 1;
105744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.y = 2;
105844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.y1 = 3;
105944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.y2 = 4;
106044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.y3 = 0XBABA;
106144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  t.y4 = 0xDEDA;
106244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
106344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
106444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  USE(dummy);
106544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
106644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(3, t.y1);
106744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
106844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
106944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
107044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS13) {
107144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test Cvt_d_uw and Trunc_uw_d macros.
107244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
107444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
107544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
107644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double cvt_big_out;
107744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double cvt_small_out;
107844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    uint32_t trunc_big_out;
107944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    uint32_t trunc_small_out;
108044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    uint32_t cvt_big_in;
108144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    uint32_t cvt_small_in;
108244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
108344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
108444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1085257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
108644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (CpuFeatures::IsSupported(FPU)) {
108844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
108944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
109044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
109169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    __ Cvt_d_uw(f10, t0, f22);
109244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
109344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
109469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    __ Trunc_uw_d(f10, f10, f22);
109544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
109644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
109744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
109869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    __ Cvt_d_uw(f8, t0, f22);
109944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
110044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
110169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    __ Trunc_uw_d(f8, f8, f22);
110244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
110344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
110444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
110544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
110644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
110744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
110844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
110944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
111044f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
111144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
111244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
111344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
111444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
111544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
111644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.cvt_big_in = 0xFFFFFFFF;
111744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.cvt_small_in  = 333;
111844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
111944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
112044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
112144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
112244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in));
112344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(t.cvt_small_out, static_cast<double>(t.cvt_small_in));
112444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
112544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(static_cast<int>(t.trunc_big_out), static_cast<int>(t.cvt_big_in));
112644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK_EQ(static_cast<int>(t.trunc_small_out),
112744f0eee88ff00398ff7f715fab053374d808c90dSteve Block             static_cast<int>(t.cvt_small_in));
112844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
112944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
113044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
113144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
113244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockTEST(MIPS14) {
113344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Test round, floor, ceil, trunc, cvt.
113444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  InitializeVM();
113544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::HandleScope scope;
113644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
113744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ROUND_STRUCT_ELEMENT(x) \
113844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t x##_up_out; \
113944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t x##_down_out; \
114044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t neg_##x##_up_out; \
114144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t neg_##x##_down_out; \
1142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  uint32_t x##_err1_out; \
1143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  uint32_t x##_err2_out; \
1144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  uint32_t x##_err3_out; \
1145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  uint32_t x##_err4_out; \
114644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t x##_invalid_result;
114744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
114844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  typedef struct {
114944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double round_up_in;
115044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double round_down_in;
115144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double neg_round_up_in;
115244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double neg_round_down_in;
115344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double err1_in;
115444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double err2_in;
115544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double err3_in;
115644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    double err4_in;
115744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
115844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ROUND_STRUCT_ELEMENT(round)
115944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ROUND_STRUCT_ELEMENT(floor)
116044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ROUND_STRUCT_ELEMENT(ceil)
116144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ROUND_STRUCT_ELEMENT(trunc)
116244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ROUND_STRUCT_ELEMENT(cvt)
116344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } T;
116444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  T t;
116544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
116644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef ROUND_STRUCT_ELEMENT
116744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  MacroAssembler assm(Isolate::Current(), NULL, 0);
116944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1170257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (CpuFeatures::IsSupported(FPU)) {
117144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CpuFeatures::Scope scope(FPU);
117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
117344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Save FCSR.
117444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cfc1(a1, FCSR);
117544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Disable FPU exceptions.
117644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ctc1(zero_reg, FCSR);
117744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define RUN_ROUND_TEST(x) \
117844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
117944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
118044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
118144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
118244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
118344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
118444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
118544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
118644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
118744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
118844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
118944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
119044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
119144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
119244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
119344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
119544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ctc1(zero_reg, FCSR); \
119644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
119744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cfc1(a2, FCSR); \
119844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
119944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
120044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
120144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ctc1(zero_reg, FCSR); \
120244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
120344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cfc1(a2, FCSR); \
120444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
120544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
120644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
120744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ctc1(zero_reg, FCSR); \
120844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
120944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cfc1(a2, FCSR); \
121044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
121144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    \
121244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
121344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ctc1(zero_reg, FCSR); \
121444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ x##_w_d(f0, f0); \
121544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ cfc1(a2, FCSR); \
121644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
121744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
121844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
121944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RUN_ROUND_TEST(round)
122044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RUN_ROUND_TEST(floor)
122144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RUN_ROUND_TEST(ceil)
122244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RUN_ROUND_TEST(trunc)
122344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RUN_ROUND_TEST(cvt)
122444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
122544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Restore FCSR.
122644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ ctc1(a1, FCSR);
122744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
122844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ jr(ra);
122944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    __ nop();
123044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
123144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CodeDesc desc;
123244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    assm.GetCode(&desc);
123344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* code = HEAP->CreateCode(
123444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc,
123544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Code::ComputeFlags(Code::STUB),
123644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
123744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
123844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
123944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
124044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.round_up_in = 123.51;
124144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.round_down_in = 123.49;
124244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.neg_round_up_in = -123.5;
124344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.neg_round_down_in = -123.49;
124444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.err1_in = 123.51;
124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.err2_in = 1;
124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.err3_in = static_cast<double>(1) + 0xFFFFFFFF;
124744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    t.err4_in = NAN;
124844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
124944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
125044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    USE(dummy);
125144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
12523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask))
12533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define CHECK_ROUND_RESULT(type) \
12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \
12553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \
12563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \
12573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \
12583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  CHECK_EQ(kFPUInvalidResult, t.type##_invalid_result);
12593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CHECK_ROUND_RESULT(round);
12613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CHECK_ROUND_RESULT(floor);
12623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CHECK_ROUND_RESULT(ceil);
12633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CHECK_ROUND_RESULT(cvt);
126444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
126544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
126644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
126769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
126869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(MIPS15) {
126969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Test chaining of label usages within instructions (issue 1644).
127069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  InitializeVM();
127169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  v8::HandleScope scope;
127269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Assembler assm(Isolate::Current(), NULL, 0);
127369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
127469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Label target;
127569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ beq(v0, v1, &target);
1276589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  __ nop();
127769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ bne(v0, v1, &target);
1278589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  __ nop();
127969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ bind(&target);
128069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ nop();
128169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
128269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
1283402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#undef __
1284