blob: ab6796bf18ccc0c5064dd3fef425d681c60a455e [file] [log] [blame]
Ben Murdochda12d292016-06-02 14:46:10 +01001// Copyright 2014 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "src/v8.h"
29
30#include "src/disassembler.h"
31#include "src/factory.h"
32#include "src/macro-assembler.h"
33#include "src/s390/assembler-s390-inl.h"
34#include "src/s390/simulator-s390.h"
35#include "test/cctest/cctest.h"
36
37using namespace v8::internal;
38
39// Define these function prototypes to match JSEntryFunction in execution.cc.
40typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
41typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
42typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
43typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
44
45#define __ assm.
46
47// Simple add parameter 1 to parameter 2 and return
48TEST(0) {
49 CcTest::InitializeVM();
50 Isolate* isolate = CcTest::i_isolate();
51 HandleScope scope(isolate);
52
53 Assembler assm(isolate, NULL, 0);
54
55 __ lhi(r1, Operand(3)); // test 4-byte instr
56 __ llilf(r2, Operand(4)); // test 6-byte instr
57 __ lgr(r2, r2); // test 2-byte opcode
58 __ ar(r2, r1); // test 2-byte instr
59 __ b(r14);
60
61 CodeDesc desc;
62 assm.GetCode(&desc);
63 Handle<Code> code = isolate->factory()->NewCode(
64 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
65#ifdef DEBUG
66 code->Print();
67#endif
68 F2 f = FUNCTION_CAST<F2>(code->entry());
69 intptr_t res = reinterpret_cast<intptr_t>(
70 CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0));
71 ::printf("f() = %" V8PRIxPTR "\n", res);
72 CHECK_EQ(7, static_cast<int>(res));
73}
74
75// Loop 100 times, adding loop counter to result
76TEST(1) {
77 CcTest::InitializeVM();
78 Isolate* isolate = CcTest::i_isolate();
79 HandleScope scope(isolate);
80
81 Assembler assm(isolate, NULL, 0);
82 Label L, C;
83
84#if defined(_AIX)
85 __ function_descriptor();
86#endif
87
88 __ lr(r3, r2);
89 __ lhi(r2, Operand(0, kRelocInfo_NONEPTR));
90 __ b(&C);
91
92 __ bind(&L);
93 __ ar(r2, r3);
94 __ ahi(r3, Operand(-1 & 0xFFFF));
95
96 __ bind(&C);
97 __ cfi(r3, Operand(0, kRelocInfo_NONEPTR));
98 __ bne(&L);
99 __ b(r14);
100
101 CodeDesc desc;
102 assm.GetCode(&desc);
103 Handle<Code> code = isolate->factory()->NewCode(
104 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
105#ifdef DEBUG
106 code->Print();
107#endif
108 F1 f = FUNCTION_CAST<F1>(code->entry());
109 intptr_t res = reinterpret_cast<intptr_t>(
110 CALL_GENERATED_CODE(isolate, f, 100, 0, 0, 0, 0));
111 ::printf("f() = %" V8PRIxPTR "\n", res);
112 CHECK_EQ(5050, static_cast<int>(res));
113}
114
115TEST(2) {
116 CcTest::InitializeVM();
117 Isolate* isolate = CcTest::i_isolate();
118 HandleScope scope(isolate);
119
120 // Create a function that accepts &t, and loads, manipulates, and stores
121 // the doubles and floats.
122 Assembler assm(CcTest::i_isolate(), NULL, 0);
123 Label L, C;
124
125#if defined(_AIX)
126 __ function_descriptor();
127#endif
128
129 __ lgr(r3, r2);
130 __ lhi(r2, Operand(1));
131 __ b(&C);
132
133 __ bind(&L);
134 __ lr(r5, r2); // Set up muliplicant in R4:R5
135 __ mr_z(r4, r3); // this is actually R4:R5 = R5 * R2
136 __ lr(r2, r5);
137 __ ahi(r3, Operand(-1 & 0xFFFF));
138
139 __ bind(&C);
140 __ cfi(r3, Operand(0, kRelocInfo_NONEPTR));
141 __ bne(&L);
142 __ b(r14);
143
144 // some relocated stuff here, not executed
145 __ RecordComment("dead code, just testing relocations");
146 __ iilf(r0, Operand(isolate->factory()->true_value()));
147 __ RecordComment("dead code, just testing immediate operands");
148 __ iilf(r0, Operand(-1));
149 __ iilf(r0, Operand(0xFF000000));
150 __ iilf(r0, Operand(0xF0F0F0F0));
151 __ iilf(r0, Operand(0xFFF0FFFF));
152
153 CodeDesc desc;
154 assm.GetCode(&desc);
155 Handle<Code> code = isolate->factory()->NewCode(
156 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
157#ifdef DEBUG
158 code->Print();
159#endif
160 F1 f = FUNCTION_CAST<F1>(code->entry());
161 intptr_t res = reinterpret_cast<intptr_t>(
162 CALL_GENERATED_CODE(isolate, f, 10, 0, 0, 0, 0));
163 ::printf("f() = %" V8PRIxPTR "\n", res);
164 CHECK_EQ(3628800, static_cast<int>(res));
165}
166
167TEST(3) {
168 CcTest::InitializeVM();
169 Isolate* isolate = CcTest::i_isolate();
170 HandleScope scope(isolate);
171
172 Assembler assm(isolate, NULL, 0);
173
174 __ ar(r14, r13);
175 __ sr(r14, r13);
176 __ mr_z(r14, r13);
177 __ dr(r14, r13);
178 __ or_z(r14, r13);
179 __ nr(r14, r13);
180 __ xr(r14, r13);
181
182 __ agr(r14, r13);
183 __ sgr(r14, r13);
184 __ ogr(r14, r13);
185 __ ngr(r14, r13);
186 __ xgr(r14, r13);
187
188 __ ahi(r13, Operand(123));
189 __ aghi(r13, Operand(123));
190 __ stm(r1, r2, MemOperand(r3, r0, 123));
191 __ slag(r1, r2, Operand(123));
192 __ lay(r1, MemOperand(r2, r3, -123));
193 __ a(r13, MemOperand(r1, r2, 123));
194 __ ay(r13, MemOperand(r1, r2, 123));
195 __ brc(Condition(14), Operand(123));
196 __ brc(Condition(14), Operand(-123));
197 __ brcl(Condition(14), Operand(123), false);
198 __ brcl(Condition(14), Operand(-123), false);
199 __ iilf(r13, Operand(123456789));
200 __ iihf(r13, Operand(-123456789));
201 __ mvc(MemOperand(r0, 123), MemOperand(r4, 567), 89);
202 __ sll(r13, Operand(10));
203
204 v8::internal::byte* bufPos = assm.buffer_pos();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100205 ::printf("buffer position = %p", static_cast<void*>(bufPos));
Ben Murdochda12d292016-06-02 14:46:10 +0100206 ::fflush(stdout);
207 // OS::DebugBreak();
208
209 CodeDesc desc;
210 assm.GetCode(&desc);
211 Handle<Code> code = isolate->factory()->NewCode(
212 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
213#ifdef DEBUG
214 code->Print();
215#endif
216 USE(code);
217 ::exit(0);
218}
219
220#if 0
221TEST(4) {
222 CcTest::InitializeVM();
223 Isolate* isolate = CcTest::i_isolate();
224 HandleScope scope(isolate);
225
226 Assembler assm(isolate, NULL, 0);
227 Label L2, L3, L4;
228
229 __ chi(r2, Operand(10));
230 __ ble(&L2);
231 __ lr(r2, r4);
232 __ ar(r2, r3);
233 __ b(&L3);
234
235 __ bind(&L2);
236 __ chi(r2, Operand(5));
237 __ bgt(&L4);
238
239 __ lhi(r2, Operand::Zero());
240 __ b(&L3);
241
242 __ bind(&L4);
243 __ lr(r2, r3);
244 __ sr(r2, r4);
245
246 __ bind(&L3);
247 __ lgfr(r2, r3);
248 __ b(r14);
249
250 CodeDesc desc;
251 assm.GetCode(&desc);
252 Handle<Code> code = isolate->factory()->NewCode(
253 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
254#ifdef DEBUG
255 code->Print();
256#endif
257 F2 f = FUNCTION_CAST<F2>(code->entry());
258 intptr_t res = reinterpret_cast<intptr_t>(
259 CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
260 ::printf("f() = %" V8PRIdPTR "\n", res);
261 CHECK_EQ(4, static_cast<int>(res));
262}
263
264
265// Test ExtractBitRange
266TEST(5) {
267 CcTest::InitializeVM();
268 Isolate* isolate = CcTest::i_isolate();
269 HandleScope scope(isolate);
270
271 MacroAssembler assm(isolate, NULL, 0);
272
273 __ mov(r2, Operand(0x12345678));
274 __ ExtractBitRange(r3, r2, 3, 2);
275 __ lgfr(r2, r3);
276 __ b(r14);
277
278 CodeDesc desc;
279 assm.GetCode(&desc);
280 Handle<Code> code = isolate->factory()->NewCode(
281 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
282#ifdef DEBUG
283 code->Print();
284#endif
285 F2 f = FUNCTION_CAST<F2>(code->entry());
286 intptr_t res =
287 reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
288 ::printf("f() = %" V8PRIdPTR "\n", res);
289 CHECK_EQ(2, static_cast<int>(res));
290}
291
292
293// Test JumpIfSmi
294TEST(6) {
295 CcTest::InitializeVM();
296 Isolate* isolate = CcTest::i_isolate();
297 HandleScope scope(isolate);
298
299 MacroAssembler assm(isolate, NULL, 0);
300
301 Label yes;
302
303 __ mov(r2, Operand(0x12345678));
304 __ JumpIfSmi(r2, &yes);
305 __ beq(&yes);
306 __ Load(r2, Operand::Zero());
307 __ b(r14);
308 __ bind(&yes);
309 __ Load(r2, Operand(1));
310 __ b(r14);
311
312 CodeDesc desc;
313 assm.GetCode(&desc);
314 Handle<Code> code = isolate->factory()->NewCode(
315 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
316#ifdef DEBUG
317 code->Print();
318#endif
319 F2 f = FUNCTION_CAST<F2>(code->entry());
320 intptr_t res =
321 reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
322 ::printf("f() = %" V8PRIdPTR "\n", res);
323 CHECK_EQ(1, static_cast<int>(res));
324}
325
326
327// Test fix<->floating point conversion.
328TEST(7) {
329 CcTest::InitializeVM();
330 Isolate* isolate = CcTest::i_isolate();
331 HandleScope scope(isolate);
332
333 MacroAssembler assm(isolate, NULL, 0);
334
335 Label yes;
336
337 __ mov(r3, Operand(0x1234));
338 __ cdfbr(d1, r3);
339 __ ldr(d2, d1);
340 __ adbr(d1, d2);
341 __ cfdbr(Condition(0), r2, d1);
342 __ b(r14);
343
344 CodeDesc desc;
345 assm.GetCode(&desc);
346 Handle<Code> code = isolate->factory()->NewCode(
347 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
348#ifdef DEBUG
349 code->Print();
350#endif
351 F2 f = FUNCTION_CAST<F2>(code->entry());
352 intptr_t res =
353 reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 3, 4, 3, 0, 0));
354 ::printf("f() = %" V8PRIdPTR "\n", res);
355 CHECK_EQ(0x2468, static_cast<int>(res));
356}
357
358
359// Test DSGR
360TEST(8) {
361 CcTest::InitializeVM();
362 Isolate* isolate = CcTest::i_isolate();
363 HandleScope scope(isolate);
364
365 MacroAssembler assm(isolate, NULL, 0);
366
367 // Zero upper bits of r3/r4
368 __ llihf(r3, Operand::Zero());
369 __ llihf(r4, Operand::Zero());
370 __ mov(r3, Operand(0x0002));
371 __ mov(r4, Operand(0x0002));
372 __ dsgr(r2, r4);
373 __ b(r14);
374
375 CodeDesc desc;
376 assm.GetCode(&desc);
377 Handle<Code> code = isolate->factory()->NewCode(
378 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
379#ifdef DEBUG
380 code->Print();
381#endif
382 F1 f = FUNCTION_CAST<F1>(code->entry());
383 intptr_t res =
384 reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 100, 0,
385 0, 0, 0));
386 ::printf("f() = %" V8PRIdPTR "\n", res);
387 CHECK_EQ(0, static_cast<int>(res));
388}
389
390
391// Test LZDR
392TEST(9) {
393 CcTest::InitializeVM();
394 Isolate* isolate = CcTest::i_isolate();
395 HandleScope scope(isolate);
396
397 MacroAssembler assm(isolate, NULL, 0);
398
399 __ lzdr(d4);
400 __ b(r14);
401
402 CodeDesc desc;
403 assm.GetCode(&desc);
404 Handle<Code> code = isolate->factory()->NewCode(
405 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
406#ifdef DEBUG
407 code->Print();
408#endif
409 F1 f = FUNCTION_CAST<F1>(code->entry());
410 intptr_t res =
411 reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
412 ::printf("f() = %" V8PRIdPTR "\n", res);
413}
414#endif
415
416#undef __