| Index: test/cctest/test-assembler-s390.cc
|
| diff --git a/test/cctest/test-assembler-s390.cc b/test/cctest/test-assembler-s390.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dee8e079351740fd14cfafa94881a9f4cad2b950
|
| --- /dev/null
|
| +++ b/test/cctest/test-assembler-s390.cc
|
| @@ -0,0 +1,416 @@
|
| +// Copyright 2014 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 "src/v8.h"
|
| +
|
| +#include "src/disassembler.h"
|
| +#include "src/factory.h"
|
| +#include "src/macro-assembler.h"
|
| +#include "src/s390/assembler-s390-inl.h"
|
| +#include "src/s390/simulator-s390.h"
|
| +#include "test/cctest/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* p0, int p1, int p2, int p3, int p4);
|
| +typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
|
| +
|
| +#define __ assm.
|
| +
|
| +// Simple add parameter 1 to parameter 2 and return
|
| +TEST(0) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + Assembler assm(isolate, NULL, 0);
|
| +
|
| + __ lhi(r1, Operand(3)); // test 4-byte instr
|
| + __ llilf(r2, Operand(4)); // test 6-byte instr
|
| + __ lgr(r2, r2); // test 2-byte opcode
|
| + __ ar(r2, r1); // test 2-byte instr
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F2 f = FUNCTION_CAST<F2>(code->entry());
|
| + intptr_t res = reinterpret_cast<intptr_t>(
|
| + CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0));
|
| + ::printf("f() = %" V8PRIxPTR "\n", res);
|
| + CHECK_EQ(7, static_cast<int>(res));
|
| +}
|
| +
|
| +// Loop 100 times, adding loop counter to result
|
| +TEST(1) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + Assembler assm(isolate, NULL, 0);
|
| + Label L, C;
|
| +
|
| +#if defined(_AIX)
|
| + __ function_descriptor();
|
| +#endif
|
| +
|
| + __ lr(r3, r2);
|
| + __ lhi(r2, Operand(0, kRelocInfo_NONEPTR));
|
| + __ b(&C);
|
| +
|
| + __ bind(&L);
|
| + __ ar(r2, r3);
|
| + __ ahi(r3, Operand(-1 & 0xFFFF));
|
| +
|
| + __ bind(&C);
|
| + __ cfi(r3, Operand(0, kRelocInfo_NONEPTR));
|
| + __ bne(&L);
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F1 f = FUNCTION_CAST<F1>(code->entry());
|
| + intptr_t res = reinterpret_cast<intptr_t>(
|
| + CALL_GENERATED_CODE(isolate, f, 100, 0, 0, 0, 0));
|
| + ::printf("f() = %" V8PRIxPTR "\n", res);
|
| + CHECK_EQ(5050, static_cast<int>(res));
|
| +}
|
| +
|
| +TEST(2) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + // Create a function that accepts &t, and loads, manipulates, and stores
|
| + // the doubles and floats.
|
| + Assembler assm(CcTest::i_isolate(), NULL, 0);
|
| + Label L, C;
|
| +
|
| +#if defined(_AIX)
|
| + __ function_descriptor();
|
| +#endif
|
| +
|
| + __ lgr(r3, r2);
|
| + __ lhi(r2, Operand(1));
|
| + __ b(&C);
|
| +
|
| + __ bind(&L);
|
| + __ lr(r5, r2); // Set up muliplicant in R4:R5
|
| + __ mr_z(r4, r3); // this is actually R4:R5 = R5 * R2
|
| + __ lr(r2, r5);
|
| + __ ahi(r3, Operand(-1 & 0xFFFF));
|
| +
|
| + __ bind(&C);
|
| + __ cfi(r3, Operand(0, kRelocInfo_NONEPTR));
|
| + __ bne(&L);
|
| + __ b(r14);
|
| +
|
| + // some relocated stuff here, not executed
|
| + __ RecordComment("dead code, just testing relocations");
|
| + __ iilf(r0, Operand(isolate->factory()->true_value()));
|
| + __ RecordComment("dead code, just testing immediate operands");
|
| + __ iilf(r0, Operand(-1));
|
| + __ iilf(r0, Operand(0xFF000000));
|
| + __ iilf(r0, Operand(0xF0F0F0F0));
|
| + __ iilf(r0, Operand(0xFFF0FFFF));
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F1 f = FUNCTION_CAST<F1>(code->entry());
|
| + intptr_t res = reinterpret_cast<intptr_t>(
|
| + CALL_GENERATED_CODE(isolate, f, 10, 0, 0, 0, 0));
|
| + ::printf("f() = %" V8PRIxPTR "\n", res);
|
| + CHECK_EQ(3628800, static_cast<int>(res));
|
| +}
|
| +
|
| +TEST(3) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + Assembler assm(isolate, NULL, 0);
|
| +
|
| + __ ar(r14, r13);
|
| + __ sr(r14, r13);
|
| + __ mr_z(r14, r13);
|
| + __ dr(r14, r13);
|
| + __ or_z(r14, r13);
|
| + __ nr(r14, r13);
|
| + __ xr(r14, r13);
|
| +
|
| + __ agr(r14, r13);
|
| + __ sgr(r14, r13);
|
| + __ ogr(r14, r13);
|
| + __ ngr(r14, r13);
|
| + __ xgr(r14, r13);
|
| +
|
| + __ ahi(r13, Operand(123));
|
| + __ aghi(r13, Operand(123));
|
| + __ stm(r1, r2, MemOperand(r3, r0, 123));
|
| + __ slag(r1, r2, Operand(123));
|
| + __ lay(r1, MemOperand(r2, r3, -123));
|
| + __ a(r13, MemOperand(r1, r2, 123));
|
| + __ ay(r13, MemOperand(r1, r2, 123));
|
| + __ brc(Condition(14), Operand(123));
|
| + __ brc(Condition(14), Operand(-123));
|
| + __ brcl(Condition(14), Operand(123), false);
|
| + __ brcl(Condition(14), Operand(-123), false);
|
| + __ iilf(r13, Operand(123456789));
|
| + __ iihf(r13, Operand(-123456789));
|
| + __ mvc(MemOperand(r0, 123), MemOperand(r4, 567), 89);
|
| + __ sll(r13, Operand(10));
|
| +
|
| + v8::internal::byte* bufPos = assm.buffer_pos();
|
| + ::printf("buffer position = %p", bufPos);
|
| + ::fflush(stdout);
|
| + // OS::DebugBreak();
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + USE(code);
|
| + ::exit(0);
|
| +}
|
| +
|
| +#if 0
|
| +TEST(4) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + Assembler assm(isolate, NULL, 0);
|
| + Label L2, L3, L4;
|
| +
|
| + __ chi(r2, Operand(10));
|
| + __ ble(&L2);
|
| + __ lr(r2, r4);
|
| + __ ar(r2, r3);
|
| + __ b(&L3);
|
| +
|
| + __ bind(&L2);
|
| + __ chi(r2, Operand(5));
|
| + __ bgt(&L4);
|
| +
|
| + __ lhi(r2, Operand::Zero());
|
| + __ b(&L3);
|
| +
|
| + __ bind(&L4);
|
| + __ lr(r2, r3);
|
| + __ sr(r2, r4);
|
| +
|
| + __ bind(&L3);
|
| + __ lgfr(r2, r3);
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F2 f = FUNCTION_CAST<F2>(code->entry());
|
| + intptr_t res = reinterpret_cast<intptr_t>(
|
| + CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
|
| + ::printf("f() = %" V8PRIdPTR "\n", res);
|
| + CHECK_EQ(4, static_cast<int>(res));
|
| +}
|
| +
|
| +
|
| +// Test ExtractBitRange
|
| +TEST(5) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + MacroAssembler assm(isolate, NULL, 0);
|
| +
|
| + __ mov(r2, Operand(0x12345678));
|
| + __ ExtractBitRange(r3, r2, 3, 2);
|
| + __ lgfr(r2, r3);
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F2 f = FUNCTION_CAST<F2>(code->entry());
|
| + intptr_t res =
|
| + reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
|
| + ::printf("f() = %" V8PRIdPTR "\n", res);
|
| + CHECK_EQ(2, static_cast<int>(res));
|
| +}
|
| +
|
| +
|
| +// Test JumpIfSmi
|
| +TEST(6) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + MacroAssembler assm(isolate, NULL, 0);
|
| +
|
| + Label yes;
|
| +
|
| + __ mov(r2, Operand(0x12345678));
|
| + __ JumpIfSmi(r2, &yes);
|
| + __ beq(&yes);
|
| + __ Load(r2, Operand::Zero());
|
| + __ b(r14);
|
| + __ bind(&yes);
|
| + __ Load(r2, Operand(1));
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F2 f = FUNCTION_CAST<F2>(code->entry());
|
| + intptr_t res =
|
| + reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
|
| + ::printf("f() = %" V8PRIdPTR "\n", res);
|
| + CHECK_EQ(1, static_cast<int>(res));
|
| +}
|
| +
|
| +
|
| +// Test fix<->floating point conversion.
|
| +TEST(7) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + MacroAssembler assm(isolate, NULL, 0);
|
| +
|
| + Label yes;
|
| +
|
| + __ mov(r3, Operand(0x1234));
|
| + __ cdfbr(d1, r3);
|
| + __ ldr(d2, d1);
|
| + __ adbr(d1, d2);
|
| + __ cfdbr(Condition(0), r2, d1);
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F2 f = FUNCTION_CAST<F2>(code->entry());
|
| + intptr_t res =
|
| + reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
|
| + ::printf("f() = %" V8PRIdPTR "\n", res);
|
| + CHECK_EQ(0x2468, static_cast<int>(res));
|
| +}
|
| +
|
| +
|
| +// Test DSGR
|
| +TEST(8) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + MacroAssembler assm(isolate, NULL, 0);
|
| +
|
| + // Zero upper bits of r3/r4
|
| + __ llihf(r3, Operand::Zero());
|
| + __ llihf(r4, Operand::Zero());
|
| + __ mov(r3, Operand(0x0002));
|
| + __ mov(r4, Operand(0x0002));
|
| + __ dsgr(r2, r4);
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F1 f = FUNCTION_CAST<F1>(code->entry());
|
| + intptr_t res =
|
| + reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 100, 0,
|
| + 0, 0, 0));
|
| + ::printf("f() = %" V8PRIdPTR "\n", res);
|
| + CHECK_EQ(0, static_cast<int>(res));
|
| +}
|
| +
|
| +
|
| +// Test LZDR
|
| +TEST(9) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + MacroAssembler assm(isolate, NULL, 0);
|
| +
|
| + __ lzdr(d4);
|
| + __ b(r14);
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef DEBUG
|
| + code->Print();
|
| +#endif
|
| + F1 f = FUNCTION_CAST<F1>(code->entry());
|
| + intptr_t res =
|
| + reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
|
| + ::printf("f() = %" V8PRIdPTR "\n", res);
|
| +}
|
| +#endif
|
| +
|
| +#undef __
|
|
|