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