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