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