diff options
Diffstat (limited to 'deps/v8/test/cctest/test-assembler-mips.cc')
-rw-r--r-- | deps/v8/test/cctest/test-assembler-mips.cc | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc new file mode 100644 index 000000000..ab011a73e --- /dev/null +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -0,0 +1,257 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "v8.h" + +#include "disassembler.h" +#include "factory.h" +#include "macro-assembler.h" +#include "mips/macro-assembler-mips.h" +#include "mips/simulator-mips.h" + +#include "cctest.h" + +using namespace v8::internal; + + +// Define these function prototypes to match JSEntryFunction in execution.cc. +typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); +typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); +typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); + + +static v8::Persistent<v8::Context> env; + + +// The test framework does not accept flags on the command line, so we set them. +static void InitializeVM() { + // Disable compilation of natives by specifying an empty natives file. + FLAG_natives_file = ""; + + // Enable generation of comments. + FLAG_debug_code = true; + + if (env.IsEmpty()) { + env = v8::Context::New(); + } +} + + +#define __ assm. + +TEST(MIPS0) { + InitializeVM(); + v8::HandleScope scope; + + MacroAssembler assm(NULL, 0); + + // Addition. + __ addu(v0, a0, a1); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value())); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry()); + int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); + ::printf("f() = %d\n", res); + CHECK_EQ(0xabc, res); +} + + +TEST(MIPS1) { + InitializeVM(); + v8::HandleScope scope; + + MacroAssembler assm(NULL, 0); + Label L, C; + + __ mov(a1, a0); + __ li(v0, 0); + __ b(&C); + __ nop(); + + __ bind(&L); + __ add(v0, v0, a1); + __ addiu(a1, a1, -1); + + __ bind(&C); + __ xori(v1, a1, 0); + __ Branch(ne, &L, v1, Operand(0)); + __ nop(); + + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value())); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); + int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0)); + ::printf("f() = %d\n", res); + CHECK_EQ(1275, res); +} + + +TEST(MIPS2) { + InitializeVM(); + v8::HandleScope scope; + + MacroAssembler assm(NULL, 0); + + Label exit, error; + + // ----- Test all instructions. + + // Test lui, ori, and addiu, used in the li pseudo-instruction. + // This way we can then safely load registers with chosen values. + + __ ori(t0, zero_reg, 0); + __ lui(t0, 0x1234); + __ ori(t0, t0, 0); + __ ori(t0, t0, 0x0f0f); + __ ori(t0, t0, 0xf0f0); + __ addiu(t1, t0, 1); + __ addiu(t2, t1, -0x10); + + // Load values in temporary registers. + __ li(t0, 0x00000004); + __ li(t1, 0x00001234); + __ li(t2, 0x12345678); + __ li(t3, 0x7fffffff); + __ li(t4, 0xfffffffc); + __ li(t5, 0xffffedcc); + __ li(t6, 0xedcba988); + __ li(t7, 0x80000000); + + // SPECIAL class. + __ srl(v0, t2, 8); // 0x00123456 + __ sll(v0, v0, 11); // 0x91a2b000 + __ sra(v0, v0, 3); // 0xf2345600 + __ srav(v0, v0, t0); // 0xff234560 + __ sllv(v0, v0, t0); // 0xf2345600 + __ srlv(v0, v0, t0); // 0x0f234560 + __ Branch(ne, &error, v0, Operand(0x0f234560)); + __ nop(); + + __ add(v0, t0, t1); // 0x00001238 + __ sub(v0, v0, t0); // 0x00001234 + __ Branch(ne, &error, v0, Operand(0x00001234)); + __ nop(); + __ addu(v1, t3, t0); + __ Branch(ne, &error, v1, Operand(0x80000003)); + __ nop(); + __ subu(v1, t7, t0); // 0x7ffffffc + __ Branch(ne, &error, v1, Operand(0x7ffffffc)); + __ nop(); + + __ and_(v0, t1, t2); // 0x00001230 + __ or_(v0, v0, t1); // 0x00001234 + __ xor_(v0, v0, t2); // 0x1234444c + __ nor(v0, v0, t2); // 0xedcba987 + __ Branch(ne, &error, v0, Operand(0xedcba983)); + __ nop(); + + __ slt(v0, t7, t3); + __ Branch(ne, &error, v0, Operand(0x1)); + __ nop(); + __ sltu(v0, t7, t3); + __ Branch(ne, &error, v0, Operand(0x0)); + __ nop(); + // End of SPECIAL class. + + __ addi(v0, zero_reg, 0x7421); // 0x00007421 + __ addi(v0, v0, -0x1); // 0x00007420 + __ addiu(v0, v0, -0x20); // 0x00007400 + __ Branch(ne, &error, v0, Operand(0x00007400)); + __ nop(); + __ addiu(v1, t3, 0x1); // 0x80000000 + __ Branch(ne, &error, v1, Operand(0x80000000)); + __ nop(); + + __ slti(v0, t1, 0x00002000); // 0x1 + __ slti(v0, v0, 0xffff8000); // 0x0 + __ Branch(ne, &error, v0, Operand(0x0)); + __ nop(); + __ sltiu(v0, t1, 0x00002000); // 0x1 + __ sltiu(v0, v0, 0x00008000); // 0x1 + __ Branch(ne, &error, v0, Operand(0x1)); + __ nop(); + + __ andi(v0, t1, 0xf0f0); // 0x00001030 + __ ori(v0, v0, 0x8a00); // 0x00009a30 + __ xori(v0, v0, 0x83cc); // 0x000019fc + __ Branch(ne, &error, v0, Operand(0x000019fc)); + __ nop(); + __ lui(v1, 0x8123); // 0x81230000 + __ Branch(ne, &error, v1, Operand(0x81230000)); + __ nop(); + + // Everything was correctly executed. Load the expected result. + __ li(v0, 0x31415926); + __ b(&exit); + __ nop(); + + __ bind(&error); + // Got an error. Return a wrong result. + + __ bind(&exit); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Object* code = Heap::CreateCode(desc, + NULL, + Code::ComputeFlags(Code::STUB), + Handle<Object>(Heap::undefined_value())); + CHECK(code->IsCode()); +#ifdef DEBUG + Code::cast(code)->Print(); +#endif + F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry()); + int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); + ::printf("f() = %d\n", res); + CHECK_EQ(0x31415926, res); +} + +#undef __ |