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 51namespace v8 { 52namespace internal { 53 54// Get the CPU features enabled by the build. 55static 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. 62static 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 117void 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[1]; 142 facilities[0] = 0; 143 // LHI sets up GPR0 144 // STFLE is specified as .insn, as opcode is not recognized. 145 // We register the instructions kill r0 (LHI) and the CC (STFLE). 146 asm volatile( 147 "lhi 0,0\n" 148 ".insn s,0xb2b00000,%0\n" 149 : "=Q"(facilities) 150 : 151 : "cc", "r0"); 152 153 // Test for Distinct Operands Facility - Bit 45 154 if (facilities[0] & (1lu << (63 - 45))) { 155 supported_ |= (1u << DISTINCT_OPS); 156 } 157 // Test for General Instruction Extension Facility - Bit 34 158 if (facilities[0] & (1lu << (63 - 34))) { 159 supported_ |= (1u << GENERAL_INSTR_EXT); 160 } 161 // Test for Floating Point Extension Facility - Bit 37 162 if (facilities[0] & (1lu << (63 - 37))) { 163 supported_ |= (1u << FLOATING_POINT_EXT); 164 } 165 } 166#else 167 // All distinct ops instructions can be simulated 168 supported_ |= (1u << DISTINCT_OPS); 169 // RISBG can be simulated 170 supported_ |= (1u << GENERAL_INSTR_EXT); 171 172 supported_ |= (1u << FLOATING_POINT_EXT); 173 USE(performSTFLE); // To avoid assert 174#endif 175 supported_ |= (1u << FPU); 176} 177 178void CpuFeatures::PrintTarget() { 179 const char* s390_arch = NULL; 180 181#if V8_TARGET_ARCH_S390X 182 s390_arch = "s390x"; 183#else 184 s390_arch = "s390"; 185#endif 186 187 printf("target %s\n", s390_arch); 188} 189 190void CpuFeatures::PrintFeatures() { 191 printf("FPU=%d\n", CpuFeatures::IsSupported(FPU)); 192 printf("FPU_EXT=%d\n", CpuFeatures::IsSupported(FLOATING_POINT_EXT)); 193 printf("GENERAL_INSTR=%d\n", CpuFeatures::IsSupported(GENERAL_INSTR_EXT)); 194 printf("DISTINCT_OPS=%d\n", CpuFeatures::IsSupported(DISTINCT_OPS)); 195} 196 197Register ToRegister(int num) { 198 DCHECK(num >= 0 && num < kNumRegisters); 199 const Register kRegisters[] = {r0, r1, r2, r3, r4, r5, r6, r7, 200 r8, r9, r10, fp, ip, r13, r14, sp}; 201 return kRegisters[num]; 202} 203 204// ----------------------------------------------------------------------------- 205// Implementation of RelocInfo 206 207const int RelocInfo::kApplyMask = 208 RelocInfo::kCodeTargetMask | 1 << RelocInfo::INTERNAL_REFERENCE; 209 210bool RelocInfo::IsCodedSpecially() { 211 // The deserializer needs to know whether a pointer is specially 212 // coded. Being specially coded on S390 means that it is an iihf/iilf 213 // instruction sequence, and that is always the case inside code 214 // objects. 215 return true; 216} 217 218bool RelocInfo::IsInConstantPool() { return false; } 219 220Address RelocInfo::wasm_memory_reference() { 221 DCHECK(IsWasmMemoryReference(rmode_)); 222 return Assembler::target_address_at(pc_, host_); 223} 224 225uint32_t RelocInfo::wasm_memory_size_reference() { 226 DCHECK(IsWasmMemorySizeReference(rmode_)); 227 return static_cast<uint32_t>( 228 reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_))); 229} 230 231Address RelocInfo::wasm_global_reference() { 232 DCHECK(IsWasmGlobalReference(rmode_)); 233 return Assembler::target_address_at(pc_, host_); 234} 235 236void RelocInfo::unchecked_update_wasm_memory_reference( 237 Address address, ICacheFlushMode flush_mode) { 238 Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); 239} 240 241void RelocInfo::unchecked_update_wasm_memory_size(uint32_t size, 242 ICacheFlushMode flush_mode) { 243 Assembler::set_target_address_at(isolate_, pc_, host_, 244 reinterpret_cast<Address>(size), flush_mode); 245} 246 247// ----------------------------------------------------------------------------- 248// Implementation of Operand and MemOperand 249// See assembler-s390-inl.h for inlined constructors 250 251Operand::Operand(Handle<Object> handle) { 252 AllowDeferredHandleDereference using_raw_address; 253 rm_ = no_reg; 254 // Verify all Objects referred by code are NOT in new space. 255 Object* obj = *handle; 256 if (obj->IsHeapObject()) { 257 DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); 258 imm_ = reinterpret_cast<intptr_t>(handle.location()); 259 rmode_ = RelocInfo::EMBEDDED_OBJECT; 260 } else { 261 // no relocation needed 262 imm_ = reinterpret_cast<intptr_t>(obj); 263 rmode_ = kRelocInfo_NONEPTR; 264 } 265} 266 267MemOperand::MemOperand(Register rn, int32_t offset) { 268 baseRegister = rn; 269 indexRegister = r0; 270 offset_ = offset; 271} 272 273MemOperand::MemOperand(Register rx, Register rb, int32_t offset) { 274 baseRegister = rb; 275 indexRegister = rx; 276 offset_ = offset; 277} 278 279// ----------------------------------------------------------------------------- 280// Specific instructions, constants, and masks. 281 282Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 283 : AssemblerBase(isolate, buffer, buffer_size), 284 recorded_ast_id_(TypeFeedbackId::None()), 285 code_targets_(100), 286 positions_recorder_(this) { 287 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 288 289 last_bound_pos_ = 0; 290 ClearRecordedAstId(); 291 relocations_.reserve(128); 292} 293 294void Assembler::GetCode(CodeDesc* desc) { 295 EmitRelocations(); 296 297 // Set up code descriptor. 298 desc->buffer = buffer_; 299 desc->buffer_size = buffer_size_; 300 desc->instr_size = pc_offset(); 301 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 302 desc->origin = this; 303 desc->unwinding_info_size = 0; 304 desc->unwinding_info = nullptr; 305} 306 307void Assembler::Align(int m) { 308 DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m)); 309 while ((pc_offset() & (m - 1)) != 0) { 310 nop(0); 311 } 312} 313 314void Assembler::CodeTargetAlign() { Align(8); } 315 316Condition Assembler::GetCondition(Instr instr) { 317 switch (instr & kCondMask) { 318 case BT: 319 return eq; 320 case BF: 321 return ne; 322 default: 323 UNIMPLEMENTED(); 324 } 325 return al; 326} 327 328#if V8_TARGET_ARCH_S390X 329// This code assumes a FIXED_SEQUENCE for 64bit loads (iihf/iilf) 330bool Assembler::Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2) { 331 // Check the instructions are the iihf/iilf load into ip 332 return (((instr1 >> 32) == 0xC0C8) && ((instr2 >> 32) == 0xC0C9)); 333} 334#else 335// This code assumes a FIXED_SEQUENCE for 32bit loads (iilf) 336bool Assembler::Is32BitLoadIntoIP(SixByteInstr instr) { 337 // Check the instruction is an iilf load into ip/r12. 338 return ((instr >> 32) == 0xC0C9); 339} 340#endif 341 342// Labels refer to positions in the (to be) generated code. 343// There are bound, linked, and unused labels. 344// 345// Bound labels refer to known positions in the already 346// generated code. pos() is the position the label refers to. 347// 348// Linked labels refer to unknown positions in the code 349// to be generated; pos() is the position of the last 350// instruction using the label. 351 352// The link chain is terminated by a negative code position (must be aligned) 353const int kEndOfChain = -4; 354 355// Returns the target address of the relative instructions, typically 356// of the form: pos + imm (where immediate is in # of halfwords for 357// BR* and LARL). 358int Assembler::target_at(int pos) { 359 SixByteInstr instr = instr_at(pos); 360 // check which type of branch this is 16 or 26 bit offset 361 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos); 362 363 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) { 364 int16_t imm16 = SIGN_EXT_IMM16((instr & kImm16Mask)); 365 imm16 <<= 1; // BRC immediate is in # of halfwords 366 if (imm16 == 0) return kEndOfChain; 367 return pos + imm16; 368 } else if (LLILF == opcode || BRCL == opcode || LARL == opcode || 369 BRASL == opcode) { 370 int32_t imm32 = 371 static_cast<int32_t>(instr & (static_cast<uint64_t>(0xffffffff))); 372 if (LLILF != opcode) 373 imm32 <<= 1; // BR* + LARL treat immediate in # of halfwords 374 if (imm32 == 0) return kEndOfChain; 375 return pos + imm32; 376 } 377 378 // Unknown condition 379 DCHECK(false); 380 return -1; 381} 382 383// Update the target address of the current relative instruction. 384void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) { 385 SixByteInstr instr = instr_at(pos); 386 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos); 387 388 if (is_branch != nullptr) { 389 *is_branch = (opcode == BRC || opcode == BRCT || opcode == BRCTG || 390 opcode == BRCL || opcode == BRASL); 391 } 392 393 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) { 394 int16_t imm16 = target_pos - pos; 395 instr &= (~0xffff); 396 DCHECK(is_int16(imm16)); 397 instr_at_put<FourByteInstr>(pos, instr | (imm16 >> 1)); 398 return; 399 } else if (BRCL == opcode || LARL == opcode || BRASL == opcode) { 400 // Immediate is in # of halfwords 401 int32_t imm32 = target_pos - pos; 402 instr &= (~static_cast<uint64_t>(0xffffffff)); 403 instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1)); 404 return; 405 } else if (LLILF == opcode) { 406 DCHECK(target_pos == kEndOfChain || target_pos >= 0); 407 // Emitted label constant, not part of a branch. 408 // Make label relative to Code* of generated Code object. 409 int32_t imm32 = target_pos + (Code::kHeaderSize - kHeapObjectTag); 410 instr &= (~static_cast<uint64_t>(0xffffffff)); 411 instr_at_put<SixByteInstr>(pos, instr | imm32); 412 return; 413 } 414 DCHECK(false); 415} 416 417// Returns the maximum number of bits given instruction can address. 418int Assembler::max_reach_from(int pos) { 419 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos); 420 421 // Check which type of instr. In theory, we can return 422 // the values below + 1, given offset is # of halfwords 423 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) { 424 return 16; 425 } else if (LLILF == opcode || BRCL == opcode || LARL == opcode || 426 BRASL == opcode) { 427 return 31; // Using 31 as workaround instead of 32 as 428 // is_intn(x,32) doesn't work on 32-bit platforms. 429 // llilf: Emitted label constant, not part of 430 // a branch (regexp PushBacktrack). 431 } 432 DCHECK(false); 433 return 16; 434} 435 436void Assembler::bind_to(Label* L, int pos) { 437 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position 438 bool is_branch = false; 439 while (L->is_linked()) { 440 int fixup_pos = L->pos(); 441#ifdef DEBUG 442 int32_t offset = pos - fixup_pos; 443 int maxReach = max_reach_from(fixup_pos); 444#endif 445 next(L); // call next before overwriting link with target at fixup_pos 446 DCHECK(is_intn(offset, maxReach)); 447 target_at_put(fixup_pos, pos, &is_branch); 448 } 449 L->bind_to(pos); 450 451 // Keep track of the last bound label so we don't eliminate any instructions 452 // before a bound label. 453 if (pos > last_bound_pos_) last_bound_pos_ = pos; 454} 455 456void Assembler::bind(Label* L) { 457 DCHECK(!L->is_bound()); // label can only be bound once 458 bind_to(L, pc_offset()); 459} 460 461void Assembler::next(Label* L) { 462 DCHECK(L->is_linked()); 463 int link = target_at(L->pos()); 464 if (link == kEndOfChain) { 465 L->Unuse(); 466 } else { 467 DCHECK(link >= 0); 468 L->link_to(link); 469 } 470} 471 472bool Assembler::is_near(Label* L, Condition cond) { 473 DCHECK(L->is_bound()); 474 if (L->is_bound() == false) return false; 475 476 int maxReach = ((cond == al) ? 26 : 16); 477 int offset = L->pos() - pc_offset(); 478 479 return is_intn(offset, maxReach); 480} 481 482int Assembler::link(Label* L) { 483 int position; 484 if (L->is_bound()) { 485 position = L->pos(); 486 } else { 487 if (L->is_linked()) { 488 position = L->pos(); // L's link 489 } else { 490 // was: target_pos = kEndOfChain; 491 // However, using self to mark the first reference 492 // should avoid most instances of branch offset overflow. See 493 // target_at() for where this is converted back to kEndOfChain. 494 position = pc_offset(); 495 } 496 L->link_to(pc_offset()); 497 } 498 499 return position; 500} 501 502void Assembler::load_label_offset(Register r1, Label* L) { 503 int target_pos; 504 int constant; 505 if (L->is_bound()) { 506 target_pos = L->pos(); 507 constant = target_pos + (Code::kHeaderSize - kHeapObjectTag); 508 } else { 509 if (L->is_linked()) { 510 target_pos = L->pos(); // L's link 511 } else { 512 // was: target_pos = kEndOfChain; 513 // However, using branch to self to mark the first reference 514 // should avoid most instances of branch offset overflow. See 515 // target_at() for where this is converted back to kEndOfChain. 516 target_pos = pc_offset(); 517 } 518 L->link_to(pc_offset()); 519 520 constant = target_pos - pc_offset(); 521 } 522 llilf(r1, Operand(constant)); 523} 524 525// Pseudo op - branch on condition 526void Assembler::branchOnCond(Condition c, int branch_offset, bool is_bound) { 527 int offset = branch_offset; 528 if (is_bound && is_int16(offset)) { 529 brc(c, Operand(offset & 0xFFFF)); // short jump 530 } else { 531 brcl(c, Operand(offset)); // long jump 532 } 533} 534 535// 32-bit Store Multiple - short displacement (12-bits unsigned) 536void Assembler::stm(Register r1, Register r2, const MemOperand& src) { 537 rs_form(STM, r1, r2, src.rb(), src.offset()); 538} 539 540// 32-bit Store Multiple - long displacement (20-bits signed) 541void Assembler::stmy(Register r1, Register r2, const MemOperand& src) { 542 rsy_form(STMY, r1, r2, src.rb(), src.offset()); 543} 544 545// 64-bit Store Multiple - long displacement (20-bits signed) 546void Assembler::stmg(Register r1, Register r2, const MemOperand& src) { 547 rsy_form(STMG, r1, r2, src.rb(), src.offset()); 548} 549 550// Exception-generating instructions and debugging support. 551// Stops with a non-negative code less than kNumOfWatchedStops support 552// enabling/disabling and a counter feature. See simulator-s390.h . 553void Assembler::stop(const char* msg, Condition cond, int32_t code, 554 CRegister cr) { 555 if (cond != al) { 556 Label skip; 557 b(NegateCondition(cond), &skip, Label::kNear); 558 bkpt(0); 559 bind(&skip); 560 } else { 561 bkpt(0); 562 } 563} 564 565void Assembler::bkpt(uint32_t imm16) { 566 // GDB software breakpoint instruction 567 emit2bytes(0x0001); 568} 569 570// Pseudo instructions. 571void Assembler::nop(int type) { 572 switch (type) { 573 case 0: 574 lr(r0, r0); 575 break; 576 case DEBUG_BREAK_NOP: 577 // TODO(john.yan): Use a better NOP break 578 oill(r3, Operand::Zero()); 579 break; 580 default: 581 UNIMPLEMENTED(); 582 } 583} 584 585// RR format: <insn> R1,R2 586// +--------+----+----+ 587// | OpCode | R1 | R2 | 588// +--------+----+----+ 589// 0 8 12 15 590#define RR_FORM_EMIT(name, op) \ 591 void Assembler::name(Register r1, Register r2) { rr_form(op, r1, r2); } 592 593void Assembler::rr_form(Opcode op, Register r1, Register r2) { 594 DCHECK(is_uint8(op)); 595 emit2bytes(op * B8 | r1.code() * B4 | r2.code()); 596} 597 598void Assembler::rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2) { 599 DCHECK(is_uint8(op)); 600 emit2bytes(op * B8 | r1.code() * B4 | r2.code()); 601} 602 603// RR2 format: <insn> M1,R2 604// +--------+----+----+ 605// | OpCode | M1 | R2 | 606// +--------+----+----+ 607// 0 8 12 15 608#define RR2_FORM_EMIT(name, op) \ 609 void Assembler::name(Condition m1, Register r2) { rr_form(op, m1, r2); } 610 611void Assembler::rr_form(Opcode op, Condition m1, Register r2) { 612 DCHECK(is_uint8(op)); 613 DCHECK(is_uint4(m1)); 614 emit2bytes(op * B8 | m1 * B4 | r2.code()); 615} 616 617// RX format: <insn> R1,D2(X2,B2) 618// +--------+----+----+----+-------------+ 619// | OpCode | R1 | X2 | B2 | D2 | 620// +--------+----+----+----+-------------+ 621// 0 8 12 16 20 31 622#define RX_FORM_EMIT(name, op) \ 623 void Assembler::name(Register r, const MemOperand& opnd) { \ 624 name(r, opnd.getIndexRegister(), opnd.getBaseRegister(), \ 625 opnd.getDisplacement()); \ 626 } \ 627 void Assembler::name(Register r1, Register x2, Register b2, Disp d2) { \ 628 rx_form(op, r1, x2, b2, d2); \ 629 } 630void Assembler::rx_form(Opcode op, Register r1, Register x2, Register b2, 631 Disp d2) { 632 DCHECK(is_uint8(op)); 633 DCHECK(is_uint12(d2)); 634 emit4bytes(op * B24 | r1.code() * B20 | x2.code() * B16 | b2.code() * B12 | 635 d2); 636} 637 638void Assembler::rx_form(Opcode op, DoubleRegister r1, Register x2, Register b2, 639 Disp d2) { 640 DCHECK(is_uint8(op)); 641 DCHECK(is_uint12(d2)); 642 emit4bytes(op * B24 | r1.code() * B20 | x2.code() * B16 | b2.code() * B12 | 643 d2); 644} 645 646// RI1 format: <insn> R1,I2 647// +--------+----+----+------------------+ 648// | OpCode | R1 |OpCd| I2 | 649// +--------+----+----+------------------+ 650// 0 8 12 16 31 651#define RI1_FORM_EMIT(name, op) \ 652 void Assembler::name(Register r, const Operand& i2) { ri_form(op, r, i2); } 653 654void Assembler::ri_form(Opcode op, Register r1, const Operand& i2) { 655 DCHECK(is_uint12(op)); 656 DCHECK(is_uint16(i2.imm_) || is_int16(i2.imm_)); 657 emit4bytes((op & 0xFF0) * B20 | r1.code() * B20 | (op & 0xF) * B16 | 658 (i2.imm_ & 0xFFFF)); 659} 660 661// RI2 format: <insn> M1,I2 662// +--------+----+----+------------------+ 663// | OpCode | M1 |OpCd| I2 | 664// +--------+----+----+------------------+ 665// 0 8 12 16 31 666#define RI2_FORM_EMIT(name, op) \ 667 void Assembler::name(Condition m, const Operand& i2) { ri_form(op, m, i2); } 668 669void Assembler::ri_form(Opcode op, Condition m1, const Operand& i2) { 670 DCHECK(is_uint12(op)); 671 DCHECK(is_uint4(m1)); 672 DCHECK(is_uint16(i2.imm_)); 673 emit4bytes((op & 0xFF0) * B20 | m1 * B20 | (op & 0xF) * B16 | 674 (i2.imm_ & 0xFFFF)); 675} 676 677// RIE-f format: <insn> R1,R2,I3,I4,I5 678// +--------+----+----+------------------+--------+--------+ 679// | OpCode | R1 | R2 | I3 | I4 | I5 | OpCode | 680// +--------+----+----+------------------+--------+--------+ 681// 0 8 12 16 24 32 40 47 682void Assembler::rie_f_form(Opcode op, Register r1, Register r2, 683 const Operand& i3, const Operand& i4, 684 const Operand& i5) { 685 DCHECK(is_uint16(op)); 686 DCHECK(is_uint8(i3.imm_)); 687 DCHECK(is_uint8(i4.imm_)); 688 DCHECK(is_uint8(i5.imm_)); 689 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 690 (static_cast<uint64_t>(r1.code())) * B36 | 691 (static_cast<uint64_t>(r2.code())) * B32 | 692 (static_cast<uint64_t>(i3.imm_)) * B24 | 693 (static_cast<uint64_t>(i4.imm_)) * B16 | 694 (static_cast<uint64_t>(i5.imm_)) * B8 | 695 (static_cast<uint64_t>(op & 0x00FF)); 696 emit6bytes(code); 697} 698 699// RIE format: <insn> R1,R3,I2 700// +--------+----+----+------------------+--------+--------+ 701// | OpCode | R1 | R3 | I2 |////////| OpCode | 702// +--------+----+----+------------------+--------+--------+ 703// 0 8 12 16 32 40 47 704#define RIE_FORM_EMIT(name, op) \ 705 void Assembler::name(Register r1, Register r3, const Operand& i2) { \ 706 rie_form(op, r1, r3, i2); \ 707 } 708 709void Assembler::rie_form(Opcode op, Register r1, Register r3, 710 const Operand& i2) { 711 DCHECK(is_uint16(op)); 712 DCHECK(is_int16(i2.imm_)); 713 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 714 (static_cast<uint64_t>(r1.code())) * B36 | 715 (static_cast<uint64_t>(r3.code())) * B32 | 716 (static_cast<uint64_t>(i2.imm_ & 0xFFFF)) * B16 | 717 (static_cast<uint64_t>(op & 0x00FF)); 718 emit6bytes(code); 719} 720 721// RIL1 format: <insn> R1,I2 722// +--------+----+----+------------------------------------+ 723// | OpCode | R1 |OpCd| I2 | 724// +--------+----+----+------------------------------------+ 725// 0 8 12 16 47 726#define RIL1_FORM_EMIT(name, op) \ 727 void Assembler::name(Register r, const Operand& i2) { ril_form(op, r, i2); } 728 729void Assembler::ril_form(Opcode op, Register r1, const Operand& i2) { 730 DCHECK(is_uint12(op)); 731 uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 | 732 (static_cast<uint64_t>(r1.code())) * B36 | 733 (static_cast<uint64_t>(op & 0x00F)) * B32 | 734 (static_cast<uint64_t>(i2.imm_) & 0xFFFFFFFF); 735 emit6bytes(code); 736} 737 738// RIL2 format: <insn> M1,I2 739// +--------+----+----+------------------------------------+ 740// | OpCode | M1 |OpCd| I2 | 741// +--------+----+----+------------------------------------+ 742// 0 8 12 16 47 743#define RIL2_FORM_EMIT(name, op) \ 744 void Assembler::name(Condition m1, const Operand& i2) { \ 745 ril_form(op, m1, i2); \ 746 } 747 748void Assembler::ril_form(Opcode op, Condition m1, const Operand& i2) { 749 DCHECK(is_uint12(op)); 750 DCHECK(is_uint4(m1)); 751 uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 | 752 (static_cast<uint64_t>(m1)) * B36 | 753 (static_cast<uint64_t>(op & 0x00F)) * B32 | 754 (static_cast<uint64_t>(i2.imm_ & 0xFFFFFFFF)); 755 emit6bytes(code); 756} 757 758// RRE format: <insn> R1,R2 759// +------------------+--------+----+----+ 760// | OpCode |////////| R1 | R2 | 761// +------------------+--------+----+----+ 762// 0 16 24 28 31 763#define RRE_FORM_EMIT(name, op) \ 764 void Assembler::name(Register r1, Register r2) { rre_form(op, r1, r2); } 765 766void Assembler::rre_form(Opcode op, Register r1, Register r2) { 767 DCHECK(is_uint16(op)); 768 emit4bytes(op << 16 | r1.code() * B4 | r2.code()); 769} 770 771void Assembler::rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2) { 772 DCHECK(is_uint16(op)); 773 emit4bytes(op << 16 | r1.code() * B4 | r2.code()); 774} 775 776// RRD format: <insn> R1,R3, R2 777// +------------------+----+----+----+----+ 778// | OpCode | R1 |////| R3 | R2 | 779// +------------------+----+----+----+----+ 780// 0 16 20 24 28 31 781#define RRD_FORM_EMIT(name, op) \ 782 void Assembler::name(Register r1, Register r3, Register r2) { \ 783 rrd_form(op, r1, r3, r2); \ 784 } 785 786void Assembler::rrd_form(Opcode op, Register r1, Register r3, Register r2) { 787 emit4bytes(op << 16 | r1.code() * B12 | r3.code() * B4 | r2.code()); 788} 789 790// RS1 format: <insn> R1,R3,D2(B2) 791// +--------+----+----+----+-------------+ 792// | OpCode | R1 | R3 | B2 | D2 | 793// +--------+----+----+----+-------------+ 794// 0 8 12 16 20 31 795#define RS1_FORM_EMIT(name, op) \ 796 void Assembler::name(Register r1, Register r3, Register b2, Disp d2) { \ 797 rs_form(op, r1, r3, b2, d2); \ 798 } \ 799 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \ 800 name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 801 } 802 803void Assembler::rs_form(Opcode op, Register r1, Register r3, Register b2, 804 const Disp d2) { 805 DCHECK(is_uint12(d2)); 806 emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | b2.code() * B12 | 807 d2); 808} 809 810// RS2 format: <insn> R1,M3,D2(B2) 811// +--------+----+----+----+-------------+ 812// | OpCode | R1 | M3 | B2 | D2 | 813// +--------+----+----+----+-------------+ 814// 0 8 12 16 20 31 815#define RS2_FORM_EMIT(name, op) \ 816 void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) { \ 817 rs_form(op, r1, m3, b2, d2); \ 818 } \ 819 void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \ 820 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 821 } 822 823void Assembler::rs_form(Opcode op, Register r1, Condition m3, Register b2, 824 const Disp d2) { 825 DCHECK(is_uint12(d2)); 826 emit4bytes(op * B24 | r1.code() * B20 | m3 * B16 | b2.code() * B12 | d2); 827} 828 829// RSI format: <insn> R1,R3,I2 830// +--------+----+----+------------------+ 831// | OpCode | R1 | R3 | RI2 | 832// +--------+----+----+------------------+ 833// 0 8 12 16 31 834#define RSI_FORM_EMIT(name, op) \ 835 void Assembler::name(Register r1, Register r3, const Operand& i2) { \ 836 rsi_form(op, r1, r3, i2); \ 837 } 838 839void Assembler::rsi_form(Opcode op, Register r1, Register r3, 840 const Operand& i2) { 841 DCHECK(is_uint8(op)); 842 DCHECK(is_uint16(i2.imm_)); 843 emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | (i2.imm_ & 0xFFFF)); 844} 845 846// RSL format: <insn> R1,R3,D2(B2) 847// +--------+----+----+----+-------------+--------+--------+ 848// | OpCode | L1 | | B2 | D2 | | OpCode | 849// +--------+----+----+----+-------------+--------+--------+ 850// 0 8 12 16 20 32 40 47 851#define RSL_FORM_EMIT(name, op) \ 852 void Assembler::name(Length l1, Register b2, Disp d2) { \ 853 rsl_form(op, l1, b2, d2); \ 854 } 855 856void Assembler::rsl_form(Opcode op, Length l1, Register b2, Disp d2) { 857 DCHECK(is_uint16(op)); 858 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 859 (static_cast<uint64_t>(l1)) * B36 | 860 (static_cast<uint64_t>(b2.code())) * B28 | 861 (static_cast<uint64_t>(d2)) * B16 | 862 (static_cast<uint64_t>(op & 0x00FF)); 863 emit6bytes(code); 864} 865 866// RSY1 format: <insn> R1,R3,D2(B2) 867// +--------+----+----+----+-------------+--------+--------+ 868// | OpCode | R1 | R3 | B2 | DL2 | DH2 | OpCode | 869// +--------+----+----+----+-------------+--------+--------+ 870// 0 8 12 16 20 32 40 47 871#define RSY1_FORM_EMIT(name, op) \ 872 void Assembler::name(Register r1, Register r3, Register b2, Disp d2) { \ 873 rsy_form(op, r1, r3, b2, d2); \ 874 } \ 875 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \ 876 name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 877 } 878 879void Assembler::rsy_form(Opcode op, Register r1, Register r3, Register b2, 880 const Disp d2) { 881 DCHECK(is_int20(d2)); 882 DCHECK(is_uint16(op)); 883 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 884 (static_cast<uint64_t>(r1.code())) * B36 | 885 (static_cast<uint64_t>(r3.code())) * B32 | 886 (static_cast<uint64_t>(b2.code())) * B28 | 887 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 888 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 889 (static_cast<uint64_t>(op & 0x00FF)); 890 emit6bytes(code); 891} 892 893// RSY2 format: <insn> R1,M3,D2(B2) 894// +--------+----+----+----+-------------+--------+--------+ 895// | OpCode | R1 | M3 | B2 | DL2 | DH2 | OpCode | 896// +--------+----+----+----+-------------+--------+--------+ 897// 0 8 12 16 20 32 40 47 898#define RSY2_FORM_EMIT(name, op) \ 899 void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) { \ 900 rsy_form(op, r1, m3, b2, d2); \ 901 } \ 902 void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \ 903 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \ 904 } 905 906void Assembler::rsy_form(Opcode op, Register r1, Condition m3, Register b2, 907 const Disp d2) { 908 DCHECK(is_int20(d2)); 909 DCHECK(is_uint16(op)); 910 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 911 (static_cast<uint64_t>(r1.code())) * B36 | 912 (static_cast<uint64_t>(m3)) * B32 | 913 (static_cast<uint64_t>(b2.code())) * B28 | 914 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 915 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 916 (static_cast<uint64_t>(op & 0x00FF)); 917 emit6bytes(code); 918} 919 920// RXE format: <insn> R1,D2(X2,B2) 921// +--------+----+----+----+-------------+--------+--------+ 922// | OpCode | R1 | X2 | B2 | D2 |////////| OpCode | 923// +--------+----+----+----+-------------+--------+--------+ 924// 0 8 12 16 20 32 40 47 925#define RXE_FORM_EMIT(name, op) \ 926 void Assembler::name(Register r1, Register x2, Register b2, Disp d2) { \ 927 rxe_form(op, r1, x2, b2, d2); \ 928 } \ 929 void Assembler::name(Register r1, const MemOperand& opnd) { \ 930 name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(), \ 931 opnd.getDisplacement()); \ 932 } 933 934void Assembler::rxe_form(Opcode op, Register r1, Register x2, Register b2, 935 Disp d2) { 936 DCHECK(is_uint12(d2)); 937 DCHECK(is_uint16(op)); 938 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 939 (static_cast<uint64_t>(r1.code())) * B36 | 940 (static_cast<uint64_t>(x2.code())) * B32 | 941 (static_cast<uint64_t>(b2.code())) * B28 | 942 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 943 (static_cast<uint64_t>(op & 0x00FF)); 944 emit6bytes(code); 945} 946 947// RXY format: <insn> R1,D2(X2,B2) 948// +--------+----+----+----+-------------+--------+--------+ 949// | OpCode | R1 | X2 | B2 | DL2 | DH2 | OpCode | 950// +--------+----+----+----+-------------+--------+--------+ 951// 0 8 12 16 20 32 36 40 47 952#define RXY_FORM_EMIT(name, op) \ 953 void Assembler::name(Register r1, Register x2, Register b2, Disp d2) { \ 954 rxy_form(op, r1, x2, b2, d2); \ 955 } \ 956 void Assembler::name(Register r1, const MemOperand& opnd) { \ 957 name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(), \ 958 opnd.getDisplacement()); \ 959 } 960 961void Assembler::rxy_form(Opcode op, Register r1, Register x2, Register b2, 962 Disp d2) { 963 DCHECK(is_int20(d2)); 964 DCHECK(is_uint16(op)); 965 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 966 (static_cast<uint64_t>(r1.code())) * B36 | 967 (static_cast<uint64_t>(x2.code())) * B32 | 968 (static_cast<uint64_t>(b2.code())) * B28 | 969 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 970 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 971 (static_cast<uint64_t>(op & 0x00FF)); 972 emit6bytes(code); 973} 974 975void Assembler::rxy_form(Opcode op, DoubleRegister r1, Register x2, Register b2, 976 Disp d2) { 977 DCHECK(is_int20(d2)); 978 DCHECK(is_uint16(op)); 979 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 980 (static_cast<uint64_t>(r1.code())) * B36 | 981 (static_cast<uint64_t>(x2.code())) * B32 | 982 (static_cast<uint64_t>(b2.code())) * B28 | 983 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 | 984 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 | 985 (static_cast<uint64_t>(op & 0x00FF)); 986 emit6bytes(code); 987} 988 989// RRS format: <insn> R1,R2,M3,D4(B4) 990// +--------+----+----+----+-------------+----+---+--------+ 991// | OpCode | R1 | R2 | B4 | D4 | M3 |///| OpCode | 992// +--------+----+----+----+-------------+----+---+--------+ 993// 0 8 12 16 20 32 36 40 47 994#define RRS_FORM_EMIT(name, op) \ 995 void Assembler::name(Register r1, Register r2, Register b4, Disp d4, \ 996 Condition m3) { \ 997 rrs_form(op, r1, r2, b4, d4, m3); \ 998 } \ 999 void Assembler::name(Register r1, Register r2, Condition m3, \ 1000 const MemOperand& opnd) { \ 1001 name(r1, r2, opnd.getBaseRegister(), opnd.getDisplacement(), m3); \ 1002 } 1003 1004void Assembler::rrs_form(Opcode op, Register r1, Register r2, Register b4, 1005 Disp d4, Condition m3) { 1006 DCHECK(is_uint12(d4)); 1007 DCHECK(is_uint16(op)); 1008 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 1009 (static_cast<uint64_t>(r1.code())) * B36 | 1010 (static_cast<uint64_t>(r2.code())) * B32 | 1011 (static_cast<uint64_t>(b4.code())) * B28 | 1012 (static_cast<uint64_t>(d4)) * B16 | 1013 (static_cast<uint64_t>(m3)) << 12 | 1014 (static_cast<uint64_t>(op & 0x00FF)); 1015 emit6bytes(code); 1016} 1017 1018// RIS format: <insn> R1,I2,M3,D4(B4) 1019// +--------+----+----+----+-------------+--------+--------+ 1020// | OpCode | R1 | M3 | B4 | D4 | I2 | OpCode | 1021// +--------+----+----+----+-------------+--------+--------+ 1022// 0 8 12 16 20 32 40 47 1023#define RIS_FORM_EMIT(name, op) \ 1024 void Assembler::name(Register r1, Condition m3, Register b4, Disp d4, \ 1025 const Operand& i2) { \ 1026 ris_form(op, r1, m3, b4, d4, i2); \ 1027 } \ 1028 void Assembler::name(Register r1, const Operand& i2, Condition m3, \ 1029 const MemOperand& opnd) { \ 1030 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement(), i2); \ 1031 } 1032 1033void Assembler::ris_form(Opcode op, Register r1, Condition m3, Register b4, 1034 Disp d4, const Operand& i2) { 1035 DCHECK(is_uint12(d4)); 1036 DCHECK(is_uint16(op)); 1037 DCHECK(is_uint8(i2.imm_)); 1038 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 1039 (static_cast<uint64_t>(r1.code())) * B36 | 1040 (static_cast<uint64_t>(m3)) * B32 | 1041 (static_cast<uint64_t>(b4.code())) * B28 | 1042 (static_cast<uint64_t>(d4)) * B16 | 1043 (static_cast<uint64_t>(i2.imm_)) << 8 | 1044 (static_cast<uint64_t>(op & 0x00FF)); 1045 emit6bytes(code); 1046} 1047 1048// S format: <insn> D2(B2) 1049// +------------------+----+-------------+ 1050// | OpCode | B2 | D2 | 1051// +------------------+----+-------------+ 1052// 0 16 20 31 1053#define S_FORM_EMIT(name, op) \ 1054 void Assembler::name(Register b1, Disp d2) { s_form(op, b1, d2); } \ 1055 void Assembler::name(const MemOperand& opnd) { \ 1056 name(opnd.getBaseRegister(), opnd.getDisplacement()); \ 1057 } 1058 1059void Assembler::s_form(Opcode op, Register b1, Disp d2) { 1060 DCHECK(is_uint12(d2)); 1061 emit4bytes(op << 16 | b1.code() * B12 | d2); 1062} 1063 1064// SI format: <insn> D1(B1),I2 1065// +--------+---------+----+-------------+ 1066// | OpCode | I2 | B1 | D1 | 1067// +--------+---------+----+-------------+ 1068// 0 8 16 20 31 1069#define SI_FORM_EMIT(name, op) \ 1070 void Assembler::name(const Operand& i2, Register b1, Disp d1) { \ 1071 si_form(op, i2, b1, d1); \ 1072 } \ 1073 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \ 1074 name(i2, opnd.getBaseRegister(), opnd.getDisplacement()); \ 1075 } 1076 1077void Assembler::si_form(Opcode op, const Operand& i2, Register b1, Disp d1) { 1078 emit4bytes((op & 0x00FF) << 24 | i2.imm_ * B16 | b1.code() * B12 | d1); 1079} 1080 1081// SIY format: <insn> D1(B1),I2 1082// +--------+---------+----+-------------+--------+--------+ 1083// | OpCode | I2 | B1 | DL1 | DH1 | OpCode | 1084// +--------+---------+----+-------------+--------+--------+ 1085// 0 8 16 20 32 36 40 47 1086#define SIY_FORM_EMIT(name, op) \ 1087 void Assembler::name(const Operand& i2, Register b1, Disp d1) { \ 1088 siy_form(op, i2, b1, d1); \ 1089 } \ 1090 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \ 1091 name(i2, opnd.getBaseRegister(), opnd.getDisplacement()); \ 1092 } 1093 1094void Assembler::siy_form(Opcode op, const Operand& i2, Register b1, Disp d1) { 1095 DCHECK(is_uint20(d1)); 1096 DCHECK(is_uint16(op)); 1097 DCHECK(is_uint8(i2.imm_)); 1098 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 1099 (static_cast<uint64_t>(i2.imm_)) * B32 | 1100 (static_cast<uint64_t>(b1.code())) * B28 | 1101 (static_cast<uint64_t>(d1 & 0x0FFF)) * B16 | 1102 (static_cast<uint64_t>(d1 & 0x0FF000)) >> 4 | 1103 (static_cast<uint64_t>(op & 0x00FF)); 1104 emit6bytes(code); 1105} 1106 1107// SIL format: <insn> D1(B1),I2 1108// +------------------+----+-------------+-----------------+ 1109// | OpCode | B1 | D1 | I2 | 1110// +------------------+----+-------------+-----------------+ 1111// 0 16 20 32 47 1112#define SIL_FORM_EMIT(name, op) \ 1113 void Assembler::name(Register b1, Disp d1, const Operand& i2) { \ 1114 sil_form(op, b1, d1, i2); \ 1115 } \ 1116 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \ 1117 name(opnd.getBaseRegister(), opnd.getDisplacement(), i2); \ 1118 } 1119 1120void Assembler::sil_form(Opcode op, Register b1, Disp d1, const Operand& i2) { 1121 DCHECK(is_uint12(d1)); 1122 DCHECK(is_uint16(op)); 1123 DCHECK(is_uint16(i2.imm_)); 1124 uint64_t code = (static_cast<uint64_t>(op)) * B32 | 1125 (static_cast<uint64_t>(b1.code())) * B28 | 1126 (static_cast<uint64_t>(d1)) * B16 | 1127 (static_cast<uint64_t>(i2.imm_)); 1128 emit6bytes(code); 1129} 1130 1131// RXF format: <insn> R1,R3,D2(X2,B2) 1132// +--------+----+----+----+-------------+----+---+--------+ 1133// | OpCode | R3 | X2 | B2 | D2 | R1 |///| OpCode | 1134// +--------+----+----+----+-------------+----+---+--------+ 1135// 0 8 12 16 20 32 36 40 47 1136#define RXF_FORM_EMIT(name, op) \ 1137 void Assembler::name(Register r1, Register r3, Register b2, Register x2, \ 1138 Disp d2) { \ 1139 rxf_form(op, r1, r3, b2, x2, d2); \ 1140 } \ 1141 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \ 1142 name(r1, r3, opnd.getBaseRegister(), opnd.getIndexRegister(), \ 1143 opnd.getDisplacement()); \ 1144 } 1145 1146void Assembler::rxf_form(Opcode op, Register r1, Register r3, Register b2, 1147 Register x2, Disp d2) { 1148 DCHECK(is_uint12(d2)); 1149 DCHECK(is_uint16(op)); 1150 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 | 1151 (static_cast<uint64_t>(r3.code())) * B36 | 1152 (static_cast<uint64_t>(x2.code())) * B32 | 1153 (static_cast<uint64_t>(b2.code())) * B28 | 1154 (static_cast<uint64_t>(d2)) * B16 | 1155 (static_cast<uint64_t>(r1.code())) * B12 | 1156 (static_cast<uint64_t>(op & 0x00FF)); 1157 emit6bytes(code); 1158} 1159 1160// SS1 format: <insn> D1(L,B1),D2(B3) 1161// +--------+----+----+----+-------------+----+------------+ 1162// | OpCode | L | B1 | D1 | B2 | D2 | 1163// +--------+----+----+----+-------------+----+------------+ 1164// 0 8 12 16 20 32 36 47 1165#define SS1_FORM_EMIT(name, op) \ 1166 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l) { \ 1167 ss_form(op, l, b1, d1, b2, d2); \ 1168 } \ 1169 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \ 1170 Length length) { \ 1171 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1172 opnd2.getBaseRegister(), opnd2.getDisplacement(), length); \ 1173 } 1174 1175void Assembler::ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2, 1176 Disp d2) { 1177 DCHECK(is_uint12(d2)); 1178 DCHECK(is_uint12(d1)); 1179 DCHECK(is_uint8(op)); 1180 DCHECK(is_uint8(l)); 1181 uint64_t code = 1182 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l)) * B32 | 1183 (static_cast<uint64_t>(b1.code())) * B28 | 1184 (static_cast<uint64_t>(d1)) * B16 | 1185 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2)); 1186 emit6bytes(code); 1187} 1188 1189// SS2 format: <insn> D1(L1,B1), D2(L3,B3) 1190// +--------+----+----+----+-------------+----+------------+ 1191// | OpCode | L1 | L2 | B1 | D1 | B2 | D2 | 1192// +--------+----+----+----+-------------+----+------------+ 1193// 0 8 12 16 20 32 36 47 1194#define SS2_FORM_EMIT(name, op) \ 1195 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l1, \ 1196 Length l2) { \ 1197 ss_form(op, l1, l2, b1, d1, b2, d2); \ 1198 } \ 1199 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \ 1200 Length length1, Length length2) { \ 1201 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1202 opnd2.getBaseRegister(), opnd2.getDisplacement(), length1, length2); \ 1203 } 1204 1205void Assembler::ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1, 1206 Register b2, Disp d2) { 1207 DCHECK(is_uint12(d2)); 1208 DCHECK(is_uint12(d1)); 1209 DCHECK(is_uint8(op)); 1210 DCHECK(is_uint4(l2)); 1211 DCHECK(is_uint4(l1)); 1212 uint64_t code = 1213 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 | 1214 (static_cast<uint64_t>(l2)) * B32 | 1215 (static_cast<uint64_t>(b1.code())) * B28 | 1216 (static_cast<uint64_t>(d1)) * B16 | 1217 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2)); 1218 emit6bytes(code); 1219} 1220 1221// SS3 format: <insn> D1(L1,B1), D2(I3,B2) 1222// +--------+----+----+----+-------------+----+------------+ 1223// | OpCode | L1 | I3 | B1 | D1 | B2 | D2 | 1224// +--------+----+----+----+-------------+----+------------+ 1225// 0 8 12 16 20 32 36 47 1226#define SS3_FORM_EMIT(name, op) \ 1227 void Assembler::name(const Operand& i3, Register b1, Disp d1, Register b2, \ 1228 Disp d2, Length l1) { \ 1229 ss_form(op, l1, i3, b1, d1, b2, d2); \ 1230 } \ 1231 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \ 1232 Length length) { \ 1233 DCHECK(false); \ 1234 } 1235void Assembler::ss_form(Opcode op, Length l1, const Operand& i3, Register b1, 1236 Disp d1, Register b2, Disp d2) { 1237 DCHECK(is_uint12(d2)); 1238 DCHECK(is_uint12(d1)); 1239 DCHECK(is_uint8(op)); 1240 DCHECK(is_uint4(l1)); 1241 DCHECK(is_uint4(i3.imm_)); 1242 uint64_t code = 1243 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 | 1244 (static_cast<uint64_t>(i3.imm_)) * B32 | 1245 (static_cast<uint64_t>(b1.code())) * B28 | 1246 (static_cast<uint64_t>(d1)) * B16 | 1247 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2)); 1248 emit6bytes(code); 1249} 1250 1251// SS4 format: <insn> D1(R1,B1), D2(R3,B2) 1252// +--------+----+----+----+-------------+----+------------+ 1253// | OpCode | R1 | R3 | B1 | D1 | B2 | D2 | 1254// +--------+----+----+----+-------------+----+------------+ 1255// 0 8 12 16 20 32 36 47 1256#define SS4_FORM_EMIT(name, op) \ 1257 void Assembler::name(Register r1, Register r3, Register b1, Disp d1, \ 1258 Register b2, Disp d2) { \ 1259 ss_form(op, r1, r3, b1, d1, b2, d2); \ 1260 } \ 1261 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \ 1262 DCHECK(false); \ 1263 } 1264void Assembler::ss_form(Opcode op, Register r1, Register r3, Register b1, 1265 Disp d1, Register b2, Disp d2) { 1266 DCHECK(is_uint12(d2)); 1267 DCHECK(is_uint12(d1)); 1268 DCHECK(is_uint8(op)); 1269 uint64_t code = (static_cast<uint64_t>(op)) * B40 | 1270 (static_cast<uint64_t>(r1.code())) * B36 | 1271 (static_cast<uint64_t>(r3.code())) * B32 | 1272 (static_cast<uint64_t>(b1.code())) * B28 | 1273 (static_cast<uint64_t>(d1)) * B16 | 1274 (static_cast<uint64_t>(b2.code())) * B12 | 1275 (static_cast<uint64_t>(d2)); 1276 emit6bytes(code); 1277} 1278 1279// SS5 format: <insn> D1(R1,B1), D2(R3,B2) 1280// +--------+----+----+----+-------------+----+------------+ 1281// | OpCode | R1 | R3 | B2 | D2 | B4 | D4 | 1282// +--------+----+----+----+-------------+----+------------+ 1283// 0 8 12 16 20 32 36 47 1284#define SS5_FORM_EMIT(name, op) \ 1285 void Assembler::name(Register r1, Register r3, Register b2, Disp d2, \ 1286 Register b4, Disp d4) { \ 1287 ss_form(op, r1, r3, b2, d2, b4, d4); /*SS5 use the same form as SS4*/ \ 1288 } \ 1289 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \ 1290 DCHECK(false); \ 1291 } 1292 1293#define SS6_FORM_EMIT(name, op) SS1_FORM_EMIT(name, op) 1294 1295// SSE format: <insn> D1(B1),D2(B2) 1296// +------------------+----+-------------+----+------------+ 1297// | OpCode | B1 | D1 | B2 | D2 | 1298// +------------------+----+-------------+----+------------+ 1299// 0 8 12 16 20 32 36 47 1300#define SSE_FORM_EMIT(name, op) \ 1301 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2) { \ 1302 sse_form(op, b1, d1, b2, d2); \ 1303 } \ 1304 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \ 1305 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1306 opnd2.getBaseRegister(), opnd2.getDisplacement()); \ 1307 } 1308void Assembler::sse_form(Opcode op, Register b1, Disp d1, Register b2, 1309 Disp d2) { 1310 DCHECK(is_uint12(d2)); 1311 DCHECK(is_uint12(d1)); 1312 DCHECK(is_uint16(op)); 1313 uint64_t code = (static_cast<uint64_t>(op)) * B32 | 1314 (static_cast<uint64_t>(b1.code())) * B28 | 1315 (static_cast<uint64_t>(d1)) * B16 | 1316 (static_cast<uint64_t>(b2.code())) * B12 | 1317 (static_cast<uint64_t>(d2)); 1318 emit6bytes(code); 1319} 1320 1321// SSF format: <insn> R3, D1(B1),D2(B2),R3 1322// +--------+----+----+----+-------------+----+------------+ 1323// | OpCode | R3 |OpCd| B1 | D1 | B2 | D2 | 1324// +--------+----+----+----+-------------+----+------------+ 1325// 0 8 12 16 20 32 36 47 1326#define SSF_FORM_EMIT(name, op) \ 1327 void Assembler::name(Register r3, Register b1, Disp d1, Register b2, \ 1328 Disp d2) { \ 1329 ssf_form(op, r3, b1, d1, b2, d2); \ 1330 } \ 1331 void Assembler::name(Register r3, const MemOperand& opnd1, \ 1332 const MemOperand& opnd2) { \ 1333 name(r3, opnd1.getBaseRegister(), opnd1.getDisplacement(), \ 1334 opnd2.getBaseRegister(), opnd2.getDisplacement()); \ 1335 } 1336 1337void Assembler::ssf_form(Opcode op, Register r3, Register b1, Disp d1, 1338 Register b2, Disp d2) { 1339 DCHECK(is_uint12(d2)); 1340 DCHECK(is_uint12(d1)); 1341 DCHECK(is_uint12(op)); 1342 uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 | 1343 (static_cast<uint64_t>(r3.code())) * B36 | 1344 (static_cast<uint64_t>(op & 0x00F)) * B32 | 1345 (static_cast<uint64_t>(b1.code())) * B28 | 1346 (static_cast<uint64_t>(d1)) * B16 | 1347 (static_cast<uint64_t>(b2.code())) * B12 | 1348 (static_cast<uint64_t>(d2)); 1349 emit6bytes(code); 1350} 1351 1352// RRF1 format: <insn> R1,R2,R3 1353// +------------------+----+----+----+----+ 1354// | OpCode | R3 | | R1 | R2 | 1355// +------------------+----+----+----+----+ 1356// 0 16 20 24 28 31 1357#define RRF1_FORM_EMIT(name, op) \ 1358 void Assembler::name(Register r1, Register r2, Register r3) { \ 1359 rrf1_form(op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code()); \ 1360 } 1361 1362void Assembler::rrf1_form(Opcode op, Register r1, Register r2, Register r3) { 1363 uint32_t code = op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code(); 1364 emit4bytes(code); 1365} 1366 1367void Assembler::rrf1_form(uint32_t code) { emit4bytes(code); } 1368 1369// RRF2 format: <insn> R1,R2,M3 1370// +------------------+----+----+----+----+ 1371// | OpCode | M3 | | R1 | R2 | 1372// +------------------+----+----+----+----+ 1373// 0 16 20 24 28 31 1374#define RRF2_FORM_EMIT(name, op) \ 1375 void Assembler::name(Condition m3, Register r1, Register r2) { \ 1376 rrf2_form(op << 16 | m3 * B12 | r1.code() * B4 | r2.code()); \ 1377 } 1378 1379void Assembler::rrf2_form(uint32_t code) { emit4bytes(code); } 1380 1381// RRF3 format: <insn> R1,R2,R3,M4 1382// +------------------+----+----+----+----+ 1383// | OpCode | R3 | M4 | R1 | R2 | 1384// +------------------+----+----+----+----+ 1385// 0 16 20 24 28 31 1386#define RRF3_FORM_EMIT(name, op) \ 1387 void Assembler::name(Register r3, Conition m4, Register r1, Register r2) { \ 1388 rrf3_form(op << 16 | r3.code() * B12 | m4 * B8 | r1.code() * B4 | \ 1389 r2.code()); \ 1390 } 1391 1392void Assembler::rrf3_form(uint32_t code) { emit4bytes(code); } 1393 1394// RRF-e format: <insn> R1,M3,R2,M4 1395// +------------------+----+----+----+----+ 1396// | OpCode | M3 | M4 | R1 | R2 | 1397// +------------------+----+----+----+----+ 1398// 0 16 20 24 28 31 1399void Assembler::rrfe_form(Opcode op, Condition m3, Condition m4, Register r1, 1400 Register r2) { 1401 uint32_t code = op << 16 | m3 * B12 | m4 * B8 | r1.code() * B4 | r2.code(); 1402 emit4bytes(code); 1403} 1404 1405// end of S390 Instruction generation 1406 1407// start of S390 instruction 1408RX_FORM_EMIT(bc, BC) 1409RR_FORM_EMIT(bctr, BCTR) 1410RXE_FORM_EMIT(ceb, CEB) 1411RRE_FORM_EMIT(cefbr, CEFBR) 1412SS1_FORM_EMIT(ed, ED) 1413RX_FORM_EMIT(ex, EX) 1414RRE_FORM_EMIT(flogr, FLOGR) 1415RRE_FORM_EMIT(lcgr, LCGR) 1416RR_FORM_EMIT(lcr, LCR) 1417RX_FORM_EMIT(le_z, LE) 1418RXY_FORM_EMIT(ley, LEY) 1419RIL1_FORM_EMIT(llihf, LLIHF) 1420RIL1_FORM_EMIT(llilf, LLILF) 1421RRE_FORM_EMIT(lngr, LNGR) 1422RR_FORM_EMIT(lnr, LNR) 1423RSY1_FORM_EMIT(loc, LOC) 1424RXY_FORM_EMIT(lrv, LRV) 1425RXY_FORM_EMIT(lrvh, LRVH) 1426SS1_FORM_EMIT(mvn, MVN) 1427SS1_FORM_EMIT(nc, NC) 1428SI_FORM_EMIT(ni, NI) 1429RIL1_FORM_EMIT(nihf, NIHF) 1430RIL1_FORM_EMIT(nilf, NILF) 1431RI1_FORM_EMIT(nilh, NILH) 1432RI1_FORM_EMIT(nill, NILL) 1433RIL1_FORM_EMIT(oihf, OIHF) 1434RIL1_FORM_EMIT(oilf, OILF) 1435RI1_FORM_EMIT(oill, OILL) 1436RRE_FORM_EMIT(popcnt, POPCNT_Z) 1437RIL1_FORM_EMIT(slfi, SLFI) 1438RXY_FORM_EMIT(slgf, SLGF) 1439RIL1_FORM_EMIT(slgfi, SLGFI) 1440RXY_FORM_EMIT(strv, STRV) 1441RI1_FORM_EMIT(tmll, TMLL) 1442SS1_FORM_EMIT(tr, TR) 1443S_FORM_EMIT(ts, TS) 1444RIL1_FORM_EMIT(xihf, XIHF) 1445RIL1_FORM_EMIT(xilf, XILF) 1446 1447// ------------------------- 1448// Load Address Instructions 1449// ------------------------- 1450// Load Address Register-Storage 1451void Assembler::la(Register r1, const MemOperand& opnd) { 1452 rx_form(LA, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1453} 1454 1455// Load Address Register-Storage 1456void Assembler::lay(Register r1, const MemOperand& opnd) { 1457 rxy_form(LAY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1458} 1459 1460// Load Address Relative Long 1461void Assembler::larl(Register r1, const Operand& opnd) { 1462 ril_form(LARL, r1, opnd); 1463} 1464 1465// Load Address Relative Long 1466void Assembler::larl(Register r1, Label* l) { 1467 larl(r1, Operand(branch_offset(l))); 1468} 1469 1470// ----------------- 1471// Load Instructions 1472// ----------------- 1473// Load Byte Register-Storage (32<-8) 1474void Assembler::lb(Register r, const MemOperand& src) { 1475 rxy_form(LB, r, src.rx(), src.rb(), src.offset()); 1476} 1477 1478// Load Byte Register-Register (32<-8) 1479void Assembler::lbr(Register r1, Register r2) { rre_form(LBR, r1, r2); } 1480 1481// Load Byte Register-Storage (64<-8) 1482void Assembler::lgb(Register r, const MemOperand& src) { 1483 rxy_form(LGB, r, src.rx(), src.rb(), src.offset()); 1484} 1485 1486// Load Byte Register-Register (64<-8) 1487void Assembler::lgbr(Register r1, Register r2) { rre_form(LGBR, r1, r2); } 1488 1489// Load Halfword Register-Storage (32<-16) 1490void Assembler::lh(Register r, const MemOperand& src) { 1491 rx_form(LH, r, src.rx(), src.rb(), src.offset()); 1492} 1493 1494// Load Halfword Register-Storage (32<-16) 1495void Assembler::lhy(Register r, const MemOperand& src) { 1496 rxy_form(LHY, r, src.rx(), src.rb(), src.offset()); 1497} 1498 1499// Load Halfword Register-Register (32<-16) 1500void Assembler::lhr(Register r1, Register r2) { rre_form(LHR, r1, r2); } 1501 1502// Load Halfword Register-Storage (64<-16) 1503void Assembler::lgh(Register r, const MemOperand& src) { 1504 rxy_form(LGH, r, src.rx(), src.rb(), src.offset()); 1505} 1506 1507// Load Halfword Register-Register (64<-16) 1508void Assembler::lghr(Register r1, Register r2) { rre_form(LGHR, r1, r2); } 1509 1510// Load Register-Storage (32) 1511void Assembler::l(Register r, const MemOperand& src) { 1512 rx_form(L, r, src.rx(), src.rb(), src.offset()); 1513} 1514 1515// Load Register-Storage (32) 1516void Assembler::ly(Register r, const MemOperand& src) { 1517 rxy_form(LY, r, src.rx(), src.rb(), src.offset()); 1518} 1519 1520// Load Register-Register (32) 1521void Assembler::lr(Register r1, Register r2) { rr_form(LR, r1, r2); } 1522 1523// Load Register-Storage (64) 1524void Assembler::lg(Register r, const MemOperand& src) { 1525 rxy_form(LG, r, src.rx(), src.rb(), src.offset()); 1526} 1527 1528// Load Register-Register (64) 1529void Assembler::lgr(Register r1, Register r2) { rre_form(LGR, r1, r2); } 1530 1531// Load Register-Storage (64<-32) 1532void Assembler::lgf(Register r, const MemOperand& src) { 1533 rxy_form(LGF, r, src.rx(), src.rb(), src.offset()); 1534} 1535 1536// Load Sign Extended Register-Register (64<-32) 1537void Assembler::lgfr(Register r1, Register r2) { rre_form(LGFR, r1, r2); } 1538 1539// Load Halfword Immediate (32) 1540void Assembler::lhi(Register r, const Operand& imm) { ri_form(LHI, r, imm); } 1541 1542// Load Halfword Immediate (64) 1543void Assembler::lghi(Register r, const Operand& imm) { ri_form(LGHI, r, imm); } 1544 1545// -------------------------- 1546// Load And Test Instructions 1547// -------------------------- 1548// Load and Test Register-Storage (32) 1549void Assembler::lt_z(Register r1, const MemOperand& opnd) { 1550 rxy_form(LT, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1551} 1552 1553// Load and Test Register-Storage (64) 1554void Assembler::ltg(Register r1, const MemOperand& opnd) { 1555 rxy_form(LTG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1556} 1557 1558// Load and Test Register-Register (32) 1559void Assembler::ltr(Register r1, Register r2) { rr_form(LTR, r1, r2); } 1560 1561// Load and Test Register-Register (64) 1562void Assembler::ltgr(Register r1, Register r2) { rre_form(LTGR, r1, r2); } 1563 1564// Load and Test Register-Register (64<-32) 1565void Assembler::ltgfr(Register r1, Register r2) { rre_form(LTGFR, r1, r2); } 1566 1567// ------------------------- 1568// Load Logical Instructions 1569// ------------------------- 1570// Load Logical Character (32) - loads a byte and zero ext. 1571void Assembler::llc(Register r1, const MemOperand& opnd) { 1572 rxy_form(LLC, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1573} 1574 1575// Load Logical Character (64) - loads a byte and zero ext. 1576void Assembler::llgc(Register r1, const MemOperand& opnd) { 1577 rxy_form(LLGC, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1578} 1579 1580// Load Logical halfword Register-Storage (64<-32) 1581void Assembler::llgf(Register r1, const MemOperand& opnd) { 1582 rxy_form(LLGF, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1583} 1584 1585// Load Logical Register-Register (64<-32) 1586void Assembler::llgfr(Register r1, Register r2) { rre_form(LLGFR, r1, r2); } 1587 1588// Load Logical halfword Register-Storage (32) 1589void Assembler::llh(Register r1, const MemOperand& opnd) { 1590 rxy_form(LLH, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1591} 1592 1593// Load Logical halfword Register-Storage (64) 1594void Assembler::llgh(Register r1, const MemOperand& opnd) { 1595 rxy_form(LLGH, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1596} 1597 1598// Load Logical halfword Register-Register (32) 1599void Assembler::llhr(Register r1, Register r2) { rre_form(LLHR, r1, r2); } 1600 1601// Load Logical halfword Register-Register (64) 1602void Assembler::llghr(Register r1, Register r2) { rre_form(LLGHR, r1, r2); } 1603 1604// ------------------- 1605// Branch Instructions 1606// ------------------- 1607// Branch and Save 1608void Assembler::basr(Register r1, Register r2) { rr_form(BASR, r1, r2); } 1609 1610// Indirect Conditional Branch via register 1611void Assembler::bcr(Condition m, Register target) { rr_form(BCR, m, target); } 1612 1613// Branch on Count (32) 1614void Assembler::bct(Register r, const MemOperand& opnd) { 1615 rx_form(BCT, r, opnd.rx(), opnd.rb(), opnd.offset()); 1616} 1617 1618// Branch on Count (64) 1619void Assembler::bctg(Register r, const MemOperand& opnd) { 1620 rxy_form(BCTG, r, opnd.rx(), opnd.rb(), opnd.offset()); 1621} 1622 1623// Branch Relative and Save (32) 1624void Assembler::bras(Register r, const Operand& opnd) { 1625 ri_form(BRAS, r, opnd); 1626} 1627 1628// Branch Relative and Save (64) 1629void Assembler::brasl(Register r, const Operand& opnd) { 1630 ril_form(BRASL, r, opnd); 1631} 1632 1633// Branch relative on Condition (32) 1634void Assembler::brc(Condition c, const Operand& opnd) { 1635 // BRC actually encodes # of halfwords, so divide by 2. 1636 int16_t numHalfwords = static_cast<int16_t>(opnd.immediate()) / 2; 1637 Operand halfwordOp = Operand(numHalfwords); 1638 halfwordOp.setBits(16); 1639 ri_form(BRC, c, halfwordOp); 1640} 1641 1642// Branch Relative on Condition (64) 1643void Assembler::brcl(Condition c, const Operand& opnd, bool isCodeTarget) { 1644 Operand halfwordOp = opnd; 1645 // Operand for code targets will be index to code_targets_ 1646 if (!isCodeTarget) { 1647 // BRCL actually encodes # of halfwords, so divide by 2. 1648 int32_t numHalfwords = static_cast<int32_t>(opnd.immediate()) / 2; 1649 halfwordOp = Operand(numHalfwords); 1650 } 1651 ril_form(BRCL, c, halfwordOp); 1652} 1653 1654// Branch On Count (32) 1655void Assembler::brct(Register r1, const Operand& imm) { 1656 // BRCT encodes # of halfwords, so divide by 2. 1657 int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2; 1658 Operand halfwordOp = Operand(numHalfwords); 1659 halfwordOp.setBits(16); 1660 ri_form(BRCT, r1, halfwordOp); 1661} 1662 1663// Branch On Count (32) 1664void Assembler::brctg(Register r1, const Operand& imm) { 1665 // BRCTG encodes # of halfwords, so divide by 2. 1666 int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2; 1667 Operand halfwordOp = Operand(numHalfwords); 1668 halfwordOp.setBits(16); 1669 ri_form(BRCTG, r1, halfwordOp); 1670} 1671 1672// -------------------- 1673// Compare Instructions 1674// -------------------- 1675// Compare Register-Storage (32) 1676void Assembler::c(Register r, const MemOperand& opnd) { 1677 rx_form(C, r, opnd.rx(), opnd.rb(), opnd.offset()); 1678} 1679 1680// Compare Register-Storage (32) 1681void Assembler::cy(Register r, const MemOperand& opnd) { 1682 rxy_form(CY, r, opnd.rx(), opnd.rb(), opnd.offset()); 1683} 1684 1685// Compare Register-Register (32) 1686void Assembler::cr_z(Register r1, Register r2) { rr_form(CR, r1, r2); } 1687 1688// Compare Register-Storage (64) 1689void Assembler::cg(Register r, const MemOperand& opnd) { 1690 rxy_form(CG, r, opnd.rx(), opnd.rb(), opnd.offset()); 1691} 1692 1693// Compare Register-Register (64) 1694void Assembler::cgr(Register r1, Register r2) { rre_form(CGR, r1, r2); } 1695 1696// Compare Halfword Register-Storage (32) 1697void Assembler::ch(Register r, const MemOperand& opnd) { 1698 rx_form(CH, r, opnd.rx(), opnd.rb(), opnd.offset()); 1699} 1700 1701// Compare Halfword Register-Storage (32) 1702void Assembler::chy(Register r, const MemOperand& opnd) { 1703 rxy_form(CHY, r, opnd.rx(), opnd.rb(), opnd.offset()); 1704} 1705 1706// Compare Halfword Immediate (32) 1707void Assembler::chi(Register r, const Operand& opnd) { ri_form(CHI, r, opnd); } 1708 1709// Compare Halfword Immediate (64) 1710void Assembler::cghi(Register r, const Operand& opnd) { 1711 ri_form(CGHI, r, opnd); 1712} 1713 1714// Compare Immediate (32) 1715void Assembler::cfi(Register r, const Operand& opnd) { ril_form(CFI, r, opnd); } 1716 1717// Compare Immediate (64) 1718void Assembler::cgfi(Register r, const Operand& opnd) { 1719 ril_form(CGFI, r, opnd); 1720} 1721 1722// ---------------------------- 1723// Compare Logical Instructions 1724// ---------------------------- 1725// Compare Logical Register-Storage (32) 1726void Assembler::cl(Register r, const MemOperand& opnd) { 1727 rx_form(CL, r, opnd.rx(), opnd.rb(), opnd.offset()); 1728} 1729 1730// Compare Logical Register-Storage (32) 1731void Assembler::cly(Register r, const MemOperand& opnd) { 1732 rxy_form(CLY, r, opnd.rx(), opnd.rb(), opnd.offset()); 1733} 1734 1735// Compare Logical Register-Register (32) 1736void Assembler::clr(Register r1, Register r2) { rr_form(CLR, r1, r2); } 1737 1738// Compare Logical Register-Storage (64) 1739void Assembler::clg(Register r, const MemOperand& opnd) { 1740 rxy_form(CLG, r, opnd.rx(), opnd.rb(), opnd.offset()); 1741} 1742 1743// Compare Logical Register-Register (64) 1744void Assembler::clgr(Register r1, Register r2) { rre_form(CLGR, r1, r2); } 1745 1746// Compare Logical Immediate (32) 1747void Assembler::clfi(Register r1, const Operand& i2) { ril_form(CLFI, r1, i2); } 1748 1749// Compare Logical Immediate (64<32) 1750void Assembler::clgfi(Register r1, const Operand& i2) { 1751 ril_form(CLGFI, r1, i2); 1752} 1753 1754// Compare Immediate (Mem - Imm) (8) 1755void Assembler::cli(const MemOperand& opnd, const Operand& imm) { 1756 si_form(CLI, imm, opnd.rb(), opnd.offset()); 1757} 1758 1759// Compare Immediate (Mem - Imm) (8) 1760void Assembler::cliy(const MemOperand& opnd, const Operand& imm) { 1761 siy_form(CLIY, imm, opnd.rb(), opnd.offset()); 1762} 1763 1764// Compare logical - mem to mem operation 1765void Assembler::clc(const MemOperand& opnd1, const MemOperand& opnd2, 1766 Length length) { 1767 ss_form(CLC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(), 1768 opnd2.getBaseRegister(), opnd2.getDisplacement()); 1769} 1770 1771// ---------------------------- 1772// Test Under Mask Instructions 1773// ---------------------------- 1774// Test Under Mask (Mem - Imm) (8) 1775void Assembler::tm(const MemOperand& opnd, const Operand& imm) { 1776 si_form(TM, imm, opnd.rb(), opnd.offset()); 1777} 1778 1779// Test Under Mask (Mem - Imm) (8) 1780void Assembler::tmy(const MemOperand& opnd, const Operand& imm) { 1781 siy_form(TMY, imm, opnd.rb(), opnd.offset()); 1782} 1783 1784// ------------------------------- 1785// Rotate and Insert Selected Bits 1786// ------------------------------- 1787// Rotate-And-Insert-Selected-Bits 1788void Assembler::risbg(Register dst, Register src, const Operand& startBit, 1789 const Operand& endBit, const Operand& shiftAmt, 1790 bool zeroBits) { 1791 // High tag the top bit of I4/EndBit to zero out any unselected bits 1792 if (zeroBits) 1793 rie_f_form(RISBG, dst, src, startBit, Operand(endBit.imm_ | 0x80), 1794 shiftAmt); 1795 else 1796 rie_f_form(RISBG, dst, src, startBit, endBit, shiftAmt); 1797} 1798 1799// Rotate-And-Insert-Selected-Bits 1800void Assembler::risbgn(Register dst, Register src, const Operand& startBit, 1801 const Operand& endBit, const Operand& shiftAmt, 1802 bool zeroBits) { 1803 // High tag the top bit of I4/EndBit to zero out any unselected bits 1804 if (zeroBits) 1805 rie_f_form(RISBGN, dst, src, startBit, Operand(endBit.imm_ | 0x80), 1806 shiftAmt); 1807 else 1808 rie_f_form(RISBGN, dst, src, startBit, endBit, shiftAmt); 1809} 1810 1811// --------------------------- 1812// Move Character Instructions 1813// --------------------------- 1814// Move charactor - mem to mem operation 1815void Assembler::mvc(const MemOperand& opnd1, const MemOperand& opnd2, 1816 uint32_t length) { 1817 ss_form(MVC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(), 1818 opnd2.getBaseRegister(), opnd2.getDisplacement()); 1819} 1820 1821// ----------------------- 1822// 32-bit Add Instructions 1823// ----------------------- 1824// Add Register-Storage (32) 1825void Assembler::a(Register r1, const MemOperand& opnd) { 1826 rx_form(A, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1827} 1828 1829// Add Register-Storage (32) 1830void Assembler::ay(Register r1, const MemOperand& opnd) { 1831 rxy_form(AY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1832} 1833 1834// Add Immediate (32) 1835void Assembler::afi(Register r1, const Operand& opnd) { 1836 ril_form(AFI, r1, opnd); 1837} 1838 1839// Add Halfword Register-Storage (32) 1840void Assembler::ah(Register r1, const MemOperand& opnd) { 1841 rx_form(AH, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1842} 1843 1844// Add Halfword Register-Storage (32) 1845void Assembler::ahy(Register r1, const MemOperand& opnd) { 1846 rxy_form(AHY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1847} 1848 1849// Add Halfword Immediate (32) 1850void Assembler::ahi(Register r1, const Operand& i2) { ri_form(AHI, r1, i2); } 1851 1852// Add Halfword Immediate (32) 1853void Assembler::ahik(Register r1, Register r3, const Operand& i2) { 1854 rie_form(AHIK, r1, r3, i2); 1855} 1856 1857// Add Register (32) 1858void Assembler::ar(Register r1, Register r2) { rr_form(AR, r1, r2); } 1859 1860// Add Register-Register-Register (32) 1861void Assembler::ark(Register r1, Register r2, Register r3) { 1862 rrf1_form(ARK, r1, r2, r3); 1863} 1864 1865// Add Storage-Imm (32) 1866void Assembler::asi(const MemOperand& opnd, const Operand& imm) { 1867 DCHECK(is_int8(imm.imm_)); 1868 DCHECK(is_int20(opnd.offset())); 1869 siy_form(ASI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset()); 1870} 1871 1872// ----------------------- 1873// 64-bit Add Instructions 1874// ----------------------- 1875// Add Register-Storage (64) 1876void Assembler::ag(Register r1, const MemOperand& opnd) { 1877 rxy_form(AG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1878} 1879 1880// Add Register-Storage (64<-32) 1881void Assembler::agf(Register r1, const MemOperand& opnd) { 1882 rxy_form(AGF, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1883} 1884 1885// Add Immediate (64) 1886void Assembler::agfi(Register r1, const Operand& opnd) { 1887 ril_form(ALFI, r1, opnd); 1888} 1889 1890// Add Register-Register (64<-32) 1891void Assembler::agfr(Register r1, Register r2) { rre_form(AGFR, r1, r2); } 1892 1893// Add Halfword Immediate (64) 1894void Assembler::aghi(Register r1, const Operand& i2) { ri_form(AGHI, r1, i2); } 1895 1896// Add Halfword Immediate (64) 1897void Assembler::aghik(Register r1, Register r3, const Operand& i2) { 1898 rie_form(AGHIK, r1, r3, i2); 1899} 1900 1901// Add Register (64) 1902void Assembler::agr(Register r1, Register r2) { rre_form(AGR, r1, r2); } 1903 1904// Add Register-Register-Register (64) 1905void Assembler::agrk(Register r1, Register r2, Register r3) { 1906 rrf1_form(AGRK, r1, r2, r3); 1907} 1908 1909// Add Storage-Imm (64) 1910void Assembler::agsi(const MemOperand& opnd, const Operand& imm) { 1911 DCHECK(is_int8(imm.imm_)); 1912 DCHECK(is_int20(opnd.offset())); 1913 siy_form(AGSI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset()); 1914} 1915 1916// ------------------------------- 1917// 32-bit Add Logical Instructions 1918// ------------------------------- 1919// Add Logical Register-Storage (32) 1920void Assembler::al_z(Register r1, const MemOperand& opnd) { 1921 rx_form(AL, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1922} 1923 1924// Add Logical Register-Storage (32) 1925void Assembler::aly(Register r1, const MemOperand& opnd) { 1926 rxy_form(ALY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1927} 1928 1929// Add Logical Immediate (32) 1930void Assembler::alfi(Register r1, const Operand& opnd) { 1931 ril_form(ALFI, r1, opnd); 1932} 1933 1934// Add Logical Register-Register (32) 1935void Assembler::alr(Register r1, Register r2) { rr_form(ALR, r1, r2); } 1936 1937// Add Logical With Carry Register-Register (32) 1938void Assembler::alcr(Register r1, Register r2) { rre_form(ALCR, r1, r2); } 1939 1940// Add Logical Register-Register-Register (32) 1941void Assembler::alrk(Register r1, Register r2, Register r3) { 1942 rrf1_form(ALRK, r1, r2, r3); 1943} 1944 1945// ------------------------------- 1946// 64-bit Add Logical Instructions 1947// ------------------------------- 1948// Add Logical Register-Storage (64) 1949void Assembler::alg(Register r1, const MemOperand& opnd) { 1950 rxy_form(ALG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1951} 1952 1953// Add Logical Immediate (64) 1954void Assembler::algfi(Register r1, const Operand& opnd) { 1955 ril_form(ALGFI, r1, opnd); 1956} 1957 1958// Add Logical Register-Register (64) 1959void Assembler::algr(Register r1, Register r2) { rre_form(ALGR, r1, r2); } 1960 1961// Add Logical Register-Register-Register (64) 1962void Assembler::algrk(Register r1, Register r2, Register r3) { 1963 rrf1_form(ALGRK, r1, r2, r3); 1964} 1965 1966// ---------------------------- 1967// 32-bit Subtract Instructions 1968// ---------------------------- 1969// Subtract Register-Storage (32) 1970void Assembler::s(Register r1, const MemOperand& opnd) { 1971 rx_form(S, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1972} 1973 1974// Subtract Register-Storage (32) 1975void Assembler::sy(Register r1, const MemOperand& opnd) { 1976 rxy_form(SY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1977} 1978 1979// Subtract Halfword Register-Storage (32) 1980void Assembler::sh(Register r1, const MemOperand& opnd) { 1981 rx_form(SH, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1982} 1983 1984// Subtract Halfword Register-Storage (32) 1985void Assembler::shy(Register r1, const MemOperand& opnd) { 1986 rxy_form(SHY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 1987} 1988 1989// Subtract Register (32) 1990void Assembler::sr(Register r1, Register r2) { rr_form(SR, r1, r2); } 1991 1992// Subtract Register-Register-Register (32) 1993void Assembler::srk(Register r1, Register r2, Register r3) { 1994 rrf1_form(SRK, r1, r2, r3); 1995} 1996 1997// ---------------------------- 1998// 64-bit Subtract Instructions 1999// ---------------------------- 2000// Subtract Register-Storage (64) 2001void Assembler::sg(Register r1, const MemOperand& opnd) { 2002 rxy_form(SG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2003} 2004 2005// Subtract Register-Storage (64<-32) 2006void Assembler::sgf(Register r1, const MemOperand& opnd) { 2007 rxy_form(SGF, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2008} 2009 2010// Subtract Register (64) 2011void Assembler::sgr(Register r1, Register r2) { rre_form(SGR, r1, r2); } 2012 2013// Subtract Register (64<-32) 2014void Assembler::sgfr(Register r1, Register r2) { rre_form(SGFR, r1, r2); } 2015 2016// Subtract Register-Register-Register (64) 2017void Assembler::sgrk(Register r1, Register r2, Register r3) { 2018 rrf1_form(SGRK, r1, r2, r3); 2019} 2020 2021// ------------------------------------ 2022// 32-bit Subtract Logical Instructions 2023// ------------------------------------ 2024// Subtract Logical Register-Storage (32) 2025void Assembler::sl(Register r1, const MemOperand& opnd) { 2026 rx_form(SL, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2027} 2028 2029// Subtract Logical Register-Storage (32) 2030void Assembler::sly(Register r1, const MemOperand& opnd) { 2031 rxy_form(SLY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2032} 2033 2034// Subtract Logical Register-Register (32) 2035void Assembler::slr(Register r1, Register r2) { rr_form(SLR, r1, r2); } 2036 2037// Subtract Logical With Borrow Register-Register (32) 2038void Assembler::slbr(Register r1, Register r2) { rre_form(SLBR, r1, r2); } 2039 2040// Subtract Logical Register-Register-Register (32) 2041void Assembler::slrk(Register r1, Register r2, Register r3) { 2042 rrf1_form(SLRK, r1, r2, r3); 2043} 2044 2045// ------------------------------------ 2046// 64-bit Subtract Logical Instructions 2047// ------------------------------------ 2048// Subtract Logical Register-Storage (64) 2049void Assembler::slg(Register r1, const MemOperand& opnd) { 2050 rxy_form(SLG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2051} 2052 2053// Subtract Logical Register-Register (64) 2054void Assembler::slgr(Register r1, Register r2) { rre_form(SLGR, r1, r2); } 2055 2056// Subtract Logical Register-Register-Register (64) 2057void Assembler::slgrk(Register r1, Register r2, Register r3) { 2058 rrf1_form(SLGRK, r1, r2, r3); 2059} 2060 2061// ---------------------------- 2062// 32-bit Multiply Instructions 2063// ---------------------------- 2064// Multiply Register-Storage (64<32) 2065void Assembler::m(Register r1, const MemOperand& opnd) { 2066 rx_form(M, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2067} 2068 2069// Multiply Register (64<32) 2070void Assembler::mr_z(Register r1, Register r2) { 2071 DCHECK(r1.code() % 2 == 0); 2072 rr_form(MR, r1, r2); 2073} 2074 2075// Multiply Logical Register-Storage (64<32) 2076void Assembler::ml(Register r1, const MemOperand& opnd) { 2077 rxy_form(ML, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2078} 2079 2080// Multiply Logical Register (64<32) 2081void Assembler::mlr(Register r1, Register r2) { 2082 DCHECK(r1.code() % 2 == 0); 2083 rre_form(MLR, r1, r2); 2084} 2085 2086// Multiply Single Register-Storage (32) 2087void Assembler::ms(Register r1, const MemOperand& opnd) { 2088 rx_form(MS, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2089} 2090 2091// Multiply Single Register-Storage (32) 2092void Assembler::msy(Register r1, const MemOperand& opnd) { 2093 rxy_form(MSY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2094} 2095 2096// Multiply Single Immediate (32) 2097void Assembler::msfi(Register r1, const Operand& opnd) { 2098 ril_form(MSFI, r1, opnd); 2099} 2100 2101// Multiply Single Register (64<32) 2102void Assembler::msr(Register r1, Register r2) { rre_form(MSR, r1, r2); } 2103 2104// Multiply Halfword Register-Storage (32) 2105void Assembler::mh(Register r1, const MemOperand& opnd) { 2106 rx_form(MH, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2107} 2108 2109// Multiply Halfword Register-Storage (32) 2110void Assembler::mhy(Register r1, const MemOperand& opnd) { 2111 rxy_form(MHY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2112} 2113 2114// Multiply Halfword Immediate (32) 2115void Assembler::mhi(Register r1, const Operand& opnd) { 2116 ri_form(MHI, r1, opnd); 2117} 2118 2119// ---------------------------- 2120// 64-bit Multiply Instructions 2121// ---------------------------- 2122// Multiply Logical Register-Storage (128<64) 2123void Assembler::mlg(Register r1, const MemOperand& opnd) { 2124 rxy_form(MLG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2125} 2126 2127// Multiply Register (128<64) 2128void Assembler::mlgr(Register r1, Register r2) { rre_form(MLGR, r1, r2); } 2129 2130// Multiply Halfword Immediate (64) 2131void Assembler::mghi(Register r1, const Operand& opnd) { 2132 ri_form(MGHI, r1, opnd); 2133} 2134 2135// Multiply Single Immediate (64) 2136void Assembler::msgfi(Register r1, const Operand& opnd) { 2137 ril_form(MSGFI, r1, opnd); 2138} 2139 2140// Multiply Single Register-Storage (64) 2141void Assembler::msg(Register r1, const MemOperand& opnd) { 2142 rxy_form(MSG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2143} 2144 2145// Multiply Single Register-Register (64) 2146void Assembler::msgr(Register r1, Register r2) { rre_form(MSGR, r1, r2); } 2147 2148// -------------------------- 2149// 32-bit Divide Instructions 2150// -------------------------- 2151// Divide Register-Storage (32<-64) 2152void Assembler::d(Register r1, const MemOperand& opnd) { 2153 rx_form(D, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2154} 2155 2156// Divide Register (32<-64) 2157void Assembler::dr(Register r1, Register r2) { 2158 DCHECK(r1.code() % 2 == 0); 2159 rr_form(DR, r1, r2); 2160} 2161 2162// Divide Logical Register-Storage (32<-64) 2163void Assembler::dl(Register r1, const MemOperand& opnd) { 2164 rx_form(DL, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2165} 2166 2167// Divide Logical Register (32<-64) 2168void Assembler::dlr(Register r1, Register r2) { rre_form(DLR, r1, r2); } 2169 2170// -------------------------- 2171// 64-bit Divide Instructions 2172// -------------------------- 2173// Divide Logical Register (64<-128) 2174void Assembler::dlgr(Register r1, Register r2) { rre_form(DLGR, r1, r2); } 2175 2176// Divide Single Register (64<-32) 2177void Assembler::dsgr(Register r1, Register r2) { rre_form(DSGR, r1, r2); } 2178 2179// -------------------- 2180// Bitwise Instructions 2181// -------------------- 2182// AND Register-Storage (32) 2183void Assembler::n(Register r1, const MemOperand& opnd) { 2184 rx_form(N, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2185} 2186 2187// AND Register-Storage (32) 2188void Assembler::ny(Register r1, const MemOperand& opnd) { 2189 rxy_form(NY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2190} 2191 2192// AND Register (32) 2193void Assembler::nr(Register r1, Register r2) { rr_form(NR, r1, r2); } 2194 2195// AND Register-Register-Register (32) 2196void Assembler::nrk(Register r1, Register r2, Register r3) { 2197 rrf1_form(NRK, r1, r2, r3); 2198} 2199 2200// AND Register-Storage (64) 2201void Assembler::ng(Register r1, const MemOperand& opnd) { 2202 rxy_form(NG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2203} 2204 2205// AND Register (64) 2206void Assembler::ngr(Register r1, Register r2) { rre_form(NGR, r1, r2); } 2207 2208// AND Register-Register-Register (64) 2209void Assembler::ngrk(Register r1, Register r2, Register r3) { 2210 rrf1_form(NGRK, r1, r2, r3); 2211} 2212 2213// OR Register-Storage (32) 2214void Assembler::o(Register r1, const MemOperand& opnd) { 2215 rx_form(O, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2216} 2217 2218// OR Register-Storage (32) 2219void Assembler::oy(Register r1, const MemOperand& opnd) { 2220 rxy_form(OY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2221} 2222 2223// OR Register (32) 2224void Assembler::or_z(Register r1, Register r2) { rr_form(OR, r1, r2); } 2225 2226// OR Register-Register-Register (32) 2227void Assembler::ork(Register r1, Register r2, Register r3) { 2228 rrf1_form(ORK, r1, r2, r3); 2229} 2230 2231// OR Register-Storage (64) 2232void Assembler::og(Register r1, const MemOperand& opnd) { 2233 rxy_form(OG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2234} 2235 2236// OR Register (64) 2237void Assembler::ogr(Register r1, Register r2) { rre_form(OGR, r1, r2); } 2238 2239// OR Register-Register-Register (64) 2240void Assembler::ogrk(Register r1, Register r2, Register r3) { 2241 rrf1_form(OGRK, r1, r2, r3); 2242} 2243 2244// XOR Register-Storage (32) 2245void Assembler::x(Register r1, const MemOperand& opnd) { 2246 rx_form(X, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2247} 2248 2249// XOR Register-Storage (32) 2250void Assembler::xy(Register r1, const MemOperand& opnd) { 2251 rxy_form(XY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2252} 2253 2254// XOR Register (32) 2255void Assembler::xr(Register r1, Register r2) { rr_form(XR, r1, r2); } 2256 2257// XOR Register-Register-Register (32) 2258void Assembler::xrk(Register r1, Register r2, Register r3) { 2259 rrf1_form(XRK, r1, r2, r3); 2260} 2261 2262// XOR Register-Storage (64) 2263void Assembler::xg(Register r1, const MemOperand& opnd) { 2264 rxy_form(XG, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2265} 2266 2267// XOR Register (64) 2268void Assembler::xgr(Register r1, Register r2) { rre_form(XGR, r1, r2); } 2269 2270// XOR Register-Register-Register (64) 2271void Assembler::xgrk(Register r1, Register r2, Register r3) { 2272 rrf1_form(XGRK, r1, r2, r3); 2273} 2274 2275// XOR Storage-Storage 2276void Assembler::xc(const MemOperand& opnd1, const MemOperand& opnd2, 2277 Length length) { 2278 ss_form(XC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(), 2279 opnd2.getBaseRegister(), opnd2.getDisplacement()); 2280} 2281 2282// ------------------------------------------- 2283// Bitwise GPR <-> FPR Conversion Instructions 2284// ------------------------------------------- 2285// Load GR from FPR (64 <- L) 2286void Assembler::lgdr(Register r1, DoubleRegister f2) { 2287 rre_form(LGDR, r1, Register::from_code(f2.code())); 2288} 2289 2290// Load FPR from FR (L <- 64) 2291void Assembler::ldgr(DoubleRegister f1, Register r2) { 2292 rre_form(LDGR, Register::from_code(f1.code()), r2); 2293} 2294 2295void Assembler::EnsureSpaceFor(int space_needed) { 2296 if (buffer_space() <= (kGap + space_needed)) { 2297 GrowBuffer(space_needed); 2298 } 2299} 2300 2301// Rotate Left Single Logical (32) 2302void Assembler::rll(Register r1, Register r3, Register opnd) { 2303 DCHECK(!opnd.is(r0)); 2304 rsy_form(RLL, r1, r3, opnd, 0); 2305} 2306 2307// Rotate Left Single Logical (32) 2308void Assembler::rll(Register r1, Register r3, const Operand& opnd) { 2309 rsy_form(RLL, r1, r3, r0, opnd.immediate()); 2310} 2311 2312// Rotate Left Single Logical (32) 2313void Assembler::rll(Register r1, Register r3, Register r2, 2314 const Operand& opnd) { 2315 rsy_form(RLL, r1, r3, r2, opnd.immediate()); 2316} 2317 2318// Rotate Left Single Logical (64) 2319void Assembler::rllg(Register r1, Register r3, Register opnd) { 2320 DCHECK(!opnd.is(r0)); 2321 rsy_form(RLLG, r1, r3, opnd, 0); 2322} 2323 2324// Rotate Left Single Logical (64) 2325void Assembler::rllg(Register r1, Register r3, const Operand& opnd) { 2326 rsy_form(RLLG, r1, r3, r0, opnd.immediate()); 2327} 2328 2329// Rotate Left Single Logical (64) 2330void Assembler::rllg(Register r1, Register r3, Register r2, 2331 const Operand& opnd) { 2332 rsy_form(RLLG, r1, r3, r2, opnd.immediate()); 2333} 2334 2335// Shift Left Single Logical (32) 2336void Assembler::sll(Register r1, Register opnd) { 2337 DCHECK(!opnd.is(r0)); 2338 rs_form(SLL, r1, r0, opnd, 0); 2339} 2340 2341// Shift Left Single Logical (32) 2342void Assembler::sll(Register r1, const Operand& opnd) { 2343 rs_form(SLL, r1, r0, r0, opnd.immediate()); 2344} 2345 2346// Shift Left Single Logical (32) 2347void Assembler::sllk(Register r1, Register r3, Register opnd) { 2348 DCHECK(!opnd.is(r0)); 2349 rsy_form(SLLK, r1, r3, opnd, 0); 2350} 2351 2352// Shift Left Single Logical (32) 2353void Assembler::sllk(Register r1, Register r3, const Operand& opnd) { 2354 rsy_form(SLLK, r1, r3, r0, opnd.immediate()); 2355} 2356 2357// Shift Left Single Logical (64) 2358void Assembler::sllg(Register r1, Register r3, Register opnd) { 2359 DCHECK(!opnd.is(r0)); 2360 rsy_form(SLLG, r1, r3, opnd, 0); 2361} 2362 2363// Shift Left Single Logical (64) 2364void Assembler::sllg(Register r1, Register r3, const Operand& opnd) { 2365 rsy_form(SLLG, r1, r3, r0, opnd.immediate()); 2366} 2367 2368// Shift Left Double Logical (64) 2369void Assembler::sldl(Register r1, Register b2, const Operand& opnd) { 2370 DCHECK(r1.code() % 2 == 0); 2371 rs_form(SLDL, r1, r0, b2, opnd.immediate()); 2372} 2373 2374// Shift Right Single Logical (32) 2375void Assembler::srl(Register r1, Register opnd) { 2376 DCHECK(!opnd.is(r0)); 2377 rs_form(SRL, r1, r0, opnd, 0); 2378} 2379 2380// Shift Right Double Arith (64) 2381void Assembler::srda(Register r1, Register b2, const Operand& opnd) { 2382 DCHECK(r1.code() % 2 == 0); 2383 rs_form(SRDA, r1, r0, b2, opnd.immediate()); 2384} 2385 2386// Shift Right Double Logical (64) 2387void Assembler::srdl(Register r1, Register b2, const Operand& opnd) { 2388 DCHECK(r1.code() % 2 == 0); 2389 rs_form(SRDL, r1, r0, b2, opnd.immediate()); 2390} 2391 2392// Shift Right Single Logical (32) 2393void Assembler::srl(Register r1, const Operand& opnd) { 2394 rs_form(SRL, r1, r0, r0, opnd.immediate()); 2395} 2396 2397// Shift Right Single Logical (32) 2398void Assembler::srlk(Register r1, Register r3, Register opnd) { 2399 DCHECK(!opnd.is(r0)); 2400 rsy_form(SRLK, r1, r3, opnd, 0); 2401} 2402 2403// Shift Right Single Logical (32) 2404void Assembler::srlk(Register r1, Register r3, const Operand& opnd) { 2405 rsy_form(SRLK, r1, r3, r0, opnd.immediate()); 2406} 2407 2408// Shift Right Single Logical (64) 2409void Assembler::srlg(Register r1, Register r3, Register opnd) { 2410 DCHECK(!opnd.is(r0)); 2411 rsy_form(SRLG, r1, r3, opnd, 0); 2412} 2413 2414// Shift Right Single Logical (64) 2415void Assembler::srlg(Register r1, Register r3, const Operand& opnd) { 2416 rsy_form(SRLG, r1, r3, r0, opnd.immediate()); 2417} 2418 2419// Shift Left Single (32) 2420void Assembler::sla(Register r1, Register opnd) { 2421 DCHECK(!opnd.is(r0)); 2422 rs_form(SLA, r1, r0, opnd, 0); 2423} 2424 2425// Shift Left Single (32) 2426void Assembler::sla(Register r1, const Operand& opnd) { 2427 rs_form(SLA, r1, r0, r0, opnd.immediate()); 2428} 2429 2430// Shift Left Single (32) 2431void Assembler::slak(Register r1, Register r3, Register opnd) { 2432 DCHECK(!opnd.is(r0)); 2433 rsy_form(SLAK, r1, r3, opnd, 0); 2434} 2435 2436// Shift Left Single (32) 2437void Assembler::slak(Register r1, Register r3, const Operand& opnd) { 2438 rsy_form(SLAK, r1, r3, r0, opnd.immediate()); 2439} 2440 2441// Shift Left Single (64) 2442void Assembler::slag(Register r1, Register r3, Register opnd) { 2443 DCHECK(!opnd.is(r0)); 2444 rsy_form(SLAG, r1, r3, opnd, 0); 2445} 2446 2447// Shift Left Single (64) 2448void Assembler::slag(Register r1, Register r3, const Operand& opnd) { 2449 rsy_form(SLAG, r1, r3, r0, opnd.immediate()); 2450} 2451 2452// Shift Right Single (32) 2453void Assembler::sra(Register r1, Register opnd) { 2454 DCHECK(!opnd.is(r0)); 2455 rs_form(SRA, r1, r0, opnd, 0); 2456} 2457 2458// Shift Right Single (32) 2459void Assembler::sra(Register r1, const Operand& opnd) { 2460 rs_form(SRA, r1, r0, r0, opnd.immediate()); 2461} 2462 2463// Shift Right Single (32) 2464void Assembler::srak(Register r1, Register r3, Register opnd) { 2465 DCHECK(!opnd.is(r0)); 2466 rsy_form(SRAK, r1, r3, opnd, 0); 2467} 2468 2469// Shift Right Single (32) 2470void Assembler::srak(Register r1, Register r3, const Operand& opnd) { 2471 rsy_form(SRAK, r1, r3, r0, opnd.immediate()); 2472} 2473 2474// Shift Right Single (64) 2475void Assembler::srag(Register r1, Register r3, Register opnd) { 2476 DCHECK(!opnd.is(r0)); 2477 rsy_form(SRAG, r1, r3, opnd, 0); 2478} 2479 2480void Assembler::srag(Register r1, Register r3, const Operand& opnd) { 2481 rsy_form(SRAG, r1, r3, r0, opnd.immediate()); 2482} 2483 2484// Shift Right Double 2485void Assembler::srda(Register r1, const Operand& opnd) { 2486 DCHECK(r1.code() % 2 == 0); 2487 rs_form(SRDA, r1, r0, r0, opnd.immediate()); 2488} 2489 2490// Shift Right Double Logical 2491void Assembler::srdl(Register r1, const Operand& opnd) { 2492 DCHECK(r1.code() % 2 == 0); 2493 rs_form(SRDL, r1, r0, r0, opnd.immediate()); 2494} 2495 2496void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode, 2497 TypeFeedbackId ast_id) { 2498 EnsureSpace ensure_space(this); 2499 2500 int32_t target_index = emit_code_target(target, rmode, ast_id); 2501 brasl(r14, Operand(target_index)); 2502} 2503 2504void Assembler::jump(Handle<Code> target, RelocInfo::Mode rmode, 2505 Condition cond) { 2506 EnsureSpace ensure_space(this); 2507 2508 int32_t target_index = emit_code_target(target, rmode); 2509 brcl(cond, Operand(target_index), true); 2510} 2511 2512// Store (32) 2513void Assembler::st(Register src, const MemOperand& dst) { 2514 rx_form(ST, src, dst.rx(), dst.rb(), dst.offset()); 2515} 2516 2517// Store (32) 2518void Assembler::sty(Register src, const MemOperand& dst) { 2519 rxy_form(STY, src, dst.rx(), dst.rb(), dst.offset()); 2520} 2521 2522// Store Halfword 2523void Assembler::sth(Register src, const MemOperand& dst) { 2524 rx_form(STH, src, dst.rx(), dst.rb(), dst.offset()); 2525} 2526 2527// Store Halfword 2528void Assembler::sthy(Register src, const MemOperand& dst) { 2529 rxy_form(STHY, src, dst.rx(), dst.rb(), dst.offset()); 2530} 2531 2532// Store Character 2533void Assembler::stc(Register src, const MemOperand& dst) { 2534 rx_form(STC, src, dst.rx(), dst.rb(), dst.offset()); 2535} 2536 2537// Store Character 2538void Assembler::stcy(Register src, const MemOperand& dst) { 2539 rxy_form(STCY, src, dst.rx(), dst.rb(), dst.offset()); 2540} 2541 2542// 32-bit Load Multiple - short displacement (12-bits unsigned) 2543void Assembler::lm(Register r1, Register r2, const MemOperand& src) { 2544 rs_form(LM, r1, r2, src.rb(), src.offset()); 2545} 2546 2547// 32-bit Load Multiple - long displacement (20-bits signed) 2548void Assembler::lmy(Register r1, Register r2, const MemOperand& src) { 2549 rsy_form(LMY, r1, r2, src.rb(), src.offset()); 2550} 2551 2552// 64-bit Load Multiple - long displacement (20-bits signed) 2553void Assembler::lmg(Register r1, Register r2, const MemOperand& src) { 2554 rsy_form(LMG, r1, r2, src.rb(), src.offset()); 2555} 2556 2557// Move integer (32) 2558void Assembler::mvhi(const MemOperand& opnd1, const Operand& i2) { 2559 sil_form(MVHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2); 2560} 2561 2562// Move integer (64) 2563void Assembler::mvghi(const MemOperand& opnd1, const Operand& i2) { 2564 sil_form(MVGHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2); 2565} 2566 2567// Store Register (64) 2568void Assembler::stg(Register src, const MemOperand& dst) { 2569 DCHECK(!(dst.rb().code() == 15 && dst.offset() < 0)); 2570 rxy_form(STG, src, dst.rx(), dst.rb(), dst.offset()); 2571} 2572 2573// Insert Character 2574void Assembler::ic_z(Register r1, const MemOperand& opnd) { 2575 rx_form(IC_z, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2576} 2577 2578// Insert Character 2579void Assembler::icy(Register r1, const MemOperand& opnd) { 2580 rxy_form(ICY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2581} 2582 2583// Insert Immediate (High) 2584void Assembler::iihf(Register r1, const Operand& opnd) { 2585 ril_form(IIHF, r1, opnd); 2586} 2587 2588// Insert Immediate (low) 2589void Assembler::iilf(Register r1, const Operand& opnd) { 2590 ril_form(IILF, r1, opnd); 2591} 2592 2593// Insert Immediate (high high) 2594void Assembler::iihh(Register r1, const Operand& opnd) { 2595 ri_form(IIHH, r1, opnd); 2596} 2597 2598// Insert Immediate (high low) 2599void Assembler::iihl(Register r1, const Operand& opnd) { 2600 ri_form(IIHL, r1, opnd); 2601} 2602 2603// Insert Immediate (low high) 2604void Assembler::iilh(Register r1, const Operand& opnd) { 2605 ri_form(IILH, r1, opnd); 2606} 2607 2608// Insert Immediate (low low) 2609void Assembler::iill(Register r1, const Operand& opnd) { 2610 ri_form(IILL, r1, opnd); 2611} 2612 2613// GPR <-> FPR Instructions 2614 2615// Floating point instructions 2616// 2617// Load zero Register (64) 2618void Assembler::lzdr(DoubleRegister r1) { 2619 rre_form(LZDR, Register::from_code(r1.code()), Register::from_code(0)); 2620} 2621 2622// Add Register-Register (LB) 2623void Assembler::aebr(DoubleRegister r1, DoubleRegister r2) { 2624 rre_form(AEBR, Register::from_code(r1.code()), 2625 Register::from_code(r2.code())); 2626} 2627 2628// Add Register-Storage (LB) 2629void Assembler::adb(DoubleRegister r1, const MemOperand& opnd) { 2630 rxe_form(ADB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 2631 opnd.offset()); 2632} 2633 2634// Add Register-Register (LB) 2635void Assembler::adbr(DoubleRegister r1, DoubleRegister r2) { 2636 rre_form(ADBR, Register::from_code(r1.code()), 2637 Register::from_code(r2.code())); 2638} 2639 2640// Compare Register-Register (LB) 2641void Assembler::cebr(DoubleRegister r1, DoubleRegister r2) { 2642 rre_form(CEBR, Register::from_code(r1.code()), 2643 Register::from_code(r2.code())); 2644} 2645 2646// Compare Register-Storage (LB) 2647void Assembler::cdb(DoubleRegister r1, const MemOperand& opnd) { 2648 rx_form(CD, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 2649 opnd.offset()); 2650} 2651 2652// Compare Register-Register (LB) 2653void Assembler::cdbr(DoubleRegister r1, DoubleRegister r2) { 2654 rre_form(CDBR, Register::from_code(r1.code()), 2655 Register::from_code(r2.code())); 2656} 2657 2658// Divide Register-Register (LB) 2659void Assembler::debr(DoubleRegister r1, DoubleRegister r2) { 2660 rre_form(DEBR, Register::from_code(r1.code()), 2661 Register::from_code(r2.code())); 2662} 2663 2664// Divide Register-Storage (LB) 2665void Assembler::ddb(DoubleRegister r1, const MemOperand& opnd) { 2666 rxe_form(DDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 2667 opnd.offset()); 2668} 2669 2670// Divide Register-Register (LB) 2671void Assembler::ddbr(DoubleRegister r1, DoubleRegister r2) { 2672 rre_form(DDBR, Register::from_code(r1.code()), 2673 Register::from_code(r2.code())); 2674} 2675 2676// Multiply Register-Register (LB) 2677void Assembler::meebr(DoubleRegister r1, DoubleRegister r2) { 2678 rre_form(MEEBR, Register::from_code(r1.code()), 2679 Register::from_code(r2.code())); 2680} 2681 2682// Multiply Register-Storage (LB) 2683void Assembler::mdb(DoubleRegister r1, const MemOperand& opnd) { 2684 rxe_form(MDB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(), 2685 opnd.offset()); 2686} 2687 2688// Multiply Register-Register (LB) 2689void Assembler::mdbr(DoubleRegister r1, DoubleRegister r2) { 2690 rre_form(MDBR, Register::from_code(r1.code()), 2691 Register::from_code(r2.code())); 2692} 2693 2694// Subtract Register-Register (LB) 2695void Assembler::sebr(DoubleRegister r1, DoubleRegister r2) { 2696 rre_form(SEBR, Register::from_code(r1.code()), 2697 Register::from_code(r2.code())); 2698} 2699 2700// Subtract Register-Storage (LB) 2701void Assembler::sdb(DoubleRegister r1, const MemOperand& opnd) { 2702 rxe_form(SDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 2703 opnd.offset()); 2704} 2705 2706// Subtract Register-Register (LB) 2707void Assembler::sdbr(DoubleRegister r1, DoubleRegister r2) { 2708 rre_form(SDBR, Register::from_code(r1.code()), 2709 Register::from_code(r2.code())); 2710} 2711 2712// Square Root (LB) 2713void Assembler::sqdb(DoubleRegister r1, const MemOperand& opnd) { 2714 rxe_form(SQDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(), 2715 opnd.offset()); 2716} 2717 2718// Square Root Register-Register (LB) 2719void Assembler::sqebr(DoubleRegister r1, DoubleRegister r2) { 2720 rre_form(SQEBR, Register::from_code(r1.code()), 2721 Register::from_code(r2.code())); 2722} 2723 2724// Square Root Register-Register (LB) 2725void Assembler::sqdbr(DoubleRegister r1, DoubleRegister r2) { 2726 rre_form(SQDBR, Register::from_code(r1.code()), 2727 Register::from_code(r2.code())); 2728} 2729 2730// Load Rounded (double -> float) 2731void Assembler::ledbr(DoubleRegister r1, DoubleRegister r2) { 2732 rre_form(LEDBR, Register::from_code(r1.code()), 2733 Register::from_code(r2.code())); 2734} 2735 2736// Load Lengthen (float -> double) 2737void Assembler::ldebr(DoubleRegister r1, DoubleRegister r2) { 2738 rre_form(LDEBR, Register::from_code(r1.code()), 2739 Register::from_code(r2.code())); 2740} 2741 2742// Load Complement Register-Register (LB) 2743void Assembler::lcdbr(DoubleRegister r1, DoubleRegister r2) { 2744 rre_form(LCDBR, Register::from_code(r1.code()), 2745 Register::from_code(r2.code())); 2746} 2747 2748// Load Positive Register-Register (LB) 2749void Assembler::lpebr(DoubleRegister r1, DoubleRegister r2) { 2750 rre_form(LPEBR, Register::from_code(r1.code()), 2751 Register::from_code(r2.code())); 2752} 2753 2754// Load Positive Register-Register (LB) 2755void Assembler::lpdbr(DoubleRegister r1, DoubleRegister r2) { 2756 rre_form(LPDBR, Register::from_code(r1.code()), 2757 Register::from_code(r2.code())); 2758} 2759 2760// Store Double (64) 2761void Assembler::std(DoubleRegister r1, const MemOperand& opnd) { 2762 rx_form(STD, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2763} 2764 2765// Store Double (64) 2766void Assembler::stdy(DoubleRegister r1, const MemOperand& opnd) { 2767 DCHECK(!(opnd.rb().code() == 15 && opnd.offset() < 0)); 2768 rxy_form(STDY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2769} 2770 2771// Store Float (32) 2772void Assembler::ste(DoubleRegister r1, const MemOperand& opnd) { 2773 rx_form(STE, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2774} 2775 2776// Store Float (32) 2777void Assembler::stey(DoubleRegister r1, const MemOperand& opnd) { 2778 DCHECK(!(opnd.rb().code() == 15 && opnd.offset() < 0)); 2779 rxy_form(STEY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2780} 2781 2782// Load Double (64) 2783void Assembler::ld(DoubleRegister r1, const MemOperand& opnd) { 2784 DCHECK(is_uint12(opnd.offset())); 2785 rx_form(LD, r1, opnd.rx(), opnd.rb(), opnd.offset() & 0xfff); 2786} 2787 2788// Load Double (64) 2789void Assembler::ldy(DoubleRegister r1, const MemOperand& opnd) { 2790 DCHECK(is_int20(opnd.offset())); 2791 rxy_form(LDY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2792} 2793 2794// Load Float (32) 2795void Assembler::le_z(DoubleRegister r1, const MemOperand& opnd) { 2796 DCHECK(is_uint12(opnd.offset())); 2797 rx_form(LE, r1, opnd.rx(), opnd.rb(), opnd.offset() & 0xfff); 2798} 2799 2800// Load Float (32) 2801void Assembler::ley(DoubleRegister r1, const MemOperand& opnd) { 2802 DCHECK(is_int20(opnd.offset())); 2803 rxy_form(LEY, r1, opnd.rx(), opnd.rb(), opnd.offset()); 2804} 2805 2806// Load Double Register-Register (64) 2807void Assembler::ldr(DoubleRegister r1, DoubleRegister r2) { 2808 rr_form(LDR, r1, r2); 2809} 2810 2811// Load And Test Register-Register (L) 2812void Assembler::ltebr(DoubleRegister r1, DoubleRegister r2) { 2813 rre_form(LTEBR, r1, r2); 2814} 2815 2816// Load And Test Register-Register (L) 2817void Assembler::ltdbr(DoubleRegister r1, DoubleRegister r2) { 2818 rre_form(LTDBR, r1, r2); 2819} 2820 2821// Convert to Fixed point (64<-S) 2822void Assembler::cgebr(Condition m, Register r1, DoubleRegister r2) { 2823 rrfe_form(CGEBR, m, Condition(0), r1, Register::from_code(r2.code())); 2824} 2825 2826// Convert to Fixed point (64<-L) 2827void Assembler::cgdbr(Condition m, Register r1, DoubleRegister r2) { 2828 rrfe_form(CGDBR, m, Condition(0), r1, Register::from_code(r2.code())); 2829} 2830 2831// Convert to Fixed point (32<-L) 2832void Assembler::cfdbr(Condition m, Register r1, DoubleRegister r2) { 2833 rrfe_form(CFDBR, m, Condition(0), r1, Register::from_code(r2.code())); 2834} 2835 2836// Convert from Fixed point (L<-64) 2837void Assembler::cegbr(DoubleRegister r1, Register r2) { 2838 rre_form(CEGBR, Register::from_code(r1.code()), r2); 2839} 2840 2841// Convert from Fixed point (L<-64) 2842void Assembler::cdgbr(DoubleRegister r1, Register r2) { 2843 rre_form(CDGBR, Register::from_code(r1.code()), r2); 2844} 2845 2846// Convert from Fixed point (L<-32) 2847void Assembler::cdfbr(DoubleRegister r1, Register r2) { 2848 rre_form(CDFBR, Register::from_code(r1.code()), r2); 2849} 2850 2851// Convert to Fixed Logical (64<-L) 2852void Assembler::clgdbr(Condition m3, Condition m4, Register r1, 2853 DoubleRegister r2) { 2854 DCHECK_EQ(m4, Condition(0)); 2855 rrfe_form(CLGDBR, m3, m4, r1, Register::from_code(r2.code())); 2856} 2857 2858// Convert to Fixed Logical (64<-F32) 2859void Assembler::clgebr(Condition m3, Condition m4, Register r1, 2860 DoubleRegister r2) { 2861 DCHECK_EQ(m4, Condition(0)); 2862 rrfe_form(CLGEBR, m3, m4, r1, Register::from_code(r2.code())); 2863} 2864 2865// Convert to Fixed Logical (32<-F64) 2866void Assembler::clfdbr(Condition m3, Condition m4, Register r1, 2867 DoubleRegister r2) { 2868 DCHECK_EQ(m3, Condition(0)); 2869 DCHECK_EQ(m4, Condition(0)); 2870 rrfe_form(CLFDBR, Condition(0), Condition(0), r1, 2871 Register::from_code(r2.code())); 2872} 2873 2874// Convert to Fixed Logical (32<-F32) 2875void Assembler::clfebr(Condition m3, Condition m4, Register r1, 2876 DoubleRegister r2) { 2877 DCHECK_EQ(m4, Condition(0)); 2878 rrfe_form(CLFEBR, m3, Condition(0), r1, Register::from_code(r2.code())); 2879} 2880 2881// Convert from Fixed Logical (L<-64) 2882void Assembler::celgbr(Condition m3, Condition m4, DoubleRegister r1, 2883 Register r2) { 2884 DCHECK_EQ(m3, Condition(0)); 2885 DCHECK_EQ(m4, Condition(0)); 2886 rrfe_form(CELGBR, Condition(0), Condition(0), Register::from_code(r1.code()), 2887 r2); 2888} 2889 2890// Convert from Fixed Logical (F32<-32) 2891void Assembler::celfbr(Condition m3, Condition m4, DoubleRegister r1, 2892 Register r2) { 2893 DCHECK_EQ(m3, Condition(0)); 2894 DCHECK_EQ(m4, Condition(0)); 2895 rrfe_form(CELFBR, Condition(0), Condition(0), Register::from_code(r1.code()), 2896 r2); 2897} 2898 2899// Convert from Fixed Logical (L<-64) 2900void Assembler::cdlgbr(Condition m3, Condition m4, DoubleRegister r1, 2901 Register r2) { 2902 DCHECK_EQ(m3, Condition(0)); 2903 DCHECK_EQ(m4, Condition(0)); 2904 rrfe_form(CDLGBR, Condition(0), Condition(0), Register::from_code(r1.code()), 2905 r2); 2906} 2907 2908// Convert from Fixed Logical (L<-32) 2909void Assembler::cdlfbr(Condition m3, Condition m4, DoubleRegister r1, 2910 Register r2) { 2911 DCHECK_EQ(m4, Condition(0)); 2912 rrfe_form(CDLFBR, m3, Condition(0), Register::from_code(r1.code()), r2); 2913} 2914 2915// Convert from Fixed point (S<-32) 2916void Assembler::cefbr(DoubleRegister r1, Register r2) { 2917 rre_form(CEFBR, Register::from_code(r1.code()), r2); 2918} 2919 2920// Convert to Fixed point (32<-S) 2921void Assembler::cfebr(Condition m3, Register r1, DoubleRegister r2) { 2922 rrfe_form(CFEBR, m3, Condition(0), r1, Register::from_code(r2.code())); 2923} 2924 2925// Load (L <- S) 2926void Assembler::ldeb(DoubleRegister d1, const MemOperand& opnd) { 2927 rxe_form(LDEB, Register::from_code(d1.code()), opnd.rx(), opnd.rb(), 2928 opnd.offset()); 2929} 2930 2931// Load FP Integer 2932void Assembler::fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) { 2933 rrf2_form(FIEBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code()); 2934} 2935 2936// Load FP Integer 2937void Assembler::fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) { 2938 rrf2_form(FIDBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code()); 2939} 2940 2941// Multiply and Add - MADBR R1, R3, R2 2942// R1 = R3 * R2 + R1 2943void Assembler::madbr(DoubleRegister d1, DoubleRegister d3, DoubleRegister d2) { 2944 rrd_form(MADBR, Register::from_code(d1.code()), 2945 Register::from_code(d3.code()), Register::from_code(d2.code())); 2946} 2947 2948// Multiply and Subtract - MSDBR R1, R3, R2 2949// R1 = R3 * R2 - R1 2950void Assembler::msdbr(DoubleRegister d1, DoubleRegister d3, DoubleRegister d2) { 2951 rrd_form(MSDBR, Register::from_code(d1.code()), 2952 Register::from_code(d3.code()), Register::from_code(d2.code())); 2953} 2954 2955// end of S390instructions 2956 2957bool Assembler::IsNop(SixByteInstr instr, int type) { 2958 DCHECK((0 == type) || (DEBUG_BREAK_NOP == type)); 2959 if (DEBUG_BREAK_NOP == type) { 2960 return ((instr & 0xffffffff) == 0xa53b0000); // oill r3, 0 2961 } 2962 return ((instr & 0xffff) == 0x1800); // lr r0,r0 2963} 2964 2965void Assembler::GrowBuffer(int needed) { 2966 if (!own_buffer_) FATAL("external code buffer is too small"); 2967 2968 // Compute new buffer size. 2969 CodeDesc desc; // the new buffer 2970 if (buffer_size_ < 4 * KB) { 2971 desc.buffer_size = 4 * KB; 2972 } else if (buffer_size_ < 1 * MB) { 2973 desc.buffer_size = 2 * buffer_size_; 2974 } else { 2975 desc.buffer_size = buffer_size_ + 1 * MB; 2976 } 2977 int space = buffer_space() + (desc.buffer_size - buffer_size_); 2978 if (space < needed) { 2979 desc.buffer_size += needed - space; 2980 } 2981 CHECK_GT(desc.buffer_size, 0); // no overflow 2982 2983 // Set up new buffer. 2984 desc.buffer = NewArray<byte>(desc.buffer_size); 2985 desc.origin = this; 2986 2987 desc.instr_size = pc_offset(); 2988 desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 2989 2990 // Copy the data. 2991 intptr_t pc_delta = desc.buffer - buffer_; 2992 intptr_t rc_delta = 2993 (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); 2994 memmove(desc.buffer, buffer_, desc.instr_size); 2995 memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(), 2996 desc.reloc_size); 2997 2998 // Switch buffers. 2999 DeleteArray(buffer_); 3000 buffer_ = desc.buffer; 3001 buffer_size_ = desc.buffer_size; 3002 pc_ += pc_delta; 3003 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 3004 reloc_info_writer.last_pc() + pc_delta); 3005 3006 // None of our relocation types are pc relative pointing outside the code 3007 // buffer nor pc absolute pointing inside the code buffer, so there is no need 3008 // to relocate any emitted relocation entries. 3009} 3010 3011void Assembler::db(uint8_t data) { 3012 CheckBuffer(); 3013 *reinterpret_cast<uint8_t*>(pc_) = data; 3014 pc_ += sizeof(uint8_t); 3015} 3016 3017void Assembler::dd(uint32_t data) { 3018 CheckBuffer(); 3019 *reinterpret_cast<uint32_t*>(pc_) = data; 3020 pc_ += sizeof(uint32_t); 3021} 3022 3023void Assembler::dq(uint64_t value) { 3024 CheckBuffer(); 3025 *reinterpret_cast<uint64_t*>(pc_) = value; 3026 pc_ += sizeof(uint64_t); 3027} 3028 3029void Assembler::dp(uintptr_t data) { 3030 CheckBuffer(); 3031 *reinterpret_cast<uintptr_t*>(pc_) = data; 3032 pc_ += sizeof(uintptr_t); 3033} 3034 3035void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 3036 if (RelocInfo::IsNone(rmode) || 3037 // Don't record external references unless the heap will be serialized. 3038 (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() && 3039 !emit_debug_code())) { 3040 return; 3041 } 3042 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 3043 data = RecordedAstId().ToInt(); 3044 ClearRecordedAstId(); 3045 } 3046 DeferredRelocInfo rinfo(pc_offset(), rmode, data); 3047 relocations_.push_back(rinfo); 3048} 3049 3050void Assembler::emit_label_addr(Label* label) { 3051 CheckBuffer(); 3052 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 3053 int position = link(label); 3054 DCHECK(label->is_bound()); 3055 // Keep internal references relative until EmitRelocations. 3056 dp(position); 3057} 3058 3059void Assembler::EmitRelocations() { 3060 EnsureSpaceFor(relocations_.size() * kMaxRelocSize); 3061 3062 for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin(); 3063 it != relocations_.end(); it++) { 3064 RelocInfo::Mode rmode = it->rmode(); 3065 Address pc = buffer_ + it->position(); 3066 Code* code = NULL; 3067 RelocInfo rinfo(isolate(), pc, rmode, it->data(), code); 3068 3069 // Fix up internal references now that they are guaranteed to be bound. 3070 if (RelocInfo::IsInternalReference(rmode)) { 3071 // Jump table entry 3072 intptr_t pos = reinterpret_cast<intptr_t>(Memory::Address_at(pc)); 3073 Memory::Address_at(pc) = buffer_ + pos; 3074 } else if (RelocInfo::IsInternalReferenceEncoded(rmode)) { 3075 // mov sequence 3076 intptr_t pos = reinterpret_cast<intptr_t>(target_address_at(pc, code)); 3077 set_target_address_at(isolate(), pc, code, buffer_ + pos, 3078 SKIP_ICACHE_FLUSH); 3079 } 3080 3081 reloc_info_writer.Write(&rinfo); 3082 } 3083 3084 reloc_info_writer.Finish(); 3085} 3086 3087} // namespace internal 3088} // namespace v8 3089#endif // V8_TARGET_ARCH_S390 3090