1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 2 // All Rights Reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions 6 // are met: 7 // 8 // - Redistributions of source code must retain the above copyright notice, 9 // this list of conditions and the following disclaimer. 10 // 11 // - Redistribution in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the 14 // distribution. 15 // 16 // - Neither the name of Sun Microsystems or the names of contributors may 17 // be used to endorse or promote products derived from this software without 18 // specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 // OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 // The original source code covered by the above license above has been 34 // modified significantly by Google Inc. 35 // Copyright 2014 the V8 project authors. All rights reserved. 36 37 #include "src/s390/assembler-s390.h" 38 39 #if V8_TARGET_ARCH_S390 40 41 #if V8_HOST_ARCH_S390 42 #include <elf.h> // Required for auxv checks for STFLE support 43 #endif 44 45 #include "src/base/bits.h" 46 #include "src/base/cpu.h" 47 #include "src/s390/assembler-s390-inl.h" 48 49 #include "src/macro-assembler.h" 50 51 namespace v8 { 52 namespace internal { 53 54 // Get the CPU features enabled by the build. 55 static unsigned CpuFeaturesImpliedByCompiler() { 56 unsigned answer = 0; 57 return answer; 58 } 59 60 // Check whether Store Facility STFLE instruction is available on the platform. 61 // Instruction returns a bit vector of the enabled hardware facilities. 62 static bool supportsSTFLE() { 63 #if V8_HOST_ARCH_S390 64 static bool read_tried = false; 65 static uint32_t auxv_hwcap = 0; 66 67 if (!read_tried) { 68 // Open the AUXV (auxilliary vector) psuedo-file 69 int fd = open("/proc/self/auxv", O_RDONLY); 70 71 read_tried = true; 72 if (fd != -1) { 73 #if V8_TARGET_ARCH_S390X 74 static Elf64_auxv_t buffer[16]; 75 Elf64_auxv_t* auxv_element; 76 #else 77 static Elf32_auxv_t buffer[16]; 78 Elf32_auxv_t* auxv_element; 79 #endif 80 int bytes_read = 0; 81 while (bytes_read >= 0) { 82 // Read a chunk of the AUXV 83 bytes_read = read(fd, buffer, sizeof(buffer)); 84 // Locate and read the platform field of AUXV if it is in the chunk 85 for (auxv_element = buffer; 86 auxv_element + sizeof(auxv_element) <= buffer + bytes_read && 87 auxv_element->a_type != AT_NULL; 88 auxv_element++) { 89 // We are looking for HWCAP entry in AUXV to search for STFLE support 90 if (auxv_element->a_type == AT_HWCAP) { 91 /* Note: Both auxv_hwcap and buffer are static */ 92 auxv_hwcap = auxv_element->a_un.a_val; 93 goto done_reading; 94 } 95 } 96 } 97 done_reading: 98 close(fd); 99 } 100 } 101 102 // Did not find result 103 if (0 == auxv_hwcap) { 104 return false; 105 } 106 107 // HWCAP_S390_STFLE is defined to be 4 in include/asm/elf.h. Currently 108 // hardcoded in case that include file does not exist. 109 const uint32_t HWCAP_S390_STFLE = 4; 110 return (auxv_hwcap & HWCAP_S390_STFLE); 111 #else 112 // STFLE is not available on non-s390 hosts 113 return false; 114 #endif 115 } 116 117 void CpuFeatures::ProbeImpl(bool cross_compile) { 118 supported_ |= CpuFeaturesImpliedByCompiler(); 119 icache_line_size_ = 256; 120 121 // Only use statically determined features for cross compile (snapshot). 122 if (cross_compile) return; 123 124 #ifdef DEBUG 125 initialized_ = true; 126 #endif 127 128 static bool performSTFLE = supportsSTFLE(); 129 130 // Need to define host, as we are generating inlined S390 assembly to test 131 // for facilities. 132 #if V8_HOST_ARCH_S390 133 if (performSTFLE) { 134 // STFLE D(B) requires: 135 // GPR0 to specify # of double words to update minus 1. 136 // i.e. GPR0 = 0 for 1 doubleword 137 // D(B) to specify to memory location to store the facilities bits 138 // The facilities we are checking for are: 139 // Bit 45 - Distinct Operands for instructions like ARK, SRK, etc. 140 // As such, we require only 1 double word 141 int64_t facilities[3] = {0L}; 142 // LHI sets up GPR0 143 // STFLE is specified as .insn, as opcode is not recognized. 144 // We register the instructions kill r0 (LHI) and the CC (STFLE). 145 asm volatile( 146 "lhi 0,2\n" 147 ".insn s,0xb2b00000,%0\n" 148 : "=Q"(facilities) 149 : 150 : "cc", "r0"); 151 152 uint64_t one = static_cast<uint64_t>(1); 153 // Test for Distinct Operands Facility - Bit 45 154 if (facilities[0] & (one << (63 - 45))) { 155 supported_ |= (1u << DISTINCT_OPS); 156 } 157 // Test for General Instruction Extension Facility - Bit 34 158 if (facilities[0] & (one << (63 - 34))) { 159 supported_ |= (1u << GENERAL_INSTR_EXT); 160 } 161 // Test for Floating Point Extension Facility - Bit 37 162 if (facilities[0] & (one << (63 - 37))) { 163 supported_ |= (1u << FLOATING_POINT_EXT); 164 } 165 // Test for Vector Facility - Bit 129 166 if (facilities[2] & (one << (63 - (129 - 128)))) { 167 supported_ |= (1u << VECTOR_FACILITY); 168 } 169 // Test for Miscellaneous Instruction Extension Facility - Bit 58 170 if (facilities[0] & (1lu << (63 - 58))) { 171 supported_ |= (1u << MISC_INSTR_EXT2); 172 } 173 } 174 #else 175 // All distinct ops instructions can be simulated 176 supported_ |= (1u << DISTINCT_OPS); 177 // RISBG can be simulated 178 supported_ |= (1u << GENERAL_INSTR_EXT); 179 supported_ |= (1u << FLOATING_POINT_EXT); 180 supported_ |= (1u << MISC_INSTR_EXT2); 181 USE(performSTFLE); // To avoid assert 182 supported_ |= (1u << VECTOR_FACILITY); 183 #endif 184 supported_ |= (1u << FPU); 185 } 186 187 void CpuFeatures::PrintTarget() { 188 const char* s390_arch = NULL; 189 190 #if V8_TARGET_ARCH_S390X 191 s390_arch = "s390x"; 192 #else 193 s390_arch = "s390"; 194 #endif 195 196 printf("target %s\n", s390_arch); 197 } 198 199 void CpuFeatures::PrintFeatures() { 200 printf("FPU=%d\n", CpuFeatures::IsSupported(FPU)); 201 printf("FPU_EXT=%d\n", CpuFeatures::IsSupported(FLOATING_POINT_EXT)); 202 printf("GENERAL_INSTR=%d\n", CpuFeatures::IsSupported(GENERAL_INSTR_EXT)); 203 printf("DISTINCT_OPS=%d\n", CpuFeatures::IsSupported(DISTINCT_OPS)); 204 printf("VECTOR_FACILITY=%d\n", CpuFeatures::IsSupported(VECTOR_FACILITY)); 205 printf("MISC_INSTR_EXT2=%d\n", CpuFeatures::IsSupported(MISC_INSTR_EXT2)); 206 } 207 208 Register ToRegister(int num) { 209 DCHECK(num >= 0 && num < kNumRegisters); 210 const Register kRegisters[] = {r0, r1, r2, r3, r4, r5, r6, r7, 211 r8, r9, r10, fp, ip, r13, r14, sp}; 212 return kRegisters[num]; 213 } 214 215 // ----------------------------------------------------------------------------- 216 // Implementation of RelocInfo 217 218 const int RelocInfo::kApplyMask = 219 RelocInfo::kCodeTargetMask | 1 << RelocInfo::INTERNAL_REFERENCE; 220 221 bool RelocInfo::IsCodedSpecially() { 222 // The deserializer needs to know whether a pointer is specially 223 // coded. Being specially coded on S390 means that it is an iihf/iilf 224 // instruction sequence, and that is always the case inside code 225 // objects. 226 return true; 227 } 228 229 bool RelocInfo::IsInConstantPool() { return false; } 230 231 Address RelocInfo::wasm_memory_reference() { 232 DCHECK(IsWasmMemoryReference(rmode_)); 233 return Assembler::target_address_at(pc_, host_); 234 } 235 236 uint32_t RelocInfo::wasm_memory_size_reference() { 237 DCHECK(IsWasmMemorySizeReference(rmode_)); 238 return static_cast<uint32_t>( 239 reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_))); 240 } 241 242 Address RelocInfo::wasm_global_reference() { 243 DCHECK(IsWasmGlobalReference(rmode_)); 244 return Assembler::target_address_at(pc_, host_); 245 } 246 247 uint32_t RelocInfo::wasm_function_table_size_reference() { 248 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); 249 return static_cast<uint32_t>( 250 reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_))); 251 } 252 253 void RelocInfo::unchecked_update_wasm_memory_reference( 254 Address address, ICacheFlushMode flush_mode) { 255 Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); 256 } 257 258 void RelocInfo::unchecked_update_wasm_size(uint32_t size, 259 ICacheFlushMode flush_mode) { 260 Assembler::set_target_address_at(isolate_, pc_, host_, 261 reinterpret_cast<Address>(size), flush_mode); 262 } 263 264 // ----------------------------------------------------------------------------- 265 // Implementation of Operand and MemOperand 266 // See assembler-s390-inl.h for inlined constructors 267 268 Operand::Operand(Handle<Object> handle) { 269 AllowDeferredHandleDereference using_raw_address; 270 rm_ = no_reg; 271 // Verify all Objects referred by code are NOT in new space. 272 Object* obj = *handle; 273 if (obj->IsHeapObject()) { 274 imm_ = reinterpret_cast<intptr_t>(handle.location()); 275 rmode_ = RelocInfo::EMBEDDED_OBJECT; 276 } else { 277 // no relocation needed 278 imm_ = reinterpret_cast<intptr_t>(obj); 279 rmode_ = kRelocInfo_NONEPTR; 280 } 281 } 282 283 MemOperand::MemOperand(Register rn, int32_t offset) { 284 baseRegister = rn; 285 indexRegister = r0; 286 offset_ = offset; 287 } 288 289 MemOperand::MemOperand(Register rx, Register rb, int32_t offset) { 290 baseRegister = rb; 291 indexRegister = rx; 292 offset_ = offset; 293 } 294 295 // ----------------------------------------------------------------------------- 296 // Specific instructions, constants, and masks. 297 298 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 299 : AssemblerBase(isolate, buffer, buffer_size), 300 recorded_ast_id_(TypeFeedbackId::None()), 301 code_targets_(100) { 302 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 303 304 last_bound_pos_ = 0; 305 ClearRecordedAstId(); 306 relocations_.reserve(128); 307 } 308 309 void Assembler::GetCode(CodeDesc* desc) { 310 EmitRelocations(); 311 312 // Set up code descriptor. 313 desc->buffer = buffer_; 314 desc->buffer_size = buffer_size_; 315 desc->instr_size = pc_offset(); 316 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 317 desc->origin = this; 318 desc->unwinding_info_size = 0; 319 desc->unwinding_info = nullptr; 320 } 321 322 void Assembler::Align(int m) { 323 DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m)); 324 while ((pc_offset() & (m - 1)) != 0) { 325 nop(0); 326 } 327 } 328 329 void Assembler::CodeTargetAlign() { Align(8); } 330 331 Condition Assembler::GetCondition(Instr instr) { 332 switch (instr & kCondMask) { 333 case BT: 334 return eq; 335 case BF: 336 return ne; 337 default: 338 UNIMPLEMENTED(); 339 } 340 return al; 341 } 342 343 #if V8_TARGET_ARCH_S390X 344 // This code assumes a FIXED_SEQUENCE for 64bit loads (iihf/iilf) 345 bool Assembler::Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2) { 346 // Check the instructions are the iihf/iilf load into ip 347 return (((instr1 >> 32) == 0xC0C8) && ((instr2 >> 32) == 0xC0C9)); 348 } 349 #else 350 // This code assumes a FIXED_SEQUENCE for 32bit loads (iilf) 351 bool Assembler::Is32BitLoadIntoIP(SixByteInstr instr) { 352 // Check the instruction is an iilf load into ip/r12. 353 return ((instr >> 32) == 0xC0C9); 354 } 355 #endif 356 357 // Labels refer to positions in the (to be) generated code. 358 // There are bound, linked, and unused labels. 359 // 360 // Bound labels refer to known positions in the already 361 // generated code. pos() is the position the label refers to. 362 // 363 // Linked labels refer to unknown positions in the code 364 // to be generated; pos() is the position of the last 365 // instruction using the label. 366 367 // The link chain is terminated by a negative code position (must be aligned) 368 const int kEndOfChain = -4; 369 370 // Returns the target address of the relative instructions, typically 371 // of the form: pos + imm (where immediate is in # of halfwords for 372 // BR* and LARL). 373 int Assembler::target_at(int pos) { 374 SixByteInstr instr = instr_at(pos); 375 // check which type of branch this is 16 or 26 bit offset 376 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos); 377 378 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) { 379 int16_t imm16 = SIGN_EXT_IMM16((instr & kImm16Mask)); 380 imm16 <<= 1; // BRC immediate is in # of halfwords 381 if (imm16 == 0) return kEndOfChain; 382 return pos + imm16; 383 } else if (LLILF == opcode || BRCL == opcode || LARL == opcode || 384 BRASL == opcode) { 385 int32_t imm32 = 386 static_cast<int32_t>(instr & (static_cast<uint64_t>(0xffffffff))); 387 if (LLILF != opcode) 388 imm32 <<= 1; // BR* + LARL treat immediate in # of halfwords 389 if (imm32 == 0) return kEndOfChain; 390 return pos + imm32; 391 } 392 393 // Unknown condition 394 DCHECK(false); 395 return -1; 396 } 397 398 // Update the target address of the current relative instruction. 399 void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) { 400 SixByteInstr instr = instr_at(pos); 401 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos); 402 403 if (is_branch != nullptr) { 404 *is_branch = (opcode == BRC || opcode == BRCT || opcode == BRCTG || 405 opcode == BRCL || opcode == BRASL); 406 } 407 408 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) { 409 int16_t imm16 = target_pos - pos; 410 instr &= (~0xffff); 411 DCHECK(is_int16(imm16)); 412 instr_at_put<FourByteInstr>(pos, instr | (imm16 >> 1)); 413 return; 414 } else if (BRCL == opcode || LARL == opcode || BRASL == opcode) { 415 // Immediate is in # of halfwords 416 int32_t imm32 = target_pos - pos; 417 instr &= (~static_cast<uint64_t>(0xffffffff)); 418 instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1)); 419 return; 420 } else if (LLILF == opcode) { 421 DCHECK(target_pos == kEndOfChain || target_pos >= 0); 422 // Emitted label constant, not part of a branch. 423 // Make label relative to Code* of generated Code object. 424 int32_t imm32 = target_pos + (Code::kHeaderSize - kHeapObjectTag); 425 instr &= (~static_cast<uint64_t>(0xffffffff)); 426 instr_at_put<SixByteInstr>(pos, instr | imm32); 427 return; 428 } 429 DCHECK(false); 430 } 431 432 // Returns the maximum number of bits given instruction can address. 433 int Assembler::max_reach_from(int pos) { 434 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos); 435 436 // Check which type of instr. In theory, we can return 437 // the values below + 1, given offset is # of halfwords 438 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) { 439 return 16; 440 } else if (LLILF == opcode || BRCL == opcode || LARL == opcode || 441 BRASL == opcode) { 442 return 31; // Using 31 as workaround instead of 32 as 443 // is_intn(x,32) doesn't work on 32-bit platforms. 444 // llilf: Emitted label constant, not part of 445 // a branch (regexp PushBacktrack). 446 } 447 DCHECK(false); 448 return 16; 449 } 450 451 void Assembler::bind_to(Label* L, int pos) { 452 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position 453 bool is_branch = false; 454 while (L->is_linked()) { 455 int fixup_pos = L->pos(); 456 #ifdef DEBUG 457 int32_t offset = pos - fixup_pos; 458 int maxReach = max_reach_from(fixup_pos); 459 #endif 460 next(L); // call next before overwriting link with target at fixup_pos 461 DCHECK(is_intn(offset, maxReach)); 462 target_at_put(fixup_pos, pos, &is_branch); 463 } 464 L->bind_to(pos); 465 466 // Keep track of the last bound label so we don't eliminate any instructions 467 // before a bound label. 468 if (pos > last_bound_pos_) last_bound_pos_ = pos; 469 } 470 471 void Assembler::bind(Label* L) { 472 DCHECK(!L->is_bound()); // label can only be bound once 473 bind_to(L, pc_offset()); 474 } 475 476 void Assembler::next(Label* L) { 477 DCHECK(L->is_linked()); 478 int link = target_at(L->pos()); 479 if (link == kEndOfChain) { 480 L->Unuse(); 481 } else { 482 DCHECK(link >= 0); 483 L->link_to(link); 484 } 485 } 486 487 bool Assembler::is_near(Label* L, Condition cond) { 488 DCHECK(L->is_bound()); 489 if (L->is_bound() == false) return false; 490 491 int maxReach = ((cond == al) ? 26 : 16); 492 int offset = L->pos() - pc_offset(); 493 494 return is_intn(offset, maxReach); 495 } 496 497 int Assembler::link(Label* L) { 498 int position; 499 if (L->is_bound()) { 500 position = L->pos(); 501 } else { 502 if (L->is_linked()) { 503 position = L->pos(); // L's link 504 } else { 505 // was: target_pos = kEndOfChain; 506 // However, using self to mark the first reference 507 // should avoid most instances of branch offset overflow. See 508 // target_at() for where this is converted back to kEndOfChain. 509 position = pc_offset(); 510 } 511 L->link_to(pc_offset()); 512 } 513 514 return position; 515 } 516 517 void Assembler::load_label_offset(Register r1, Label* L) { 518 int target_pos; 519 int constant; 520 if (L->is_bound()) { 521 target_pos = L->pos(); 522 constant = target_pos + (Code::kHeaderSize - kHeapObjectTag); 523 } else { 524 if (L->is_linked()) { 525 target_pos = L->pos(); // L's link 526 } else { 527 // was: target_pos = kEndOfChain; 528 // However, using branch to self to mark the first reference 529 // should avoid most instances of branch offset overflow. See 530 // target_at() for where this is converted back to kEndOfChain. 531 target_pos = pc_offset(); 532 } 533 L->link_to(pc_offset()); 534 535 constant = target_pos - pc_offset(); 536 } 537 llilf(r1, Operand(constant)); 538 } 539 540 // Pseudo op - branch on condition 541 void Assembler::branchOnCond(Condition c, int branch_offset, bool is_bound) { 542 int offset_in_halfwords = branch_offset / 2; 543 if (is_bound && is_int16(offset_in_halfwords)) { 544 brc(c, Operand(offset_in_halfwords)); // short jump 545 } else { 546 brcl(c, Operand(offset_in_halfwords)); // long jump 547 } 548 } 549 550 // 32-bit Store Multiple - short displacement (12-bits unsigned) 551 void Assembler::stm(Register r1, Register r2, const MemOperand& src) { 552 rs_form(STM, r1, r2, src.rb(), src.offset()); 553 } 554 555 // 32-bit Store Multiple - long displacement (20-bits signed) 556 void Assembler::stmy(Register r1, Register r2, const MemOperand& src) { 557 rsy_form(STMY, r1, r2, src.rb(), src.offset()); 558 } 559 560 // 64-bit Store Multiple - long displacement (20-bits signed) 561 void Assembler::stmg(Register r1, Register r2, const MemOperand& src) { 562 rsy_form(STMG, r1, r2, src.rb(), src.offset()); 563 } 564 565 // Exception-generating instructions and debugging support. 566 // Stops with a non-negative code less than kNumOfWatchedStops support 567 // enabling/disabling and a counter feature. See simulator-s390.h . 568 void Assembler::stop(const char* msg, Condition cond, int32_t code, 569 CRegister cr) { 570 if (cond != al) { 571 Label skip; 572 b(NegateCondition(cond), &skip, Label::kNear); 573 bkpt(0); 574 bind(&skip); 575 } else { 576 bkpt(0); 577 } 578 } 579 580 void Assembler::bkpt(uint32_t imm16) { 581 // GDB software breakpoint instruction 582 emit2bytes(0x0001); 583 } 584 585 // Pseudo instructions. 586 void Assembler::nop(int type) { 587 switch (type) { 588 case 0: 589 lr(r0, r0); 590 break; 591 case DEBUG_BREAK_NOP: 592 // TODO(john.yan): Use a better NOP break 593 oill(r3, Operand::Zero()); 594 break; 595 default: 596 UNIMPLEMENTED(); 597 } 598 } 599 600 601 602 // RI1 format: <insn> R1,I2 603 // +--------+----+----+------------------+ 604 // | OpCode | R1 |OpCd| I2 | 605 // +--------+----+----+------------------+ 606 // 0 8 12 16 31 607 #define RI1_FORM_EMIT(name, op) \ 608 void Assembler::name(Register r, const Operand& i2) { ri_form(op, r, i2); } 609 610 void Assembler::ri_form(Opcode op, Register r1, const Operand& i2) { 611 DCHECK(is_uint12(op)); 612 DCHECK(is_uint16(i2.imm_) || is_int16(i2.imm_)); 613 emit4bytes((op & 0xFF0) * B20 | r1.code() * B20 | (op & 0xF) * B16 | 614 (i2.imm_ & 0xFFFF)); 615 } 616 617 // RI2 format: <insn> M1,I2 618 // +--------+----+----+------------------+ 619 // | OpCode | M1 |OpCd| I2 | 620 // +--------+----+----+------------------+ 621 // 0 8 12 16 31 622 #define RI2_FORM_EMIT(name, op) \ 623 void Assembler::name(Condition m, const Operand& i2) { ri_form(op, m, i2); } 624 625 void Assembler::ri_form(Opcode op, Condition m1, const Operand& i2) { 626 DCHECK(is_uint12(op)); 627 DCHECK(is_uint4(m1)); 628 DCHECK(op == BRC ? is_int16(i2.imm_) : is_uint16(i2.imm_)); 629 emit4bytes((op & 0xFF0) * B20 | m1 * B20 | (op & 0xF) * B16 | 630 (i2.imm_ & 0xFFFF)); 631 } 632 633 // RIE-f format: <insn> R1,R2,I3,I4,I5 634 // +--------+----+----+------------------+--------+--------+ 635 // | OpCode | R1 | R2 | I3 | I4 | I5 | OpCode | 636 // +--------+----+----+------------------+--------+--------+ 637 // 0 8 12 16 24 32 40 47 638 void Assembler::rie_f_form(Opcode op, Register r1, Register r2, 639 const Operand& i3, const Operand& i4, 640 const Operand& i5) { 641 DCHECK(is_uint16(op)); 642 DCHECK(is_uint8(i3.imm_)); 643 DCHECK(is_uint8(i4.imm_)); 644 DCHECK(is_uint8(i5.imm_)); 645 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 646 (static_cast<uint64_t>(r1.code())) * B36 | 647 (static_cast<uint64_t>(r2.code())) * B32 | 648 (static_cast<uint64_t>(i3.imm_)) * B24 | 649 (static_cast<uint64_t>(i4.imm_)) * B16 | 650 (static_cast<uint64_t>(i5.imm_)) * B8 | 651 (static_cast<uint64_t>(op & 0x00FF)); 652 emit6bytes(code); 653 } 654 655 // RIE format: <insn> R1,R3,I2 656 // +--------+----+----+------------------+--------+--------+ 657 // | OpCode | R1 | R3 | I2 |////////| OpCode | 658 // +--------+----+----+------------------+--------+--------+ 659 // 0 8 12 16 32 40 47 660 #define RIE_FORM_EMIT(name, op) \ 661 void Assembler::name(Register r1, Register r3, const Operand& i2) { \ 662 rie_form(op, r1, r3, i2); \ 663 } 664 665 void Assembler::rie_form(Opcode op, Register r1, Register r3, 666 const Operand& i2) { 667 DCHECK(is_uint16(op)); 668 DCHECK(is_int16(i2.imm_)); 669 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 670 (static_cast<uint64_t>(r1.code())) * B36 | 671 (static_cast<uint64_t>(r3.code())) * B32 | 672 (static_cast<uint64_t>(i2.imm_ & 0xFFFF)) * B16 | 673 (static_cast<uint64_t>(op & 0x00FF)); 674 emit6bytes(code); 675 } 676 677 // RS1 format: <insn> R1,R3,D2(B2) 678 // +--------+----+----+----+-------------+ 679 // | OpCode | R1 | R3 | B2 | D2 | 680 // +--------+----+----+----+-------------+ 681 // 0 8 12 16 20 31 682 #define RS1_FORM_EMIT(name, op) \ 683 void Assembler::name(Register r1, Register r3, Register b2, Disp d2) { \ 684 rs_form(op, r1, r3, b2, d2); \ 685 } \ 686 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \ 687 name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 688 } 689 690 void Assembler::rs_form(Opcode op, Register r1, Register r3, Register b2, 691 const Disp d2) { 692 DCHECK(is_uint12(d2)); 693 emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | b2.code() * B12 | 694 d2); 695 } 696 697 // RS2 format: <insn> R1,M3,D2(B2) 698 // +--------+----+----+----+-------------+ 699 // | OpCode | R1 | M3 | B2 | D2 | 700 // +--------+----+----+----+-------------+ 701 // 0 8 12 16 20 31 702 #define RS2_FORM_EMIT(name, op) \ 703 void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) { \ 704 rs_form(op, r1, m3, b2, d2); \ 705 } \ 706 void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \ 707 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 708 } 709 710 void Assembler::rs_form(Opcode op, Register r1, Condition m3, Register b2, 711 const Disp d2) { 712 DCHECK(is_uint12(d2)); 713 emit4bytes(op * B24 | r1.code() * B20 | m3 * B16 | b2.code() * B12 | d2); 714 } 715 716 // RSI format: <insn> R1,R3,I2 717 // +--------+----+----+------------------+ 718 // | OpCode | R1 | R3 | RI2 | 719 // +--------+----+----+------------------+ 720 // 0 8 12 16 31 721 #define RSI_FORM_EMIT(name, op) \ 722 void Assembler::name(Register r1, Register r3, const Operand& i2) { \ 723 rsi_form(op, r1, r3, i2); \ 724 } 725 726 void Assembler::rsi_form(Opcode op, Register r1, Register r3, 727 const Operand& i2) { 728 DCHECK(is_uint8(op)); 729 DCHECK(is_uint16(i2.imm_)); 730 emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | (i2.imm_ & 0xFFFF)); 731 } 732 733 // RSL format: <insn> R1,R3,D2(B2) 734 // +--------+----+----+----+-------------+--------+--------+ 735 // | OpCode | L1 | | B2 | D2 | | OpCode | 736 // +--------+----+----+----+-------------+--------+--------+ 737 // 0 8 12 16 20 32 40 47 738 #define RSL_FORM_EMIT(name, op) \ 739 void Assembler::name(Length l1, Register b2, Disp d2) { \ 740 rsl_form(op, l1, b2, d2); \ 741 } 742 743 void Assembler::rsl_form(Opcode op, Length l1, Register b2, Disp d2) { 744 DCHECK(is_uint16(op)); 745 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 746 (static_cast<uint64_t>(l1)) * B36 | 747 (static_cast<uint64_t>(b2.code())) * B28 | 748 (static_cast<uint64_t>(d2)) * B16 | 749 (static_cast<uint64_t>(op & 0x00FF)); 750 emit6bytes(code); 751 } 752 753 // RSY1 format: <insn> R1,R3,D2(B2) 754 // +--------+----+----+----+-------------+--------+--------+ 755 // | OpCode | R1 | R3 | B2 | DL2 | DH2 | OpCode | 756 // +--------+----+----+----+-------------+--------+--------+ 757 // 0 8 12 16 20 32 40 47 758 #define RSY1_FORM_EMIT(name, op) \ 759 void Assembler::name(Register r1, Register r3, Register b2, Disp d2) { \ 760 rsy_form(op, r1, r3, b2, d2); \ 761 } \ 762 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \ 763 name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 764 } 765 766 void Assembler::rsy_form(Opcode op, Register r1, Register r3, Register b2, 767 const Disp d2) { 768 DCHECK(is_int20(d2)); 769 DCHECK(is_uint16(op)); 770 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 771 (static_cast<uint64_t>(r1.code())) * B36 | 772 (static_cast<uint64_t>(r3.code())) * B32 | 773 (static_cast<uint64_t>(b2.code())) * B28 | 774 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 775 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 776 (static_cast<uint64_t>(op & 0x00FF)); 777 emit6bytes(code); 778 } 779 780 // RSY2 format: <insn> R1,M3,D2(B2) 781 // +--------+----+----+----+-------------+--------+--------+ 782 // | OpCode | R1 | M3 | B2 | DL2 | DH2 | OpCode | 783 // +--------+----+----+----+-------------+--------+--------+ 784 // 0 8 12 16 20 32 40 47 785 #define RSY2_FORM_EMIT(name, op) \ 786 void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) { \ 787 rsy_form(op, r1, m3, b2, d2); \ 788 } \ 789 void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \ 790 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 791 } 792 793 void Assembler::rsy_form(Opcode op, Register r1, Condition m3, Register b2, 794 const Disp d2) { 795 DCHECK(is_int20(d2)); 796 DCHECK(is_uint16(op)); 797 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 798 (static_cast<uint64_t>(r1.code())) * B36 | 799 (static_cast<uint64_t>(m3)) * B32 | 800 (static_cast<uint64_t>(b2.code())) * B28 | 801 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 802 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 803 (static_cast<uint64_t>(op & 0x00FF)); 804 emit6bytes(code); 805 } 806 807 // RXE format: <insn> R1,D2(X2,B2) 808 // +--------+----+----+----+-------------+--------+--------+ 809 // | OpCode | R1 | X2 | B2 | D2 |////////| OpCode | 810 // +--------+----+----+----+-------------+--------+--------+ 811 // 0 8 12 16 20 32 40 47 812 #define RXE_FORM_EMIT(name, op) \ 813 void Assembler::name(Register r1, Register x2, Register b2, Disp d2) { \ 814 rxe_form(op, r1, x2, b2, d2); \ 815 } \ 816 void Assembler::name(Register r1, const MemOperand& opnd) { \ 817 name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(), \ 818 opnd.getDisplacement()); \ 819 } 820 821 void Assembler::rxe_form(Opcode op, Register r1, Register x2, Register b2, 822 Disp d2) { 823 DCHECK(is_uint12(d2)); 824 DCHECK(is_uint16(op)); 825 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 826 (static_cast<uint64_t>(r1.code())) * B36 | 827 (static_cast<uint64_t>(x2.code())) * B32 | 828 (static_cast<uint64_t>(b2.code())) * B28 | 829 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 830 (static_cast<uint64_t>(op & 0x00FF)); 831 emit6bytes(code); 832 } 833 834 // RRS format: <insn> R1,R2,M3,D4(B4) 835 // +--------+----+----+----+-------------+----+---+--------+ 836 // | OpCode | R1 | R2 | B4 | D4 | M3 |///| OpCode | 837 // +--------+----+----+----+-------------+----+---+--------+ 838 // 0 8 12 16 20 32 36 40 47 839 #define RRS_FORM_EMIT(name, op) \ 840 void Assembler::name(Register r1, Register r2, Register b4, Disp d4, \ 841 Condition m3) { \ 842 rrs_form(op, r1, r2, b4, d4, m3); \ 843 } \ 844 void Assembler::name(Register r1, Register r2, Condition m3, \ 845 const MemOperand& opnd) { \ 846 name(r1, r2, opnd.getBaseRegister(), opnd.getDisplacement(), m3); \ 847 } 848 849 void Assembler::rrs_form(Opcode op, Register r1, Register r2, Register b4, 850 Disp d4, Condition m3) { 851 DCHECK(is_uint12(d4)); 852 DCHECK(is_uint16(op)); 853 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 854 (static_cast<uint64_t>(r1.code())) * B36 | 855 (static_cast<uint64_t>(r2.code())) * B32 | 856 (static_cast<uint64_t>(b4.code())) * B28 | 857 (static_cast<uint64_t>(d4)) * B16 | 858 (static_cast<uint64_t>(m3)) << 12 | 859 (static_cast<uint64_t>(op & 0x00FF)); 860 emit6bytes(code); 861 } 862 863 // RIS format: <insn> R1,I2,M3,D4(B4) 864 // +--------+----+----+----+-------------+--------+--------+ 865 // | OpCode | R1 | M3 | B4 | D4 | I2 | OpCode | 866 // +--------+----+----+----+-------------+--------+--------+ 867 // 0 8 12 16 20 32 40 47 868 #define RIS_FORM_EMIT(name, op) \ 869 void Assembler::name(Register r1, Condition m3, Register b4, Disp d4, \ 870 const Operand& i2) { \ 871 ris_form(op, r1, m3, b4, d4, i2); \ 872 } \ 873 void Assembler::name(Register r1, const Operand& i2, Condition m3, \ 874 const MemOperand& opnd) { \ 875 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement(), i2); \ 876 } 877 878 void Assembler::ris_form(Opcode op, Register r1, Condition m3, Register b4, 879 Disp d4, const Operand& i2) { 880 DCHECK(is_uint12(d4)); 881 DCHECK(is_uint16(op)); 882 DCHECK(is_uint8(i2.imm_)); 883 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 884 (static_cast<uint64_t>(r1.code())) * B36 | 885 (static_cast<uint64_t>(m3)) * B32 | 886 (static_cast<uint64_t>(b4.code())) * B28 | 887 (static_cast<uint64_t>(d4)) * B16 | 888 (static_cast<uint64_t>(i2.imm_)) << 8 | 889 (static_cast<uint64_t>(op & 0x00FF)); 890 emit6bytes(code); 891 } 892 893 // S format: <insn> D2(B2) 894 // +------------------+----+-------------+ 895 // | OpCode | B2 | D2 | 896 // +------------------+----+-------------+ 897 // 0 16 20 31 898 #define S_FORM_EMIT(name, op) \ 899 void Assembler::name(Register b1, Disp d2) { s_form(op, b1, d2); } \ 900 void Assembler::name(const MemOperand& opnd) { \ 901 name(opnd.getBaseRegister(), opnd.getDisplacement()); \ 902 } 903 904 void Assembler::s_form(Opcode op, Register b1, Disp d2) { 905 DCHECK(is_uint12(d2)); 906 emit4bytes(op << 16 | b1.code() * B12 | d2); 907 } 908 909 // SI format: <insn> D1(B1),I2 910 // +--------+---------+----+-------------+ 911 // | OpCode | I2 | B1 | D1 | 912 // +--------+---------+----+-------------+ 913 // 0 8 16 20 31 914 #define SI_FORM_EMIT(name, op) \ 915 void Assembler::name(const Operand& i2, Register b1, Disp d1) { \ 916 si_form(op, i2, b1, d1); \ 917 } \ 918 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \ 919 name(i2, opnd.getBaseRegister(), opnd.getDisplacement()); \ 920 } 921 922 void Assembler::si_form(Opcode op, const Operand& i2, Register b1, Disp d1) { 923 emit4bytes((op & 0x00FF) << 24 | i2.imm_ * B16 | b1.code() * B12 | d1); 924 } 925 926 // SIY format: <insn> D1(B1),I2 927 // +--------+---------+----+-------------+--------+--------+ 928 // | OpCode | I2 | B1 | DL1 | DH1 | OpCode | 929 // +--------+---------+----+-------------+--------+--------+ 930 // 0 8 16 20 32 36 40 47 931 #define SIY_FORM_EMIT(name, op) \ 932 void Assembler::name(const Operand& i2, Register b1, Disp d1) { \ 933 siy_form(op, i2, b1, d1); \ 934 } \ 935 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \ 936 name(i2, opnd.getBaseRegister(), opnd.getDisplacement()); \ 937 } 938 939 void Assembler::siy_form(Opcode op, const Operand& i2, Register b1, Disp d1) { 940 DCHECK(is_uint20(d1) || is_int20(d1)); 941 DCHECK(is_uint16(op)); 942 DCHECK(is_uint8(i2.imm_)); 943 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 944 (static_cast<uint64_t>(i2.imm_)) * B32 | 945 (static_cast<uint64_t>(b1.code())) * B28 | 946 (static_cast<uint64_t>(d1 & 0x0FFF)) * B16 | 947 (static_cast<uint64_t>(d1 & 0x0FF000)) >> 4 | 948 (static_cast<uint64_t>(op & 0x00FF)); 949 emit6bytes(code); 950 } 951 952 // SIL format: <insn> D1(B1),I2 953 // +------------------+----+-------------+-----------------+ 954 // | OpCode | B1 | D1 | I2 | 955 // +------------------+----+-------------+-----------------+ 956 // 0 16 20 32 47 957 #define SIL_FORM_EMIT(name, op) \ 958 void Assembler::name(Register b1, Disp d1, const Operand& i2) { \ 959 sil_form(op, b1, d1, i2); \ 960 } \ 961 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \ 962 name(opnd.getBaseRegister(), opnd.getDisplacement(), i2); \ 963 } 964 965 void Assembler::sil_form(Opcode op, Register b1, Disp d1, const Operand& i2) { 966 DCHECK(is_uint12(d1)); 967 DCHECK(is_uint16(op)); 968 DCHECK(is_uint16(i2.imm_)); 969 uint64_t code = (static_cast<uint64_t>(op)) * B32 | 970 (static_cast<uint64_t>(b1.code())) * B28 | 971 (static_cast<uint64_t>(d1)) * B16 | 972 (static_cast<uint64_t>(i2.imm_)); 973 emit6bytes(code); 974 } 975 976 // RXF format: <insn> R1,R3,D2(X2,B2) 977 // +--------+----+----+----+-------------+----+---+--------+ 978 // | OpCode | R3 | X2 | B2 | D2 | R1 |///| OpCode | 979 // +--------+----+----+----+-------------+----+---+--------+ 980 // 0 8 12 16 20 32 36 40 47 981 #define RXF_FORM_EMIT(name, op) \ 982 void Assembler::name(Register r1, Register r3, Register b2, Register x2, \ 983 Disp d2) { \ 984 rxf_form(op, r1, r3, b2, x2, d2); \ 985 } \ 986 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \ 987 name(r1, r3, opnd.getBaseRegister(), opnd.getIndexRegister(), \ 988 opnd.getDisplacement()); \ 989 } 990 991 void Assembler::rxf_form(Opcode op, Register r1, Register r3, Register b2, 992 Register x2, Disp d2) { 993 DCHECK(is_uint12(d2)); 994 DCHECK(is_uint16(op)); 995 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 996 (static_cast<uint64_t>(r3.code())) * B36 | 997 (static_cast<uint64_t>(x2.code())) * B32 | 998 (static_cast<uint64_t>(b2.code())) * B28 | 999 (static_cast<uint64_t>(d2)) * B16 | 1000 (static_cast<uint64_t>(r1.code())) * B12 | 1001 (static_cast<uint64_t>(op & 0x00FF)); 1002 emit6bytes(code); 1003 } 1004 1005 // SS1 format: <insn> D1(L,B1),D2(B3) 1006 // +--------+----+----+----+-------------+----+------------+ 1007 // | OpCode | L | B1 | D1 | B2 | D2 | 1008 // +--------+----+----+----+-------------+----+------------+ 1009 // 0 8 12 16 20 32 36 47 1010 #define SS1_FORM_EMIT(name, op) \ 1011 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l) { \ 1012 ss_form(op, l, b1, d1, b2, d2); \ 1013 } \ 1014 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \ 1015 Length length) { \ 1016 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1017 opnd2.getBaseRegister(), opnd2.getDisplacement(), length); \ 1018 } 1019 1020 void Assembler::ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2, 1021 Disp d2) { 1022 DCHECK(is_uint12(d2)); 1023 DCHECK(is_uint12(d1)); 1024 DCHECK(is_uint8(op)); 1025 DCHECK(is_uint8(l)); 1026 uint64_t code = 1027 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l)) * B32 | 1028 (static_cast<uint64_t>(b1.code())) * B28 | 1029 (static_cast<uint64_t>(d1)) * B16 | 1030 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2)); 1031 emit6bytes(code); 1032 } 1033 1034 // SS2 format: <insn> D1(L1,B1), D2(L3,B3) 1035 // +--------+----+----+----+-------------+----+------------+ 1036 // | OpCode | L1 | L2 | B1 | D1 | B2 | D2 | 1037 // +--------+----+----+----+-------------+----+------------+ 1038 // 0 8 12 16 20 32 36 47 1039 #define SS2_FORM_EMIT(name, op) \ 1040 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l1, \ 1041 Length l2) { \ 1042 ss_form(op, l1, l2, b1, d1, b2, d2); \ 1043 } \ 1044 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \ 1045 Length length1, Length length2) { \ 1046 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1047 opnd2.getBaseRegister(), opnd2.getDisplacement(), length1, length2); \ 1048 } 1049 1050 void Assembler::ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1, 1051 Register b2, Disp d2) { 1052 DCHECK(is_uint12(d2)); 1053 DCHECK(is_uint12(d1)); 1054 DCHECK(is_uint8(op)); 1055 DCHECK(is_uint4(l2)); 1056 DCHECK(is_uint4(l1)); 1057 uint64_t code = 1058 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 | 1059 (static_cast<uint64_t>(l2)) * B32 | 1060 (static_cast<uint64_t>(b1.code())) * B28 | 1061 (static_cast<uint64_t>(d1)) * B16 | 1062 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2)); 1063 emit6bytes(code); 1064 } 1065 1066 // SS3 format: <insn> D1(L1,B1), D2(I3,B2) 1067 // +--------+----+----+----+-------------+----+------------+ 1068 // | OpCode | L1 | I3 | B1 | D1 | B2 | D2 | 1069 // +--------+----+----+----+-------------+----+------------+ 1070 // 0 8 12 16 20 32 36 47 1071 #define SS3_FORM_EMIT(name, op) \ 1072 void Assembler::name(const Operand& i3, Register b1, Disp d1, Register b2, \ 1073 Disp d2, Length l1) { \ 1074 ss_form(op, l1, i3, b1, d1, b2, d2); \ 1075 } \ 1076 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \ 1077 Length length) { \ 1078 DCHECK(false); \ 1079 } 1080 void Assembler::ss_form(Opcode op, Length l1, const Operand& i3, Register b1, 1081 Disp d1, Register b2, Disp d2) { 1082 DCHECK(is_uint12(d2)); 1083 DCHECK(is_uint12(d1)); 1084 DCHECK(is_uint8(op)); 1085 DCHECK(is_uint4(l1)); 1086 DCHECK(is_uint4(i3.imm_)); 1087 uint64_t code = 1088 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 | 1089 (static_cast<uint64_t>(i3.imm_)) * B32 | 1090 (static_cast<uint64_t>(b1.code())) * B28 | 1091 (static_cast<uint64_t>(d1)) * B16 | 1092 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2)); 1093 emit6bytes(code); 1094 } 1095 1096 // SS4 format: <insn> D1(R1,B1), D2(R3,B2) 1097 // +--------+----+----+----+-------------+----+------------+ 1098 // | OpCode | R1 | R3 | B1 | D1 | B2 | D2 | 1099 // +--------+----+----+----+-------------+----+------------+ 1100 // 0 8 12 16 20 32 36 47 1101 #define SS4_FORM_EMIT(name, op) \ 1102 void Assembler::name(Register r1, Register r3, Register b1, Disp d1, \ 1103 Register b2, Disp d2) { \ 1104 ss_form(op, r1, r3, b1, d1, b2, d2); \ 1105 } \ 1106 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \ 1107 DCHECK(false); \ 1108 } 1109 void Assembler::ss_form(Opcode op, Register r1, Register r3, Register b1, 1110 Disp d1, Register b2, Disp d2) { 1111 DCHECK(is_uint12(d2)); 1112 DCHECK(is_uint12(d1)); 1113 DCHECK(is_uint8(op)); 1114 uint64_t code = (static_cast<uint64_t>(op)) * B40 | 1115 (static_cast<uint64_t>(r1.code())) * B36 | 1116 (static_cast<uint64_t>(r3.code())) * B32 | 1117 (static_cast<uint64_t>(b1.code())) * B28 | 1118 (static_cast<uint64_t>(d1)) * B16 | 1119 (static_cast<uint64_t>(b2.code())) * B12 | 1120 (static_cast<uint64_t>(d2)); 1121 emit6bytes(code); 1122 } 1123 1124 // SS5 format: <insn> D1(R1,B1), D2(R3,B2) 1125 // +--------+----+----+----+-------------+----+------------+ 1126 // | OpCode | R1 | R3 | B2 | D2 | B4 | D4 | 1127 // +--------+----+----+----+-------------+----+------------+ 1128 // 0 8 12 16 20 32 36 47 1129 #define SS5_FORM_EMIT(name, op) \ 1130 void Assembler::name(Register r1, Register r3, Register b2, Disp d2, \ 1131 Register b4, Disp d4) { \ 1132 ss_form(op, r1, r3, b2, d2, b4, d4); /*SS5 use the same form as SS4*/ \ 1133 } \ 1134 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \ 1135 DCHECK(false); \ 1136 } 1137 1138 #define SS6_FORM_EMIT(name, op) SS1_FORM_EMIT(name, op) 1139 1140 // SSE format: <insn> D1(B1),D2(B2) 1141 // +------------------+----+-------------+----+------------+ 1142 // | OpCode | B1 | D1 | B2 | D2 | 1143 // +------------------+----+-------------+----+------------+ 1144 // 0 8 12 16 20 32 36 47 1145 #define SSE_FORM_EMIT(name, op) \ 1146 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2) { \ 1147 sse_form(op, b1, d1, b2, d2); \ 1148 } \ 1149 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \ 1150 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1151 opnd2.getBaseRegister(), opnd2.getDisplacement()); \ 1152 } 1153 void Assembler::sse_form(Opcode op, Register b1, Disp d1, Register b2, 1154 Disp d2) { 1155 DCHECK(is_uint12(d2)); 1156 DCHECK(is_uint12(d1)); 1157 DCHECK(is_uint16(op)); 1158 uint64_t code = (static_cast<uint64_t>(op)) * B32 | 1159 (static_cast<uint64_t>(b1.code())) * B28 | 1160 (static_cast<uint64_t>(d1)) * B16 | 1161 (static_cast<uint64_t>(b2.code())) * B12 | 1162 (static_cast<uint64_t>(d2)); 1163 emit6bytes(code); 1164 } 1165 1166 // SSF format: <insn> R3, D1(B1),D2(B2),R3 1167 // +--------+----+----+----+-------------+----+------------+ 1168 // | OpCode | R3 |OpCd| B1 | D1 | B2 | D2 | 1169 // +--------+----+----+----+-------------+----+------------+ 1170 // 0 8 12 16 20 32 36 47 1171 #define SSF_FORM_EMIT(name, op) \ 1172 void Assembler::name(Register r3, Register b1, Disp d1, Register b2, \ 1173 Disp d2) { \ 1174 ssf_form(op, r3, b1, d1, b2, d2); \ 1175 } \ 1176 void Assembler::name(Register r3, const MemOperand& opnd1, \ 1177 const MemOperand& opnd2) { \ 1178 name(r3, opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1179 opnd2.getBaseRegister(), opnd2.getDisplacement()); \ 1180 } 1181 1182 void Assembler::ssf_form(Opcode op, Register r3, Register b1, Disp d1, 1183 Register b2, Disp d2) { 1184 DCHECK(is_uint12(d2)); 1185 DCHECK(is_uint12(d1)); 1186 DCHECK(is_uint12(op)); 1187 uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 | 1188 (static_cast<uint64_t>(r3.code())) * B36 | 1189 (static_cast<uint64_t>(op & 0x00F)) * B32 | 1190 (static_cast<uint64_t>(b1.code())) * B28 | 1191 (static_cast<uint64_t>(d1)) * B16 | 1192 (static_cast<uint64_t>(b2.code())) * B12 | 1193 (static_cast<uint64_t>(d2)); 1194 emit6bytes(code); 1195 } 1196 1197 // RRF1 format: <insn> R1,R2,R3 1198 // +------------------+----+----+----+----+ 1199 // | OpCode | R3 | | R1 | R2 | 1200 // +------------------+----+----+----+----+ 1201 // 0 16 20 24 28 31 1202 #define RRF1_FORM_EMIT(name, op) \ 1203 void Assembler::name(Register r1, Register r2, Register r3) { \ 1204 rrf1_form(op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code()); \ 1205 } 1206 1207 void Assembler::rrf1_form(Opcode op, Register r1, Register r2, Register r3) { 1208 uint32_t code = op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code(); 1209 emit4bytes(code); 1210 } 1211 1212 void Assembler::rrf1_form(uint32_t code) { emit4bytes(code); } 1213 1214 // RRF2 format: <insn> R1,R2,M3 1215 // +------------------+----+----+----+----+ 1216 // | OpCode | M3 | | R1 | R2 | 1217 // +------------------+----+----+----+----+ 1218 // 0 16 20 24 28 31 1219 #define RRF2_FORM_EMIT(name, op) \ 1220 void Assembler::name(Condition m3, Register r1, Register r2) { \ 1221 rrf2_form(op << 16 | m3 * B12 | r1.code() * B4 | r2.code()); \ 1222 } 1223 1224 void Assembler::rrf2_form(uint32_t code) { emit4bytes(code); } 1225 1226 // RRF3 format: <insn> R1,R2,R3,M4 1227 // +------------------+----+----+----+----+ 1228 // | OpCode | R3 | M4 | R1 | R2 | 1229 // +------------------+----+----+----+----+ 1230 // 0 16 20 24 28 31 1231 #define RRF3_FORM_EMIT(name, op) \ 1232 void Assembler::name(Register r3, Conition m4, Register r1, Register r2) { \ 1233 rrf3_form(op << 16 | r3.code() * B12 | m4 * B8 | r1.code() * B4 | \ 1234 r2.code()); \ 1235 } 1236 1237 void Assembler::rrf3_form(uint32_t code) { emit4bytes(code); } 1238 1239 // RRF-e format: <insn> R1,M3,R2,M4 1240 // +------------------+----+----+----+----+ 1241 // | OpCode | M3 | M4 | R1 | R2 | 1242 // +------------------+----+----+----+----+ 1243 // 0 16 20 24 28 31 1244 void Assembler::rrfe_form(Opcode op, Condition m3, Condition m4, Register r1, 1245 Register r2) { 1246 uint32_t code = op << 16 | m3 * B12 | m4 * B8 | r1.code() * B4 | r2.code(); 1247 emit4bytes(code); 1248 } 1249 1250 // end of S390 Instruction generation 1251 1252 // start of S390 instruction 1253 SS1_FORM_EMIT(ed, ED) 1254 SS1_FORM_EMIT(mvn, MVN) 1255 SS1_FORM_EMIT(nc, NC) 1256 SI_FORM_EMIT(ni, NI) 1257 RI1_FORM_EMIT(nilh, NILH) 1258 RI1_FORM_EMIT(nill, NILL) 1259 RI1_FORM_EMIT(oill, OILL) 1260 RI1_FORM_EMIT(tmll, TMLL) 1261 SS1_FORM_EMIT(tr, TR) 1262 S_FORM_EMIT(ts, TS) 1263 1264 // ------------------------- 1265 // Load Address Instructions 1266 // ------------------------- 1267 // Load Address Relative Long 1268 void Assembler::larl(Register r1, Label* l) { 1269 larl(r1, Operand(branch_offset(l))); 1270 } 1271 1272 // ----------------- 1273 // Load Instructions 1274 // ----------------- 1275 // Load Halfword Immediate (32) 1276 void Assembler::lhi(Register r, const Operand& imm) { ri_form(LHI, r, imm); } 1277 1278 // Load Halfword Immediate (64) 1279 void Assembler::lghi(Register r, const Operand& imm) { ri_form(LGHI, r, imm); } 1280 1281 // ------------------------- 1282 // Load Logical Instructions 1283 // ------------------------- 1284 // Load On Condition R-R (32) 1285 void Assembler::locr(Condition m3, Register r1, Register r2) { 1286 rrf2_form(LOCR << 16 | m3 * B12 | r1.code() * B4 | r2.code()); 1287 } 1288 1289 // Load On Condition R-R (64) 1290 void Assembler::locgr(Condition m3, Register r1, Register r2) { 1291 rrf2_form(LOCGR << 16 | m3 * B12 | r1.code() * B4 | r2.code()); 1292 } 1293 1294 // Load On Condition R-M (32) 1295 void Assembler::loc(Condition m3, Register r1, const MemOperand& src) { 1296 rsy_form(LOC, r1, m3, src.rb(), src.offset()); 1297 } 1298 1299 // Load On Condition R-M (64) 1300 void Assembler::locg(Condition m3, Register r1, const MemOperand& src) { 1301 rsy_form(LOCG, r1, m3, src.rb(), src.offset()); 1302 } 1303 1304 // ------------------- 1305 // Branch Instructions 1306 // ------------------- 1307 // Branch on Count (64) 1308 // Branch Relative and Save (32) 1309 void Assembler::bras(Register r, const Operand& opnd) { 1310 ri_form(BRAS, r, opnd); 1311 } 1312 1313 // Branch relative on Condition (32) 1314 void Assembler::brc(Condition c, const Operand& opnd) { ri_form(BRC, c, opnd); } 1315 1316 // Branch On Count (32) 1317 void Assembler::brct(Register r1, const Operand& imm) { 1318 // BRCT encodes # of halfwords, so divide by 2. 1319 int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2; 1320 Operand halfwordOp = Operand(numHalfwords); 1321 halfwordOp.setBits(16); 1322 ri_form(BRCT, r1, halfwordOp); 1323 } 1324 1325 // Branch On Count (32) 1326 void Assembler::brctg(Register r1, const Operand& imm) { 1327 // BRCTG encodes # of halfwords, so divide by 2. 1328 int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2; 1329 Operand halfwordOp = Operand(numHalfwords); 1330 halfwordOp.setBits(16); 1331 ri_form(BRCTG, r1, halfwordOp); 1332 } 1333 1334 // -------------------- 1335 // Compare Instructions 1336 // -------------------- 1337 // Compare Halfword Immediate (32) 1338 void Assembler::chi(Register r, const Operand& opnd) { ri_form(CHI, r, opnd); } 1339 1340 // Compare Halfword Immediate (64) 1341 void Assembler::cghi(Register r, const Operand& opnd) { 1342 ri_form(CGHI, r, opnd); 1343 } 1344 1345 // ---------------------------- 1346 // Compare Logical Instructions 1347 // ---------------------------- 1348 // Compare Immediate (Mem - Imm) (8) 1349 void Assembler::cli(const MemOperand& opnd, const Operand& imm) { 1350 si_form(CLI, imm, opnd.rb(), opnd.offset()); 1351 } 1352 1353 // Compare Immediate (Mem - Imm) (8) 1354 void Assembler::cliy(const MemOperand& opnd, const Operand& imm) { 1355 siy_form(CLIY, imm, opnd.rb(), opnd.offset()); 1356 } 1357 1358 // Compare logical - mem to mem operation 1359 void Assembler::clc(const MemOperand& opnd1, const MemOperand& opnd2, 1360 Length length) { 1361 ss_form(CLC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(), 1362 opnd2.getBaseRegister(), opnd2.getDisplacement()); 1363 } 1364 1365 // ---------------------------- 1366 // Test Under Mask Instructions 1367 // ---------------------------- 1368 // Test Under Mask (Mem - Imm) (8) 1369 void Assembler::tm(const MemOperand& opnd, const Operand& imm) { 1370 si_form(TM, imm, opnd.rb(), opnd.offset()); 1371 } 1372 1373 // Test Under Mask (Mem - Imm) (8) 1374 void Assembler::tmy(const MemOperand& opnd, const Operand& imm) { 1375 siy_form(TMY, imm, opnd.rb(), opnd.offset()); 1376 } 1377 1378 // ------------------------------- 1379 // Rotate and Insert Selected Bits 1380 // ------------------------------- 1381 // Rotate-And-Insert-Selected-Bits 1382 void Assembler::risbg(Register dst, Register src, const Operand& startBit, 1383 const Operand& endBit, const Operand& shiftAmt, 1384 bool zeroBits) { 1385 // High tag the top bit of I4/EndBit to zero out any unselected bits 1386 if (zeroBits) 1387 rie_f_form(RISBG, dst, src, startBit, Operand(endBit.imm_ | 0x80), 1388 shiftAmt); 1389 else 1390 rie_f_form(RISBG, dst, src, startBit, endBit, shiftAmt); 1391 } 1392 1393 // Rotate-And-Insert-Selected-Bits 1394 void Assembler::risbgn(Register dst, Register src, const Operand& startBit, 1395 const Operand& endBit, const Operand& shiftAmt, 1396 bool zeroBits) { 1397 // High tag the top bit of I4/EndBit to zero out any unselected bits 1398 if (zeroBits) 1399 rie_f_form(RISBGN, dst, src, startBit, Operand(endBit.imm_ | 0x80), 1400 shiftAmt); 1401 else 1402 rie_f_form(RISBGN, dst, src, startBit, endBit, shiftAmt); 1403 } 1404 1405 // --------------------------- 1406 // Move Character Instructions 1407 // --------------------------- 1408 // Move charactor - mem to mem operation 1409 void Assembler::mvc(const MemOperand& opnd1, const MemOperand& opnd2, 1410 uint32_t length) { 1411 ss_form(MVC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(), 1412 opnd2.getBaseRegister(), opnd2.getDisplacement()); 1413 } 1414 1415 // ----------------------- 1416 // 32-bit Add Instructions 1417 // ----------------------- 1418 // Add Halfword Immediate (32) 1419 void Assembler::ahi(Register r1, const Operand& i2) { ri_form(AHI, r1, i2); } 1420 1421 // Add Halfword Immediate (32) 1422 void Assembler::ahik(Register r1, Register r3, const Operand& i2) { 1423 rie_form(AHIK, r1, r3, i2); 1424 } 1425 1426 // Add Register-Register-Register (32) 1427 void Assembler::ark(Register r1, Register r2, Register r3) { 1428 rrf1_form(ARK, r1, r2, r3); 1429 } 1430 1431 // Add Storage-Imm (32) 1432 void Assembler::asi(const MemOperand& opnd, const Operand& imm) { 1433 DCHECK(is_int8(imm.imm_)); 1434 DCHECK(is_int20(opnd.offset())); 1435 siy_form(ASI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset()); 1436 } 1437 1438 // ----------------------- 1439 // 64-bit Add Instructions 1440 // ----------------------- 1441 // Add Halfword Immediate (64) 1442 void Assembler::aghi(Register r1, const Operand& i2) { ri_form(AGHI, r1, i2); } 1443 1444 // Add Halfword Immediate (64) 1445 void Assembler::aghik(Register r1, Register r3, const Operand& i2) { 1446 rie_form(AGHIK, r1, r3, i2); 1447 } 1448 1449 // Add Register-Register-Register (64) 1450 void Assembler::agrk(Register r1, Register r2, Register r3) { 1451 rrf1_form(AGRK, r1, r2, r3); 1452 } 1453 1454 // Add Storage-Imm (64) 1455 void Assembler::agsi(const MemOperand& opnd, const Operand& imm) { 1456 DCHECK(is_int8(imm.imm_)); 1457 DCHECK(is_int20(opnd.offset())); 1458 siy_form(AGSI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset()); 1459 } 1460 1461 // ------------------------------- 1462 // 32-bit Add Logical Instructions 1463 // ------------------------------- 1464 // Add Logical Register-Register-Register (32) 1465 void Assembler::alrk(Register r1, Register r2, Register r3) { 1466 rrf1_form(ALRK, r1, r2, r3); 1467 } 1468 1469 // ------------------------------- 1470 // 64-bit Add Logical Instructions 1471 // ------------------------------- 1472 // Add Logical Register-Register-Register (64) 1473 void Assembler::algrk(Register r1, Register r2, Register r3) { 1474 rrf1_form(ALGRK, r1, r2, r3); 1475 } 1476 1477 // ---------------------------- 1478 // 32-bit Subtract Instructions 1479 // ---------------------------- 1480 // Subtract Register-Register-Register (32) 1481 void Assembler::srk(Register r1, Register r2, Register r3) { 1482 rrf1_form(SRK, r1, r2, r3); 1483 } 1484 1485 // ---------------------------- 1486 // 64-bit Subtract Instructions 1487 // ---------------------------- 1488 // Subtract Register-Register-Register (64) 1489 void Assembler::sgrk(Register r1, Register r2, Register r3) { 1490 rrf1_form(SGRK, r1, r2, r3); 1491 } 1492 1493 // ------------------------------------ 1494 // 32-bit Subtract Logical Instructions 1495 // ------------------------------------ 1496 // Subtract Logical Register-Register-Register (32) 1497 void Assembler::slrk(Register r1, Register r2, Register r3) { 1498 rrf1_form(SLRK, r1, r2, r3); 1499 } 1500 1501 // ------------------------------------ 1502 // 64-bit Subtract Logical Instructions 1503 // ------------------------------------ 1504 // Subtract Logical Register-Register-Register (64) 1505 void Assembler::slgrk(Register r1, Register r2, Register r3) { 1506 rrf1_form(SLGRK, r1, r2, r3); 1507 } 1508 1509 // ---------------------------- 1510 // 32-bit Multiply Instructions 1511 // ---------------------------- 1512 // Multiply Halfword Immediate (32) 1513 void Assembler::mhi(Register r1, const Operand& opnd) { 1514 ri_form(MHI, r1, opnd); 1515 } 1516 1517 // Multiply Single Register (32) 1518 void Assembler::msrkc(Register r1, Register r2, Register r3) { 1519 rrf1_form(MSRKC, r1, r2, r3); 1520 } 1521 1522 // Multiply Single Register (64) 1523 void Assembler::msgrkc(Register r1, Register r2, Register r3) { 1524 rrf1_form(MSGRKC, r1, r2, r3); 1525 } 1526 1527 // ---------------------------- 1528 // 64-bit Multiply Instructions 1529 // ---------------------------- 1530 // Multiply Halfword Immediate (64) 1531 void Assembler::mghi(Register r1, const Operand& opnd) { 1532 ri_form(MGHI, r1, opnd); 1533 } 1534 1535 // -------------------- 1536 // Bitwise Instructions 1537 // -------------------- 1538 // AND Register-Register-Register (32) 1539 void Assembler::nrk(Register r1, Register r2, Register r3) { 1540 rrf1_form(NRK, r1, r2, r3); 1541 } 1542 1543 // AND Register-Register-Register (64) 1544 void Assembler::ngrk(Register r1, Register r2, Register r3) { 1545 rrf1_form(NGRK, r1, r2, r3); 1546 } 1547 1548 // OR Register-Register-Register (32) 1549 void Assembler::ork(Register r1, Register r2, Register r3) { 1550 rrf1_form(ORK, r1, r2, r3); 1551 } 1552 1553 // OR Register-Register-Register (64) 1554 void Assembler::ogrk(Register r1, Register r2, Register r3) { 1555 rrf1_form(OGRK, r1, r2, r3); 1556 } 1557 1558 // XOR Register-Register-Register (32) 1559 void Assembler::xrk(Register r1, Register r2, Register r3) { 1560 rrf1_form(XRK, r1, r2, r3); 1561 } 1562 1563 // XOR Register-Register-Register (64) 1564 void Assembler::xgrk(Register r1, Register r2, Register r3) { 1565 rrf1_form(XGRK, r1, r2, r3); 1566 } 1567 1568 // XOR Storage-Storage 1569 void Assembler::xc(const MemOperand& opnd1, const MemOperand& opnd2, 1570 Length length) { 1571 ss_form(XC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(), 1572 opnd2.getBaseRegister(), opnd2.getDisplacement()); 1573 } 1574 1575 void Assembler::EnsureSpaceFor(int space_needed) { 1576 if (buffer_space() <= (kGap + space_needed)) { 1577 GrowBuffer(space_needed); 1578 } 1579 } 1580 1581 // Rotate Left Single Logical (32) 1582 void Assembler::rll(Register r1, Register r3, Register opnd) { 1583 DCHECK(!opnd.is(r0)); 1584 rsy_form(RLL, r1, r3, opnd, 0); 1585 } 1586 1587 // Rotate Left Single Logical (32) 1588 void Assembler::rll(Register r1, Register r3, const Operand& opnd) { 1589 rsy_form(RLL, r1, r3, r0, opnd.immediate()); 1590 } 1591 1592 // Rotate Left Single Logical (32) 1593 void Assembler::rll(Register r1, Register r3, Register r2, 1594 const Operand& opnd) { 1595 rsy_form(RLL, r1, r3, r2, opnd.immediate()); 1596 } 1597 1598 // Rotate Left Single Logical (64) 1599 void Assembler::rllg(Register r1, Register r3, Register opnd) { 1600 DCHECK(!opnd.is(r0)); 1601 rsy_form(RLLG, r1, r3, opnd, 0); 1602 } 1603 1604 // Rotate Left Single Logical (64) 1605 void Assembler::rllg(Register r1, Register r3, const Operand& opnd) { 1606 rsy_form(RLLG, r1, r3, r0, opnd.immediate()); 1607 } 1608 1609 // Rotate Left Single Logical (64) 1610 void Assembler::rllg(Register r1, Register r3, Register r2, 1611 const Operand& opnd) { 1612 rsy_form(RLLG, r1, r3, r2, opnd.immediate()); 1613 } 1614 1615 // Shift Left Single Logical (32) 1616 void Assembler::sll(Register r1, Register opnd) { 1617 DCHECK(!opnd.is(r0)); 1618 rs_form(SLL, r1, r0, opnd, 0); 1619 } 1620 1621 // Shift Left Single Logical (32) 1622 void Assembler::sll(Register r1, const Operand& opnd) { 1623 rs_form(SLL, r1, r0, r0, opnd.immediate()); 1624 } 1625 1626 // Shift Left Single Logical (32) 1627 void Assembler::sllk(Register r1, Register r3, Register opnd) { 1628 DCHECK(!opnd.is(r0)); 1629 rsy_form(SLLK, r1, r3, opnd, 0); 1630 } 1631 1632 // Shift Left Single Logical (32) 1633 void Assembler::sllk(Register r1, Register r3, const Operand& opnd) { 1634 rsy_form(SLLK, r1, r3, r0, opnd.immediate()); 1635 } 1636 1637 // Shift Left Single Logical (64) 1638 void Assembler::sllg(Register r1, Register r3, Register opnd) { 1639 DCHECK(!opnd.is(r0)); 1640 rsy_form(SLLG, r1, r3, opnd, 0); 1641 } 1642 1643 // Shift Left Single Logical (64) 1644 void Assembler::sllg(Register r1, Register r3, const Operand& opnd) { 1645 rsy_form(SLLG, r1, r3, r0, opnd.immediate()); 1646 } 1647 1648 // Shift Left Double Logical (64) 1649 void Assembler::sldl(Register r1, Register b2, const Operand& opnd) { 1650 DCHECK(r1.code() % 2 == 0); 1651 rs_form(SLDL, r1, r0, b2, opnd.immediate()); 1652 } 1653 1654 // Shift Right Single Logical (32) 1655 void Assembler::srl(Register r1, Register opnd) { 1656 DCHECK(!opnd.is(r0)); 1657 rs_form(SRL, r1, r0, opnd, 0); 1658 } 1659 1660 // Shift Right Double Arith (64) 1661 void Assembler::srda(Register r1, Register b2, const Operand& opnd) { 1662 DCHECK(r1.code() % 2 == 0); 1663 rs_form(SRDA, r1, r0, b2, opnd.immediate()); 1664 } 1665 1666 // Shift Right Double Logical (64) 1667 void Assembler::srdl(Register r1, Register b2, const Operand& opnd) { 1668 DCHECK(r1.code() % 2 == 0); 1669 rs_form(SRDL, r1, r0, b2, opnd.immediate()); 1670 } 1671 1672 // Shift Right Single Logical (32) 1673 void Assembler::srl(Register r1, const Operand& opnd) { 1674 rs_form(SRL, r1, r0, r0, opnd.immediate()); 1675 } 1676 1677 // Shift Right Single Logical (32) 1678 void Assembler::srlk(Register r1, Register r3, Register opnd) { 1679 DCHECK(!opnd.is(r0)); 1680 rsy_form(SRLK, r1, r3, opnd, 0); 1681 } 1682 1683 // Shift Right Single Logical (32) 1684 void Assembler::srlk(Register r1, Register r3, const Operand& opnd) { 1685 rsy_form(SRLK, r1, r3, r0, opnd.immediate()); 1686 } 1687 1688 // Shift Right Single Logical (64) 1689 void Assembler::srlg(Register r1, Register r3, Register opnd) { 1690 DCHECK(!opnd.is(r0)); 1691 rsy_form(SRLG, r1, r3, opnd, 0); 1692 } 1693 1694 // Shift Right Single Logical (64) 1695 void Assembler::srlg(Register r1, Register r3, const Operand& opnd) { 1696 rsy_form(SRLG, r1, r3, r0, opnd.immediate()); 1697 } 1698 1699 // Shift Left Single (32) 1700 void Assembler::sla(Register r1, Register opnd) { 1701 DCHECK(!opnd.is(r0)); 1702 rs_form(SLA, r1, r0, opnd, 0); 1703 } 1704 1705 // Shift Left Single (32) 1706 void Assembler::sla(Register r1, const Operand& opnd) { 1707 rs_form(SLA, r1, r0, r0, opnd.immediate()); 1708 } 1709 1710 // Shift Left Single (32) 1711 void Assembler::slak(Register r1, Register r3, Register opnd) { 1712 DCHECK(!opnd.is(r0)); 1713 rsy_form(SLAK, r1, r3, opnd, 0); 1714 } 1715 1716 // Shift Left Single (32) 1717 void Assembler::slak(Register r1, Register r3, const Operand& opnd) { 1718 rsy_form(SLAK, r1, r3, r0, opnd.immediate()); 1719 } 1720 1721 // Shift Left Single (64) 1722 void Assembler::slag(Register r1, Register r3, Register opnd) { 1723 DCHECK(!opnd.is(r0)); 1724 rsy_form(SLAG, r1, r3, opnd, 0); 1725 } 1726 1727 // Shift Left Single (64) 1728 void Assembler::slag(Register r1, Register r3, const Operand& opnd) { 1729 rsy_form(SLAG, r1, r3, r0, opnd.immediate()); 1730 } 1731 1732 // Shift Right Single (32) 1733 void Assembler::sra(Register r1, Register opnd) { 1734 DCHECK(!opnd.is(r0)); 1735 rs_form(SRA, r1, r0, opnd, 0); 1736 } 1737 1738 // Shift Right Single (32) 1739 void Assembler::sra(Register r1, const Operand& opnd) { 1740 rs_form(SRA, r1, r0, r0, opnd.immediate()); 1741 } 1742 1743 // Shift Right Single (32) 1744 void Assembler::srak(Register r1, Register r3, Register opnd) { 1745 DCHECK(!opnd.is(r0)); 1746 rsy_form(SRAK, r1, r3, opnd, 0); 1747 } 1748 1749 // Shift Right Single (32) 1750 void Assembler::srak(Register r1, Register r3, const Operand& opnd) { 1751 rsy_form(SRAK, r1, r3, r0, opnd.immediate()); 1752 } 1753 1754 // Shift Right Single (64) 1755 void Assembler::srag(Register r1, Register r3, Register opnd) { 1756 DCHECK(!opnd.is(r0)); 1757 rsy_form(SRAG, r1, r3, opnd, 0); 1758 } 1759 1760 void Assembler::srag(Register r1, Register r3, const Operand& opnd) { 1761 rsy_form(SRAG, r1, r3, r0, opnd.immediate()); 1762 } 1763 1764 // Shift Right Double 1765 void Assembler::srda(Register r1, const Operand& opnd) { 1766 DCHECK(r1.code() % 2 == 0); 1767 rs_form(SRDA, r1, r0, r0, opnd.immediate()); 1768 } 1769 1770 // Shift Right Double Logical 1771 void Assembler::srdl(Register r1, const Operand& opnd) { 1772 DCHECK(r1.code() % 2 == 0); 1773 rs_form(SRDL, r1, r0, r0, opnd.immediate()); 1774 } 1775 1776 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode, 1777 TypeFeedbackId ast_id) { 1778 EnsureSpace ensure_space(this); 1779 1780 int32_t target_index = emit_code_target(target, rmode, ast_id); 1781 brasl(r14, Operand(target_index)); 1782 } 1783 1784 void Assembler::jump(Handle<Code> target, RelocInfo::Mode rmode, 1785 Condition cond) { 1786 EnsureSpace ensure_space(this); 1787 1788 int32_t target_index = emit_code_target(target, rmode); 1789 brcl(cond, Operand(target_index)); 1790 } 1791 1792 // 32-bit Load Multiple - short displacement (12-bits unsigned) 1793 void Assembler::lm(Register r1, Register r2, const MemOperand& src) { 1794 rs_form(LM, r1, r2, src.rb(), src.offset()); 1795 } 1796 1797 // 32-bit Load Multiple - long displacement (20-bits signed) 1798 void Assembler::lmy(Register r1, Register r2, const MemOperand& src) { 1799 rsy_form(LMY, r1, r2, src.rb(), src.offset()); 1800 } 1801 1802 // 64-bit Load Multiple - long displacement (20-bits signed) 1803 void Assembler::lmg(Register r1, Register r2, const MemOperand& src) { 1804 rsy_form(LMG, r1, r2, src.rb(), src.offset()); 1805 } 1806 1807 // Move integer (32) 1808 void Assembler::mvhi(const MemOperand& opnd1, const Operand& i2) { 1809 sil_form(MVHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2); 1810 } 1811 1812 // Move integer (64) 1813 void Assembler::mvghi(const MemOperand& opnd1, const Operand& i2) { 1814 sil_form(MVGHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2); 1815 } 1816 1817 // Insert Immediate (high high) 1818 void Assembler::iihh(Register r1, const Operand& opnd) { 1819 ri_form(IIHH, r1, opnd); 1820 } 1821 1822 // Insert Immediate (high low) 1823 void Assembler::iihl(Register r1, const Operand& opnd) { 1824 ri_form(IIHL, r1, opnd); 1825 } 1826 1827 // Insert Immediate (low high) 1828 void Assembler::iilh(Register r1, const Operand& opnd) { 1829 ri_form(IILH, r1, opnd); 1830 } 1831 1832 // Insert Immediate (low low) 1833 void Assembler::iill(Register r1, const Operand& opnd) { 1834 ri_form(IILL, r1, opnd); 1835 } 1836 1837 // GPR <-> FPR Instructions 1838 1839 // Floating point instructions 1840 // 1841 // Add Register-Storage (LB) 1842 void Assembler::adb(DoubleRegister r1, const MemOperand& opnd) { 1843 rxe_form(ADB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 1844 opnd.offset()); 1845 } 1846 1847 // Divide Register-Storage (LB) 1848 void Assembler::ddb(DoubleRegister r1, const MemOperand& opnd) { 1849 rxe_form(DDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 1850 opnd.offset()); 1851 } 1852 1853 // Multiply Register-Storage (LB) 1854 void Assembler::mdb(DoubleRegister r1, const MemOperand& opnd) { 1855 rxe_form(MDB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(), 1856 opnd.offset()); 1857 } 1858 1859 // Subtract Register-Storage (LB) 1860 void Assembler::sdb(DoubleRegister r1, const MemOperand& opnd) { 1861 rxe_form(SDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 1862 opnd.offset()); 1863 } 1864 1865 void Assembler::ceb(DoubleRegister r1, const MemOperand& opnd) { 1866 rxe_form(CEB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 1867 opnd.offset()); 1868 } 1869 1870 void Assembler::cdb(DoubleRegister r1, const MemOperand& opnd) { 1871 rxe_form(CDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 1872 opnd.offset()); 1873 } 1874 1875 // Square Root (LB) 1876 void Assembler::sqdb(DoubleRegister r1, const MemOperand& opnd) { 1877 rxe_form(SQDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 1878 opnd.offset()); 1879 } 1880 1881 // Convert to Fixed point (64<-S) 1882 void Assembler::cgebr(Condition m, Register r1, DoubleRegister r2) { 1883 rrfe_form(CGEBR, m, Condition(0), r1, Register::from_code(r2.code())); 1884 } 1885 1886 // Convert to Fixed point (64<-L) 1887 void Assembler::cgdbr(Condition m, Register r1, DoubleRegister r2) { 1888 rrfe_form(CGDBR, m, Condition(0), r1, Register::from_code(r2.code())); 1889 } 1890 1891 // Convert to Fixed point (32<-L) 1892 void Assembler::cfdbr(Condition m, Register r1, DoubleRegister r2) { 1893 rrfe_form(CFDBR, m, Condition(0), r1, Register::from_code(r2.code())); 1894 } 1895 1896 // Convert to Fixed Logical (64<-L) 1897 void Assembler::clgdbr(Condition m3, Condition m4, Register r1, 1898 DoubleRegister r2) { 1899 DCHECK_EQ(m4, Condition(0)); 1900 rrfe_form(CLGDBR, m3, m4, r1, Register::from_code(r2.code())); 1901 } 1902 1903 // Convert to Fixed Logical (64<-F32) 1904 void Assembler::clgebr(Condition m3, Condition m4, Register r1, 1905 DoubleRegister r2) { 1906 DCHECK_EQ(m4, Condition(0)); 1907 rrfe_form(CLGEBR, m3, m4, r1, Register::from_code(r2.code())); 1908 } 1909 1910 // Convert to Fixed Logical (32<-F64) 1911 void Assembler::clfdbr(Condition m3, Condition m4, Register r1, 1912 DoubleRegister r2) { 1913 DCHECK_EQ(m3, Condition(0)); 1914 DCHECK_EQ(m4, Condition(0)); 1915 rrfe_form(CLFDBR, Condition(0), Condition(0), r1, 1916 Register::from_code(r2.code())); 1917 } 1918 1919 // Convert to Fixed Logical (32<-F32) 1920 void Assembler::clfebr(Condition m3, Condition m4, Register r1, 1921 DoubleRegister r2) { 1922 DCHECK_EQ(m4, Condition(0)); 1923 rrfe_form(CLFEBR, m3, Condition(0), r1, Register::from_code(r2.code())); 1924 } 1925 1926 // Convert from Fixed Logical (L<-64) 1927 void Assembler::celgbr(Condition m3, Condition m4, DoubleRegister r1, 1928 Register r2) { 1929 DCHECK_EQ(m3, Condition(0)); 1930 DCHECK_EQ(m4, Condition(0)); 1931 rrfe_form(CELGBR, Condition(0), Condition(0), Register::from_code(r1.code()), 1932 r2); 1933 } 1934 1935 // Convert from Fixed Logical (F32<-32) 1936 void Assembler::celfbr(Condition m3, Condition m4, DoubleRegister r1, 1937 Register r2) { 1938 DCHECK_EQ(m4, Condition(0)); 1939 rrfe_form(CELFBR, m3, Condition(0), Register::from_code(r1.code()), r2); 1940 } 1941 1942 // Convert from Fixed Logical (L<-64) 1943 void Assembler::cdlgbr(Condition m3, Condition m4, DoubleRegister r1, 1944 Register r2) { 1945 DCHECK_EQ(m3, Condition(0)); 1946 DCHECK_EQ(m4, Condition(0)); 1947 rrfe_form(CDLGBR, Condition(0), Condition(0), Register::from_code(r1.code()), 1948 r2); 1949 } 1950 1951 // Convert from Fixed Logical (L<-32) 1952 void Assembler::cdlfbr(Condition m3, Condition m4, DoubleRegister r1, 1953 Register r2) { 1954 DCHECK_EQ(m4, Condition(0)); 1955 rrfe_form(CDLFBR, m3, Condition(0), Register::from_code(r1.code()), r2); 1956 } 1957 1958 // Convert from Fixed point (S<-32) 1959 void Assembler::cefbr(Condition m3, DoubleRegister r1, Register r2) { 1960 rrfe_form(CEFBR, m3, Condition(0), Register::from_code(r1.code()), r2); 1961 } 1962 1963 // Convert to Fixed point (32<-S) 1964 void Assembler::cfebr(Condition m3, Register r1, DoubleRegister r2) { 1965 rrfe_form(CFEBR, m3, Condition(0), r1, Register::from_code(r2.code())); 1966 } 1967 1968 // Load (L <- S) 1969 void Assembler::ldeb(DoubleRegister d1, const MemOperand& opnd) { 1970 rxe_form(LDEB, Register::from_code(d1.code()), opnd.rx(), opnd.rb(), 1971 opnd.offset()); 1972 } 1973 1974 // Load FP Integer 1975 void Assembler::fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) { 1976 rrf2_form(FIEBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code()); 1977 } 1978 1979 // Load FP Integer 1980 void Assembler::fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) { 1981 rrf2_form(FIDBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code()); 1982 } 1983 1984 // end of S390instructions 1985 1986 bool Assembler::IsNop(SixByteInstr instr, int type) { 1987 DCHECK((0 == type) || (DEBUG_BREAK_NOP == type)); 1988 if (DEBUG_BREAK_NOP == type) { 1989 return ((instr & 0xffffffff) == 0xa53b0000); // oill r3, 0 1990 } 1991 return ((instr & 0xffff) == 0x1800); // lr r0,r0 1992 } 1993 1994 // dummy instruction reserved for special use. 1995 void Assembler::dumy(int r1, int x2, int b2, int d2) { 1996 #if defined(USE_SIMULATOR) 1997 int op = 0xE353; 1998 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 1999 (static_cast<uint64_t>(r1) & 0xF) * B36 | 2000 (static_cast<uint64_t>(x2) & 0xF) * B32 | 2001 (static_cast<uint64_t>(b2) & 0xF) * B28 | 2002 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 2003 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 2004 (static_cast<uint64_t>(op & 0x00FF)); 2005 emit6bytes(code); 2006 #endif 2007 } 2008 2009 void Assembler::GrowBuffer(int needed) { 2010 if (!own_buffer_) FATAL("external code buffer is too small"); 2011 2012 // Compute new buffer size. 2013 CodeDesc desc; // the new buffer 2014 if (buffer_size_ < 4 * KB) { 2015 desc.buffer_size = 4 * KB; 2016 } else if (buffer_size_ < 1 * MB) { 2017 desc.buffer_size = 2 * buffer_size_; 2018 } else { 2019 desc.buffer_size = buffer_size_ + 1 * MB; 2020 } 2021 int space = buffer_space() + (desc.buffer_size - buffer_size_); 2022 if (space < needed) { 2023 desc.buffer_size += needed - space; 2024 } 2025 CHECK_GT(desc.buffer_size, 0); // no overflow 2026 2027 // Set up new buffer. 2028 desc.buffer = NewArray<byte>(desc.buffer_size); 2029 desc.origin = this; 2030 2031 desc.instr_size = pc_offset(); 2032 desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 2033 2034 // Copy the data. 2035 intptr_t pc_delta = desc.buffer - buffer_; 2036 intptr_t rc_delta = 2037 (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2038 memmove(desc.buffer, buffer_, desc.instr_size); 2039 memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(), 2040 desc.reloc_size); 2041 2042 // Switch buffers. 2043 DeleteArray(buffer_); 2044 buffer_ = desc.buffer; 2045 buffer_size_ = desc.buffer_size; 2046 pc_ += pc_delta; 2047 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2048 reloc_info_writer.last_pc() + pc_delta); 2049 2050 // None of our relocation types are pc relative pointing outside the code 2051 // buffer nor pc absolute pointing inside the code buffer, so there is no need 2052 // to relocate any emitted relocation entries. 2053 } 2054 2055 void Assembler::db(uint8_t data) { 2056 CheckBuffer(); 2057 *reinterpret_cast<uint8_t*>(pc_) = data; 2058 pc_ += sizeof(uint8_t); 2059 } 2060 2061 void Assembler::dd(uint32_t data) { 2062 CheckBuffer(); 2063 *reinterpret_cast<uint32_t*>(pc_) = data; 2064 pc_ += sizeof(uint32_t); 2065 } 2066 2067 void Assembler::dq(uint64_t value) { 2068 CheckBuffer(); 2069 *reinterpret_cast<uint64_t*>(pc_) = value; 2070 pc_ += sizeof(uint64_t); 2071 } 2072 2073 void Assembler::dp(uintptr_t data) { 2074 CheckBuffer(); 2075 *reinterpret_cast<uintptr_t*>(pc_) = data; 2076 pc_ += sizeof(uintptr_t); 2077 } 2078 2079 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2080 if (RelocInfo::IsNone(rmode) || 2081 // Don't record external references unless the heap will be serialized. 2082 (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() && 2083 !emit_debug_code())) { 2084 return; 2085 } 2086 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 2087 data = RecordedAstId().ToInt(); 2088 ClearRecordedAstId(); 2089 } 2090 DeferredRelocInfo rinfo(pc_offset(), rmode, data); 2091 relocations_.push_back(rinfo); 2092 } 2093 2094 void Assembler::emit_label_addr(Label* label) { 2095 CheckBuffer(); 2096 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 2097 int position = link(label); 2098 DCHECK(label->is_bound()); 2099 // Keep internal references relative until EmitRelocations. 2100 dp(position); 2101 } 2102 2103 void Assembler::EmitRelocations() { 2104 EnsureSpaceFor(relocations_.size() * kMaxRelocSize); 2105 2106 for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin(); 2107 it != relocations_.end(); it++) { 2108 RelocInfo::Mode rmode = it->rmode(); 2109 Address pc = buffer_ + it->position(); 2110 Code* code = NULL; 2111 RelocInfo rinfo(isolate(), pc, rmode, it->data(), code); 2112 2113 // Fix up internal references now that they are guaranteed to be bound. 2114 if (RelocInfo::IsInternalReference(rmode)) { 2115 // Jump table entry 2116 intptr_t pos = reinterpret_cast<intptr_t>(Memory::Address_at(pc)); 2117 Memory::Address_at(pc) = buffer_ + pos; 2118 } else if (RelocInfo::IsInternalReferenceEncoded(rmode)) { 2119 // mov sequence 2120 intptr_t pos = reinterpret_cast<intptr_t>(target_address_at(pc, code)); 2121 set_target_address_at(isolate(), pc, code, buffer_ + pos, 2122 SKIP_ICACHE_FLUSH); 2123 } 2124 2125 reloc_info_writer.Write(&rinfo); 2126 } 2127 } 2128 2129 } // namespace internal 2130 } // namespace v8 2131 #endif // V8_TARGET_ARCH_S390 2132