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