• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
37 using namespace v8::internal;
38 
39 // Define these function prototypes to match JSEntryFunction in execution.cc.
40 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
41 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
42 typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
43 typedef 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
48 TEST(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
76 TEST(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 
115 TEST(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 
167 TEST(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();
205   ::printf("buffer position = %p", static_cast<void*>(bufPos));
206   ::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
221 TEST(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
266 TEST(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
294 TEST(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.
328 TEST(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
360 TEST(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
392 TEST(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 __
417