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