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