• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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[3] = {0L};
142     // LHI sets up GPR0
143     // STFLE is specified as .insn, as opcode is not recognized.
144     // We register the instructions kill r0 (LHI) and the CC (STFLE).
145     asm volatile(
146         "lhi   0,2\n"
147         ".insn s,0xb2b00000,%0\n"
148         : "=Q"(facilities)
149         :
150         : "cc", "r0");
151 
152     uint64_t one = static_cast<uint64_t>(1);
153     // Test for Distinct Operands Facility - Bit 45
154     if (facilities[0] & (one << (63 - 45))) {
155       supported_ |= (1u << DISTINCT_OPS);
156     }
157     // Test for General Instruction Extension Facility - Bit 34
158     if (facilities[0] & (one << (63 - 34))) {
159       supported_ |= (1u << GENERAL_INSTR_EXT);
160     }
161     // Test for Floating Point Extension Facility - Bit 37
162     if (facilities[0] & (one << (63 - 37))) {
163       supported_ |= (1u << FLOATING_POINT_EXT);
164     }
165     // Test for Vector Facility - Bit 129
166     if (facilities[2] & (one << (63 - (129 - 128)))) {
167       supported_ |= (1u << VECTOR_FACILITY);
168     }
169     // Test for Miscellaneous Instruction Extension Facility - Bit 58
170     if (facilities[0] & (1lu << (63 - 58))) {
171       supported_ |= (1u << MISC_INSTR_EXT2);
172     }
173   }
174 #else
175   // All distinct ops instructions can be simulated
176   supported_ |= (1u << DISTINCT_OPS);
177   // RISBG can be simulated
178   supported_ |= (1u << GENERAL_INSTR_EXT);
179   supported_ |= (1u << FLOATING_POINT_EXT);
180   supported_ |= (1u << MISC_INSTR_EXT2);
181   USE(performSTFLE);  // To avoid assert
182   supported_ |= (1u << VECTOR_FACILITY);
183 #endif
184   supported_ |= (1u << FPU);
185 }
186 
PrintTarget()187 void CpuFeatures::PrintTarget() {
188   const char* s390_arch = NULL;
189 
190 #if V8_TARGET_ARCH_S390X
191   s390_arch = "s390x";
192 #else
193   s390_arch = "s390";
194 #endif
195 
196   printf("target %s\n", s390_arch);
197 }
198 
PrintFeatures()199 void CpuFeatures::PrintFeatures() {
200   printf("FPU=%d\n", CpuFeatures::IsSupported(FPU));
201   printf("FPU_EXT=%d\n", CpuFeatures::IsSupported(FLOATING_POINT_EXT));
202   printf("GENERAL_INSTR=%d\n", CpuFeatures::IsSupported(GENERAL_INSTR_EXT));
203   printf("DISTINCT_OPS=%d\n", CpuFeatures::IsSupported(DISTINCT_OPS));
204   printf("VECTOR_FACILITY=%d\n", CpuFeatures::IsSupported(VECTOR_FACILITY));
205   printf("MISC_INSTR_EXT2=%d\n", CpuFeatures::IsSupported(MISC_INSTR_EXT2));
206 }
207 
ToRegister(int num)208 Register ToRegister(int num) {
209   DCHECK(num >= 0 && num < kNumRegisters);
210   const Register kRegisters[] = {r0, r1, r2,  r3, r4, r5,  r6,  r7,
211                                  r8, r9, r10, fp, ip, r13, r14, sp};
212   return kRegisters[num];
213 }
214 
215 // -----------------------------------------------------------------------------
216 // Implementation of RelocInfo
217 
218 const int RelocInfo::kApplyMask =
219     RelocInfo::kCodeTargetMask | 1 << RelocInfo::INTERNAL_REFERENCE;
220 
IsCodedSpecially()221 bool RelocInfo::IsCodedSpecially() {
222   // The deserializer needs to know whether a pointer is specially
223   // coded.  Being specially coded on S390 means that it is an iihf/iilf
224   // instruction sequence, and that is always the case inside code
225   // objects.
226   return true;
227 }
228 
IsInConstantPool()229 bool RelocInfo::IsInConstantPool() { return false; }
230 
wasm_memory_reference()231 Address RelocInfo::wasm_memory_reference() {
232   DCHECK(IsWasmMemoryReference(rmode_));
233   return Assembler::target_address_at(pc_, host_);
234 }
235 
wasm_memory_size_reference()236 uint32_t RelocInfo::wasm_memory_size_reference() {
237   DCHECK(IsWasmMemorySizeReference(rmode_));
238   return static_cast<uint32_t>(
239       reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_)));
240 }
241 
wasm_global_reference()242 Address RelocInfo::wasm_global_reference() {
243   DCHECK(IsWasmGlobalReference(rmode_));
244   return Assembler::target_address_at(pc_, host_);
245 }
246 
wasm_function_table_size_reference()247 uint32_t RelocInfo::wasm_function_table_size_reference() {
248   DCHECK(IsWasmFunctionTableSizeReference(rmode_));
249   return static_cast<uint32_t>(
250       reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_)));
251 }
252 
unchecked_update_wasm_memory_reference(Address address,ICacheFlushMode flush_mode)253 void RelocInfo::unchecked_update_wasm_memory_reference(
254     Address address, ICacheFlushMode flush_mode) {
255   Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode);
256 }
257 
unchecked_update_wasm_size(uint32_t size,ICacheFlushMode flush_mode)258 void RelocInfo::unchecked_update_wasm_size(uint32_t size,
259                                            ICacheFlushMode flush_mode) {
260   Assembler::set_target_address_at(isolate_, pc_, host_,
261                                    reinterpret_cast<Address>(size), flush_mode);
262 }
263 
264 // -----------------------------------------------------------------------------
265 // Implementation of Operand and MemOperand
266 // See assembler-s390-inl.h for inlined constructors
267 
Operand(Handle<Object> handle)268 Operand::Operand(Handle<Object> handle) {
269   AllowDeferredHandleDereference using_raw_address;
270   rm_ = no_reg;
271   // Verify all Objects referred by code are NOT in new space.
272   Object* obj = *handle;
273   if (obj->IsHeapObject()) {
274     imm_ = reinterpret_cast<intptr_t>(handle.location());
275     rmode_ = RelocInfo::EMBEDDED_OBJECT;
276   } else {
277     // no relocation needed
278     imm_ = reinterpret_cast<intptr_t>(obj);
279     rmode_ = kRelocInfo_NONEPTR;
280   }
281 }
282 
MemOperand(Register rn,int32_t offset)283 MemOperand::MemOperand(Register rn, int32_t offset) {
284   baseRegister = rn;
285   indexRegister = r0;
286   offset_ = offset;
287 }
288 
MemOperand(Register rx,Register rb,int32_t offset)289 MemOperand::MemOperand(Register rx, Register rb, int32_t offset) {
290   baseRegister = rb;
291   indexRegister = rx;
292   offset_ = offset;
293 }
294 
295 // -----------------------------------------------------------------------------
296 // Specific instructions, constants, and masks.
297 
Assembler(Isolate * isolate,void * buffer,int buffer_size)298 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
299     : AssemblerBase(isolate, buffer, buffer_size),
300       recorded_ast_id_(TypeFeedbackId::None()),
301       code_targets_(100) {
302   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
303 
304   last_bound_pos_ = 0;
305   ClearRecordedAstId();
306   relocations_.reserve(128);
307 }
308 
GetCode(CodeDesc * desc)309 void Assembler::GetCode(CodeDesc* desc) {
310   EmitRelocations();
311 
312   // Set up code descriptor.
313   desc->buffer = buffer_;
314   desc->buffer_size = buffer_size_;
315   desc->instr_size = pc_offset();
316   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
317   desc->origin = this;
318   desc->unwinding_info_size = 0;
319   desc->unwinding_info = nullptr;
320 }
321 
Align(int m)322 void Assembler::Align(int m) {
323   DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
324   while ((pc_offset() & (m - 1)) != 0) {
325     nop(0);
326   }
327 }
328 
CodeTargetAlign()329 void Assembler::CodeTargetAlign() { Align(8); }
330 
GetCondition(Instr instr)331 Condition Assembler::GetCondition(Instr instr) {
332   switch (instr & kCondMask) {
333     case BT:
334       return eq;
335     case BF:
336       return ne;
337     default:
338       UNIMPLEMENTED();
339   }
340   return al;
341 }
342 
343 #if V8_TARGET_ARCH_S390X
344 // This code assumes a FIXED_SEQUENCE for 64bit loads (iihf/iilf)
Is64BitLoadIntoIP(SixByteInstr instr1,SixByteInstr instr2)345 bool Assembler::Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2) {
346   // Check the instructions are the iihf/iilf load into ip
347   return (((instr1 >> 32) == 0xC0C8) && ((instr2 >> 32) == 0xC0C9));
348 }
349 #else
350 // This code assumes a FIXED_SEQUENCE for 32bit loads (iilf)
Is32BitLoadIntoIP(SixByteInstr instr)351 bool Assembler::Is32BitLoadIntoIP(SixByteInstr instr) {
352   // Check the instruction is an iilf load into ip/r12.
353   return ((instr >> 32) == 0xC0C9);
354 }
355 #endif
356 
357 // Labels refer to positions in the (to be) generated code.
358 // There are bound, linked, and unused labels.
359 //
360 // Bound labels refer to known positions in the already
361 // generated code. pos() is the position the label refers to.
362 //
363 // Linked labels refer to unknown positions in the code
364 // to be generated; pos() is the position of the last
365 // instruction using the label.
366 
367 // The link chain is terminated by a negative code position (must be aligned)
368 const int kEndOfChain = -4;
369 
370 // Returns the target address of the relative instructions, typically
371 // of the form: pos + imm (where immediate is in # of halfwords for
372 // BR* and LARL).
target_at(int pos)373 int Assembler::target_at(int pos) {
374   SixByteInstr instr = instr_at(pos);
375   // check which type of branch this is 16 or 26 bit offset
376   Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos);
377 
378   if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
379     int16_t imm16 = SIGN_EXT_IMM16((instr & kImm16Mask));
380     imm16 <<= 1;  // BRC immediate is in # of halfwords
381     if (imm16 == 0) return kEndOfChain;
382     return pos + imm16;
383   } else if (LLILF == opcode || BRCL == opcode || LARL == opcode ||
384              BRASL == opcode) {
385     int32_t imm32 =
386         static_cast<int32_t>(instr & (static_cast<uint64_t>(0xffffffff)));
387     if (LLILF != opcode)
388       imm32 <<= 1;  // BR* + LARL treat immediate in # of halfwords
389     if (imm32 == 0) return kEndOfChain;
390     return pos + imm32;
391   }
392 
393   // Unknown condition
394   DCHECK(false);
395   return -1;
396 }
397 
398 // Update the target address of the current relative instruction.
target_at_put(int pos,int target_pos,bool * is_branch)399 void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
400   SixByteInstr instr = instr_at(pos);
401   Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos);
402 
403   if (is_branch != nullptr) {
404     *is_branch = (opcode == BRC || opcode == BRCT || opcode == BRCTG ||
405                   opcode == BRCL || opcode == BRASL);
406   }
407 
408   if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
409     int16_t imm16 = target_pos - pos;
410     instr &= (~0xffff);
411     DCHECK(is_int16(imm16));
412     instr_at_put<FourByteInstr>(pos, instr | (imm16 >> 1));
413     return;
414   } else if (BRCL == opcode || LARL == opcode || BRASL == opcode) {
415     // Immediate is in # of halfwords
416     int32_t imm32 = target_pos - pos;
417     instr &= (~static_cast<uint64_t>(0xffffffff));
418     instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1));
419     return;
420   } else if (LLILF == opcode) {
421     DCHECK(target_pos == kEndOfChain || target_pos >= 0);
422     // Emitted label constant, not part of a branch.
423     // Make label relative to Code* of generated Code object.
424     int32_t imm32 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
425     instr &= (~static_cast<uint64_t>(0xffffffff));
426     instr_at_put<SixByteInstr>(pos, instr | imm32);
427     return;
428   }
429   DCHECK(false);
430 }
431 
432 // Returns the maximum number of bits given instruction can address.
max_reach_from(int pos)433 int Assembler::max_reach_from(int pos) {
434   Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos);
435 
436   // Check which type of instr.  In theory, we can return
437   // the values below + 1, given offset is # of halfwords
438   if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
439     return 16;
440   } else if (LLILF == opcode || BRCL == opcode || LARL == opcode ||
441              BRASL == opcode) {
442     return 31;  // Using 31 as workaround instead of 32 as
443                 // is_intn(x,32) doesn't work on 32-bit platforms.
444                 // llilf: Emitted label constant, not part of
445                 //        a branch (regexp PushBacktrack).
446   }
447   DCHECK(false);
448   return 16;
449 }
450 
bind_to(Label * L,int pos)451 void Assembler::bind_to(Label* L, int pos) {
452   DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
453   bool is_branch = false;
454   while (L->is_linked()) {
455     int fixup_pos = L->pos();
456 #ifdef DEBUG
457     int32_t offset = pos - fixup_pos;
458     int maxReach = max_reach_from(fixup_pos);
459 #endif
460     next(L);  // call next before overwriting link with target at fixup_pos
461     DCHECK(is_intn(offset, maxReach));
462     target_at_put(fixup_pos, pos, &is_branch);
463   }
464   L->bind_to(pos);
465 
466   // Keep track of the last bound label so we don't eliminate any instructions
467   // before a bound label.
468   if (pos > last_bound_pos_) last_bound_pos_ = pos;
469 }
470 
bind(Label * L)471 void Assembler::bind(Label* L) {
472   DCHECK(!L->is_bound());  // label can only be bound once
473   bind_to(L, pc_offset());
474 }
475 
next(Label * L)476 void Assembler::next(Label* L) {
477   DCHECK(L->is_linked());
478   int link = target_at(L->pos());
479   if (link == kEndOfChain) {
480     L->Unuse();
481   } else {
482     DCHECK(link >= 0);
483     L->link_to(link);
484   }
485 }
486 
is_near(Label * L,Condition cond)487 bool Assembler::is_near(Label* L, Condition cond) {
488   DCHECK(L->is_bound());
489   if (L->is_bound() == false) return false;
490 
491   int maxReach = ((cond == al) ? 26 : 16);
492   int offset = L->pos() - pc_offset();
493 
494   return is_intn(offset, maxReach);
495 }
496 
link(Label * L)497 int Assembler::link(Label* L) {
498   int position;
499   if (L->is_bound()) {
500     position = L->pos();
501   } else {
502     if (L->is_linked()) {
503       position = L->pos();  // L's link
504     } else {
505       // was: target_pos = kEndOfChain;
506       // However, using self to mark the first reference
507       // should avoid most instances of branch offset overflow.  See
508       // target_at() for where this is converted back to kEndOfChain.
509       position = pc_offset();
510     }
511     L->link_to(pc_offset());
512   }
513 
514   return position;
515 }
516 
load_label_offset(Register r1,Label * L)517 void Assembler::load_label_offset(Register r1, Label* L) {
518   int target_pos;
519   int constant;
520   if (L->is_bound()) {
521     target_pos = L->pos();
522     constant = target_pos + (Code::kHeaderSize - kHeapObjectTag);
523   } else {
524     if (L->is_linked()) {
525       target_pos = L->pos();  // L's link
526     } else {
527       // was: target_pos = kEndOfChain;
528       // However, using branch to self to mark the first reference
529       // should avoid most instances of branch offset overflow.  See
530       // target_at() for where this is converted back to kEndOfChain.
531       target_pos = pc_offset();
532     }
533     L->link_to(pc_offset());
534 
535     constant = target_pos - pc_offset();
536   }
537   llilf(r1, Operand(constant));
538 }
539 
540 // Pseudo op - branch on condition
branchOnCond(Condition c,int branch_offset,bool is_bound)541 void Assembler::branchOnCond(Condition c, int branch_offset, bool is_bound) {
542   int offset_in_halfwords = branch_offset / 2;
543   if (is_bound && is_int16(offset_in_halfwords)) {
544     brc(c, Operand(offset_in_halfwords));  // short jump
545   } else {
546     brcl(c, Operand(offset_in_halfwords));  // long jump
547   }
548 }
549 
550 // 32-bit Store Multiple - short displacement (12-bits unsigned)
stm(Register r1,Register r2,const MemOperand & src)551 void Assembler::stm(Register r1, Register r2, const MemOperand& src) {
552   rs_form(STM, r1, r2, src.rb(), src.offset());
553 }
554 
555 // 32-bit Store Multiple - long displacement (20-bits signed)
stmy(Register r1,Register r2,const MemOperand & src)556 void Assembler::stmy(Register r1, Register r2, const MemOperand& src) {
557   rsy_form(STMY, r1, r2, src.rb(), src.offset());
558 }
559 
560 // 64-bit Store Multiple - long displacement (20-bits signed)
stmg(Register r1,Register r2,const MemOperand & src)561 void Assembler::stmg(Register r1, Register r2, const MemOperand& src) {
562   rsy_form(STMG, r1, r2, src.rb(), src.offset());
563 }
564 
565 // Exception-generating instructions and debugging support.
566 // Stops with a non-negative code less than kNumOfWatchedStops support
567 // enabling/disabling and a counter feature. See simulator-s390.h .
stop(const char * msg,Condition cond,int32_t code,CRegister cr)568 void Assembler::stop(const char* msg, Condition cond, int32_t code,
569                      CRegister cr) {
570   if (cond != al) {
571     Label skip;
572     b(NegateCondition(cond), &skip, Label::kNear);
573     bkpt(0);
574     bind(&skip);
575   } else {
576     bkpt(0);
577   }
578 }
579 
bkpt(uint32_t imm16)580 void Assembler::bkpt(uint32_t imm16) {
581   // GDB software breakpoint instruction
582   emit2bytes(0x0001);
583 }
584 
585 // Pseudo instructions.
nop(int type)586 void Assembler::nop(int type) {
587   switch (type) {
588     case 0:
589       lr(r0, r0);
590       break;
591     case DEBUG_BREAK_NOP:
592       // TODO(john.yan): Use a better NOP break
593       oill(r3, Operand::Zero());
594       break;
595     default:
596       UNIMPLEMENTED();
597   }
598 }
599 
600 
601 
602 // RI1 format: <insn> R1,I2
603 //    +--------+----+----+------------------+
604 //    | OpCode | R1 |OpCd|        I2        |
605 //    +--------+----+----+------------------+
606 //    0        8    12   16                31
607 #define RI1_FORM_EMIT(name, op) \
608   void Assembler::name(Register r, const Operand& i2) { ri_form(op, r, i2); }
609 
ri_form(Opcode op,Register r1,const Operand & i2)610 void Assembler::ri_form(Opcode op, Register r1, const Operand& i2) {
611   DCHECK(is_uint12(op));
612   DCHECK(is_uint16(i2.imm_) || is_int16(i2.imm_));
613   emit4bytes((op & 0xFF0) * B20 | r1.code() * B20 | (op & 0xF) * B16 |
614              (i2.imm_ & 0xFFFF));
615 }
616 
617 // RI2 format: <insn> M1,I2
618 //    +--------+----+----+------------------+
619 //    | OpCode | M1 |OpCd|        I2        |
620 //    +--------+----+----+------------------+
621 //    0        8    12   16                31
622 #define RI2_FORM_EMIT(name, op) \
623   void Assembler::name(Condition m, const Operand& i2) { ri_form(op, m, i2); }
624 
ri_form(Opcode op,Condition m1,const Operand & i2)625 void Assembler::ri_form(Opcode op, Condition m1, const Operand& i2) {
626   DCHECK(is_uint12(op));
627   DCHECK(is_uint4(m1));
628   DCHECK(op == BRC ? is_int16(i2.imm_) : is_uint16(i2.imm_));
629   emit4bytes((op & 0xFF0) * B20 | m1 * B20 | (op & 0xF) * B16 |
630              (i2.imm_ & 0xFFFF));
631 }
632 
633 // RIE-f format: <insn> R1,R2,I3,I4,I5
634 //    +--------+----+----+------------------+--------+--------+
635 //    | OpCode | R1 | R2 |   I3   |    I4   |   I5   | OpCode |
636 //    +--------+----+----+------------------+--------+--------+
637 //    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)638 void Assembler::rie_f_form(Opcode op, Register r1, Register r2,
639                            const Operand& i3, const Operand& i4,
640                            const Operand& i5) {
641   DCHECK(is_uint16(op));
642   DCHECK(is_uint8(i3.imm_));
643   DCHECK(is_uint8(i4.imm_));
644   DCHECK(is_uint8(i5.imm_));
645   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
646                   (static_cast<uint64_t>(r1.code())) * B36 |
647                   (static_cast<uint64_t>(r2.code())) * B32 |
648                   (static_cast<uint64_t>(i3.imm_)) * B24 |
649                   (static_cast<uint64_t>(i4.imm_)) * B16 |
650                   (static_cast<uint64_t>(i5.imm_)) * B8 |
651                   (static_cast<uint64_t>(op & 0x00FF));
652   emit6bytes(code);
653 }
654 
655 // RIE format: <insn> R1,R3,I2
656 //    +--------+----+----+------------------+--------+--------+
657 //    | OpCode | R1 | R3 |        I2        |////////| OpCode |
658 //    +--------+----+----+------------------+--------+--------+
659 //    0        8    12   16                 32       40      47
660 #define RIE_FORM_EMIT(name, op)                                       \
661   void Assembler::name(Register r1, Register r3, const Operand& i2) { \
662     rie_form(op, r1, r3, i2);                                         \
663   }
664 
rie_form(Opcode op,Register r1,Register r3,const Operand & i2)665 void Assembler::rie_form(Opcode op, Register r1, Register r3,
666                          const Operand& i2) {
667   DCHECK(is_uint16(op));
668   DCHECK(is_int16(i2.imm_));
669   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
670                   (static_cast<uint64_t>(r1.code())) * B36 |
671                   (static_cast<uint64_t>(r3.code())) * B32 |
672                   (static_cast<uint64_t>(i2.imm_ & 0xFFFF)) * B16 |
673                   (static_cast<uint64_t>(op & 0x00FF));
674   emit6bytes(code);
675 }
676 
677 // RS1 format: <insn> R1,R3,D2(B2)
678 //    +--------+----+----+----+-------------+
679 //    | OpCode | R1 | R3 | B2 |     D2      |
680 //    +--------+----+----+----+-------------+
681 //    0        8    12   16   20           31
682 #define RS1_FORM_EMIT(name, op)                                            \
683   void Assembler::name(Register r1, Register r3, Register b2, Disp d2) {   \
684     rs_form(op, r1, r3, b2, d2);                                           \
685   }                                                                        \
686   void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \
687     name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement());          \
688   }
689 
rs_form(Opcode op,Register r1,Register r3,Register b2,const Disp d2)690 void Assembler::rs_form(Opcode op, Register r1, Register r3, Register b2,
691                         const Disp d2) {
692   DCHECK(is_uint12(d2));
693   emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | b2.code() * B12 |
694              d2);
695 }
696 
697 // RS2 format: <insn> R1,M3,D2(B2)
698 //    +--------+----+----+----+-------------+
699 //    | OpCode | R1 | M3 | B2 |     D2      |
700 //    +--------+----+----+----+-------------+
701 //    0        8    12   16   20           31
702 #define RS2_FORM_EMIT(name, op)                                             \
703   void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) {   \
704     rs_form(op, r1, m3, b2, d2);                                            \
705   }                                                                         \
706   void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \
707     name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement());           \
708   }
709 
rs_form(Opcode op,Register r1,Condition m3,Register b2,const Disp d2)710 void Assembler::rs_form(Opcode op, Register r1, Condition m3, Register b2,
711                         const Disp d2) {
712   DCHECK(is_uint12(d2));
713   emit4bytes(op * B24 | r1.code() * B20 | m3 * B16 | b2.code() * B12 | d2);
714 }
715 
716 // RSI format: <insn> R1,R3,I2
717 //    +--------+----+----+------------------+
718 //    | OpCode | R1 | R3 |        RI2       |
719 //    +--------+----+----+------------------+
720 //    0        8    12   16                 31
721 #define RSI_FORM_EMIT(name, op)                                       \
722   void Assembler::name(Register r1, Register r3, const Operand& i2) { \
723     rsi_form(op, r1, r3, i2);                                         \
724   }
725 
rsi_form(Opcode op,Register r1,Register r3,const Operand & i2)726 void Assembler::rsi_form(Opcode op, Register r1, Register r3,
727                          const Operand& i2) {
728   DCHECK(is_uint8(op));
729   DCHECK(is_uint16(i2.imm_));
730   emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | (i2.imm_ & 0xFFFF));
731 }
732 
733 // RSL format: <insn> R1,R3,D2(B2)
734 //    +--------+----+----+----+-------------+--------+--------+
735 //    | OpCode | L1 |    | B2 |    D2       |        | OpCode |
736 //    +--------+----+----+----+-------------+--------+--------+
737 //    0        8    12   16   20            32       40      47
738 #define RSL_FORM_EMIT(name, op)                           \
739   void Assembler::name(Length l1, Register b2, Disp d2) { \
740     rsl_form(op, l1, b2, d2);                             \
741   }
742 
rsl_form(Opcode op,Length l1,Register b2,Disp d2)743 void Assembler::rsl_form(Opcode op, Length l1, Register b2, Disp d2) {
744   DCHECK(is_uint16(op));
745   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
746                   (static_cast<uint64_t>(l1)) * B36 |
747                   (static_cast<uint64_t>(b2.code())) * B28 |
748                   (static_cast<uint64_t>(d2)) * B16 |
749                   (static_cast<uint64_t>(op & 0x00FF));
750   emit6bytes(code);
751 }
752 
753 // RSY1 format: <insn> R1,R3,D2(B2)
754 //    +--------+----+----+----+-------------+--------+--------+
755 //    | OpCode | R1 | R3 | B2 |    DL2      |  DH2   | OpCode |
756 //    +--------+----+----+----+-------------+--------+--------+
757 //    0        8    12   16   20            32       40      47
758 #define RSY1_FORM_EMIT(name, op)                                           \
759   void Assembler::name(Register r1, Register r3, Register b2, Disp d2) {   \
760     rsy_form(op, r1, r3, b2, d2);                                          \
761   }                                                                        \
762   void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \
763     name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement());          \
764   }
765 
rsy_form(Opcode op,Register r1,Register r3,Register b2,const Disp d2)766 void Assembler::rsy_form(Opcode op, Register r1, Register r3, Register b2,
767                          const Disp d2) {
768   DCHECK(is_int20(d2));
769   DCHECK(is_uint16(op));
770   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
771                   (static_cast<uint64_t>(r1.code())) * B36 |
772                   (static_cast<uint64_t>(r3.code())) * B32 |
773                   (static_cast<uint64_t>(b2.code())) * B28 |
774                   (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
775                   (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 |
776                   (static_cast<uint64_t>(op & 0x00FF));
777   emit6bytes(code);
778 }
779 
780 // RSY2 format: <insn> R1,M3,D2(B2)
781 //    +--------+----+----+----+-------------+--------+--------+
782 //    | OpCode | R1 | M3 | B2 |    DL2      |  DH2   | OpCode |
783 //    +--------+----+----+----+-------------+--------+--------+
784 //    0        8    12   16   20            32       40      47
785 #define RSY2_FORM_EMIT(name, op)                                            \
786   void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) {   \
787     rsy_form(op, r1, m3, b2, d2);                                           \
788   }                                                                         \
789   void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \
790     name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement());           \
791   }
792 
rsy_form(Opcode op,Register r1,Condition m3,Register b2,const Disp d2)793 void Assembler::rsy_form(Opcode op, Register r1, Condition m3, Register b2,
794                          const Disp d2) {
795   DCHECK(is_int20(d2));
796   DCHECK(is_uint16(op));
797   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
798                   (static_cast<uint64_t>(r1.code())) * B36 |
799                   (static_cast<uint64_t>(m3)) * B32 |
800                   (static_cast<uint64_t>(b2.code())) * B28 |
801                   (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
802                   (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 |
803                   (static_cast<uint64_t>(op & 0x00FF));
804   emit6bytes(code);
805 }
806 
807 // RXE format: <insn> R1,D2(X2,B2)
808 //    +--------+----+----+----+-------------+--------+--------+
809 //    | OpCode | R1 | X2 | B2 |     D2      |////////| OpCode |
810 //    +--------+----+----+----+-------------+--------+--------+
811 //    0        8    12   16   20            32       40      47
812 #define RXE_FORM_EMIT(name, op)                                          \
813   void Assembler::name(Register r1, Register x2, Register b2, Disp d2) { \
814     rxe_form(op, r1, x2, b2, d2);                                        \
815   }                                                                      \
816   void Assembler::name(Register r1, const MemOperand& opnd) {            \
817     name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(),            \
818          opnd.getDisplacement());                                        \
819   }
820 
rxe_form(Opcode op,Register r1,Register x2,Register b2,Disp d2)821 void Assembler::rxe_form(Opcode op, Register r1, Register x2, Register b2,
822                          Disp d2) {
823   DCHECK(is_uint12(d2));
824   DCHECK(is_uint16(op));
825   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
826                   (static_cast<uint64_t>(r1.code())) * B36 |
827                   (static_cast<uint64_t>(x2.code())) * B32 |
828                   (static_cast<uint64_t>(b2.code())) * B28 |
829                   (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
830                   (static_cast<uint64_t>(op & 0x00FF));
831   emit6bytes(code);
832 }
833 
834 // RRS format: <insn> R1,R2,M3,D4(B4)
835 //    +--------+----+----+----+-------------+----+---+--------+
836 //    | OpCode | R1 | R2 | B4 |     D4      | M3 |///| OpCode |
837 //    +--------+----+----+----+-------------+----+---+--------+
838 //    0        8    12   16   20            32   36   40      47
839 #define RRS_FORM_EMIT(name, op)                                        \
840   void Assembler::name(Register r1, Register r2, Register b4, Disp d4, \
841                        Condition m3) {                                 \
842     rrs_form(op, r1, r2, b4, d4, m3);                                  \
843   }                                                                    \
844   void Assembler::name(Register r1, Register r2, Condition m3,         \
845                        const MemOperand& opnd) {                       \
846     name(r1, r2, opnd.getBaseRegister(), opnd.getDisplacement(), m3);  \
847   }
848 
rrs_form(Opcode op,Register r1,Register r2,Register b4,Disp d4,Condition m3)849 void Assembler::rrs_form(Opcode op, Register r1, Register r2, Register b4,
850                          Disp d4, Condition m3) {
851   DCHECK(is_uint12(d4));
852   DCHECK(is_uint16(op));
853   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
854                   (static_cast<uint64_t>(r1.code())) * B36 |
855                   (static_cast<uint64_t>(r2.code())) * B32 |
856                   (static_cast<uint64_t>(b4.code())) * B28 |
857                   (static_cast<uint64_t>(d4)) * B16 |
858                   (static_cast<uint64_t>(m3)) << 12 |
859                   (static_cast<uint64_t>(op & 0x00FF));
860   emit6bytes(code);
861 }
862 
863 // RIS format: <insn> R1,I2,M3,D4(B4)
864 //    +--------+----+----+----+-------------+--------+--------+
865 //    | OpCode | R1 | M3 | B4 |     D4      |   I2   | OpCode |
866 //    +--------+----+----+----+-------------+--------+--------+
867 //    0        8    12   16   20            32        40      47
868 #define RIS_FORM_EMIT(name, op)                                         \
869   void Assembler::name(Register r1, Condition m3, Register b4, Disp d4, \
870                        const Operand& i2) {                             \
871     ris_form(op, r1, m3, b4, d4, i2);                                   \
872   }                                                                     \
873   void Assembler::name(Register r1, const Operand& i2, Condition m3,    \
874                        const MemOperand& opnd) {                        \
875     name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement(), i2);   \
876   }
877 
ris_form(Opcode op,Register r1,Condition m3,Register b4,Disp d4,const Operand & i2)878 void Assembler::ris_form(Opcode op, Register r1, Condition m3, Register b4,
879                          Disp d4, const Operand& i2) {
880   DCHECK(is_uint12(d4));
881   DCHECK(is_uint16(op));
882   DCHECK(is_uint8(i2.imm_));
883   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
884                   (static_cast<uint64_t>(r1.code())) * B36 |
885                   (static_cast<uint64_t>(m3)) * B32 |
886                   (static_cast<uint64_t>(b4.code())) * B28 |
887                   (static_cast<uint64_t>(d4)) * B16 |
888                   (static_cast<uint64_t>(i2.imm_)) << 8 |
889                   (static_cast<uint64_t>(op & 0x00FF));
890   emit6bytes(code);
891 }
892 
893 // S format: <insn> D2(B2)
894 //    +------------------+----+-------------+
895 //    |      OpCode      | B2 |     D2      |
896 //    +------------------+----+-------------+
897 //    0                  16   20           31
898 #define S_FORM_EMIT(name, op)                                        \
899   void Assembler::name(Register b1, Disp d2) { s_form(op, b1, d2); } \
900   void Assembler::name(const MemOperand& opnd) {                     \
901     name(opnd.getBaseRegister(), opnd.getDisplacement());            \
902   }
903 
s_form(Opcode op,Register b1,Disp d2)904 void Assembler::s_form(Opcode op, Register b1, Disp d2) {
905   DCHECK(is_uint12(d2));
906   emit4bytes(op << 16 | b1.code() * B12 | d2);
907 }
908 
909 // SI format: <insn> D1(B1),I2
910 //    +--------+---------+----+-------------+
911 //    | OpCode |   I2    | B1 |     D1      |
912 //    +--------+---------+----+-------------+
913 //    0        8         16   20           31
914 #define SI_FORM_EMIT(name, op)                                      \
915   void Assembler::name(const Operand& i2, Register b1, Disp d1) {   \
916     si_form(op, i2, b1, d1);                                        \
917   }                                                                 \
918   void Assembler::name(const MemOperand& opnd, const Operand& i2) { \
919     name(i2, opnd.getBaseRegister(), opnd.getDisplacement());       \
920   }
921 
si_form(Opcode op,const Operand & i2,Register b1,Disp d1)922 void Assembler::si_form(Opcode op, const Operand& i2, Register b1, Disp d1) {
923   emit4bytes((op & 0x00FF) << 24 | i2.imm_ * B16 | b1.code() * B12 | d1);
924 }
925 
926 // SIY format: <insn> D1(B1),I2
927 //    +--------+---------+----+-------------+--------+--------+
928 //    | OpCode |   I2    | B1 |     DL1     |  DH1   | OpCode |
929 //    +--------+---------+----+-------------+--------+--------+
930 //    0        8         16   20            32   36   40      47
931 #define SIY_FORM_EMIT(name, op)                                     \
932   void Assembler::name(const Operand& i2, Register b1, Disp d1) {   \
933     siy_form(op, i2, b1, d1);                                       \
934   }                                                                 \
935   void Assembler::name(const MemOperand& opnd, const Operand& i2) { \
936     name(i2, opnd.getBaseRegister(), opnd.getDisplacement());       \
937   }
938 
siy_form(Opcode op,const Operand & i2,Register b1,Disp d1)939 void Assembler::siy_form(Opcode op, const Operand& i2, Register b1, Disp d1) {
940   DCHECK(is_uint20(d1) || is_int20(d1));
941   DCHECK(is_uint16(op));
942   DCHECK(is_uint8(i2.imm_));
943   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
944                   (static_cast<uint64_t>(i2.imm_)) * B32 |
945                   (static_cast<uint64_t>(b1.code())) * B28 |
946                   (static_cast<uint64_t>(d1 & 0x0FFF)) * B16 |
947                   (static_cast<uint64_t>(d1 & 0x0FF000)) >> 4 |
948                   (static_cast<uint64_t>(op & 0x00FF));
949   emit6bytes(code);
950 }
951 
952 // SIL format: <insn> D1(B1),I2
953 //    +------------------+----+-------------+-----------------+
954 //    |     OpCode       | B1 |      D1     |        I2       |
955 //    +------------------+----+-------------+-----------------+
956 //    0                 16   20            32                47
957 #define SIL_FORM_EMIT(name, op)                                     \
958   void Assembler::name(Register b1, Disp d1, const Operand& i2) {   \
959     sil_form(op, b1, d1, i2);                                       \
960   }                                                                 \
961   void Assembler::name(const MemOperand& opnd, const Operand& i2) { \
962     name(opnd.getBaseRegister(), opnd.getDisplacement(), i2);       \
963   }
964 
sil_form(Opcode op,Register b1,Disp d1,const Operand & i2)965 void Assembler::sil_form(Opcode op, Register b1, Disp d1, const Operand& i2) {
966   DCHECK(is_uint12(d1));
967   DCHECK(is_uint16(op));
968   DCHECK(is_uint16(i2.imm_));
969   uint64_t code = (static_cast<uint64_t>(op)) * B32 |
970                   (static_cast<uint64_t>(b1.code())) * B28 |
971                   (static_cast<uint64_t>(d1)) * B16 |
972                   (static_cast<uint64_t>(i2.imm_));
973   emit6bytes(code);
974 }
975 
976 // RXF format: <insn> R1,R3,D2(X2,B2)
977 //    +--------+----+----+----+-------------+----+---+--------+
978 //    | OpCode | R3 | X2 | B2 |     D2      | R1 |///| OpCode |
979 //    +--------+----+----+----+-------------+----+---+--------+
980 //    0        8    12   16   20            32   36  40      47
981 #define RXF_FORM_EMIT(name, op)                                            \
982   void Assembler::name(Register r1, Register r3, Register b2, Register x2, \
983                        Disp d2) {                                          \
984     rxf_form(op, r1, r3, b2, x2, d2);                                      \
985   }                                                                        \
986   void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \
987     name(r1, r3, opnd.getBaseRegister(), opnd.getIndexRegister(),          \
988          opnd.getDisplacement());                                          \
989   }
990 
rxf_form(Opcode op,Register r1,Register r3,Register b2,Register x2,Disp d2)991 void Assembler::rxf_form(Opcode op, Register r1, Register r3, Register b2,
992                          Register x2, Disp d2) {
993   DCHECK(is_uint12(d2));
994   DCHECK(is_uint16(op));
995   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
996                   (static_cast<uint64_t>(r3.code())) * B36 |
997                   (static_cast<uint64_t>(x2.code())) * B32 |
998                   (static_cast<uint64_t>(b2.code())) * B28 |
999                   (static_cast<uint64_t>(d2)) * B16 |
1000                   (static_cast<uint64_t>(r1.code())) * B12 |
1001                   (static_cast<uint64_t>(op & 0x00FF));
1002   emit6bytes(code);
1003 }
1004 
1005 // SS1 format: <insn> D1(L,B1),D2(B3)
1006 //    +--------+----+----+----+-------------+----+------------+
1007 //    | OpCode |    L    | B1 |     D1      | B2 |     D2     |
1008 //    +--------+----+----+----+-------------+----+------------+
1009 //    0        8    12   16   20            32   36          47
1010 #define SS1_FORM_EMIT(name, op)                                                \
1011   void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l) { \
1012     ss_form(op, l, b1, d1, b2, d2);                                            \
1013   }                                                                            \
1014   void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2,       \
1015                        Length length) {                                        \
1016     name(opnd1.getBaseRegister(), opnd1.getDisplacement(),                     \
1017          opnd2.getBaseRegister(), opnd2.getDisplacement(), length);            \
1018   }
1019 
ss_form(Opcode op,Length l,Register b1,Disp d1,Register b2,Disp d2)1020 void Assembler::ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2,
1021                         Disp d2) {
1022   DCHECK(is_uint12(d2));
1023   DCHECK(is_uint12(d1));
1024   DCHECK(is_uint8(op));
1025   DCHECK(is_uint8(l));
1026   uint64_t code =
1027       (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l)) * B32 |
1028       (static_cast<uint64_t>(b1.code())) * B28 |
1029       (static_cast<uint64_t>(d1)) * B16 |
1030       (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2));
1031   emit6bytes(code);
1032 }
1033 
1034 // SS2 format: <insn> D1(L1,B1), D2(L3,B3)
1035 //    +--------+----+----+----+-------------+----+------------+
1036 //    | OpCode | L1 | L2 | B1 |     D1      | B2 |     D2     |
1037 //    +--------+----+----+----+-------------+----+------------+
1038 //    0        8    12   16   20            32   36          47
1039 #define SS2_FORM_EMIT(name, op)                                               \
1040   void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l1, \
1041                        Length l2) {                                           \
1042     ss_form(op, l1, l2, b1, d1, b2, d2);                                      \
1043   }                                                                           \
1044   void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2,      \
1045                        Length length1, Length length2) {                      \
1046     name(opnd1.getBaseRegister(), opnd1.getDisplacement(),                    \
1047          opnd2.getBaseRegister(), opnd2.getDisplacement(), length1, length2); \
1048   }
1049 
ss_form(Opcode op,Length l1,Length l2,Register b1,Disp d1,Register b2,Disp d2)1050 void Assembler::ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1,
1051                         Register b2, Disp d2) {
1052   DCHECK(is_uint12(d2));
1053   DCHECK(is_uint12(d1));
1054   DCHECK(is_uint8(op));
1055   DCHECK(is_uint4(l2));
1056   DCHECK(is_uint4(l1));
1057   uint64_t code =
1058       (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 |
1059       (static_cast<uint64_t>(l2)) * B32 |
1060       (static_cast<uint64_t>(b1.code())) * B28 |
1061       (static_cast<uint64_t>(d1)) * B16 |
1062       (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2));
1063   emit6bytes(code);
1064 }
1065 
1066 // SS3 format: <insn> D1(L1,B1), D2(I3,B2)
1067 //    +--------+----+----+----+-------------+----+------------+
1068 //    | OpCode | L1 | I3 | B1 |     D1      | B2 |     D2     |
1069 //    +--------+----+----+----+-------------+----+------------+
1070 //    0        8    12   16   20            32   36          47
1071 #define SS3_FORM_EMIT(name, op)                                              \
1072   void Assembler::name(const Operand& i3, Register b1, Disp d1, Register b2, \
1073                        Disp d2, Length l1) {                                 \
1074     ss_form(op, l1, i3, b1, d1, b2, d2);                                     \
1075   }                                                                          \
1076   void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2,     \
1077                        Length length) {                                      \
1078     DCHECK(false);                                                           \
1079   }
ss_form(Opcode op,Length l1,const Operand & i3,Register b1,Disp d1,Register b2,Disp d2)1080 void Assembler::ss_form(Opcode op, Length l1, const Operand& i3, Register b1,
1081                         Disp d1, Register b2, Disp d2) {
1082   DCHECK(is_uint12(d2));
1083   DCHECK(is_uint12(d1));
1084   DCHECK(is_uint8(op));
1085   DCHECK(is_uint4(l1));
1086   DCHECK(is_uint4(i3.imm_));
1087   uint64_t code =
1088       (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 |
1089       (static_cast<uint64_t>(i3.imm_)) * B32 |
1090       (static_cast<uint64_t>(b1.code())) * B28 |
1091       (static_cast<uint64_t>(d1)) * B16 |
1092       (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2));
1093   emit6bytes(code);
1094 }
1095 
1096 // SS4 format: <insn> D1(R1,B1), D2(R3,B2)
1097 //    +--------+----+----+----+-------------+----+------------+
1098 //    | OpCode | R1 | R3 | B1 |     D1      | B2 |     D2     |
1099 //    +--------+----+----+----+-------------+----+------------+
1100 //    0        8    12   16   20            32   36          47
1101 #define SS4_FORM_EMIT(name, op)                                            \
1102   void Assembler::name(Register r1, Register r3, Register b1, Disp d1,     \
1103                        Register b2, Disp d2) {                             \
1104     ss_form(op, r1, r3, b1, d1, b2, d2);                                   \
1105   }                                                                        \
1106   void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \
1107     DCHECK(false);                                                         \
1108   }
ss_form(Opcode op,Register r1,Register r3,Register b1,Disp d1,Register b2,Disp d2)1109 void Assembler::ss_form(Opcode op, Register r1, Register r3, Register b1,
1110                         Disp d1, Register b2, Disp d2) {
1111   DCHECK(is_uint12(d2));
1112   DCHECK(is_uint12(d1));
1113   DCHECK(is_uint8(op));
1114   uint64_t code = (static_cast<uint64_t>(op)) * B40 |
1115                   (static_cast<uint64_t>(r1.code())) * B36 |
1116                   (static_cast<uint64_t>(r3.code())) * B32 |
1117                   (static_cast<uint64_t>(b1.code())) * B28 |
1118                   (static_cast<uint64_t>(d1)) * B16 |
1119                   (static_cast<uint64_t>(b2.code())) * B12 |
1120                   (static_cast<uint64_t>(d2));
1121   emit6bytes(code);
1122 }
1123 
1124 // SS5 format: <insn> D1(R1,B1), D2(R3,B2)
1125 //    +--------+----+----+----+-------------+----+------------+
1126 //    | OpCode | R1 | R3 | B2 |     D2      | B4 |     D4     |
1127 //    +--------+----+----+----+-------------+----+------------+
1128 //    0        8    12   16   20            32   36          47
1129 #define SS5_FORM_EMIT(name, op)                                            \
1130   void Assembler::name(Register r1, Register r3, Register b2, Disp d2,     \
1131                        Register b4, Disp d4) {                             \
1132     ss_form(op, r1, r3, b2, d2, b4, d4); /*SS5 use the same form as SS4*/  \
1133   }                                                                        \
1134   void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \
1135     DCHECK(false);                                                         \
1136   }
1137 
1138 #define SS6_FORM_EMIT(name, op) SS1_FORM_EMIT(name, op)
1139 
1140 // SSE format: <insn> D1(B1),D2(B2)
1141 //    +------------------+----+-------------+----+------------+
1142 //    |      OpCode      | B1 |     D1      | B2 |     D2     |
1143 //    +------------------+----+-------------+----+------------+
1144 //    0        8    12   16   20            32   36           47
1145 #define SSE_FORM_EMIT(name, op)                                            \
1146   void Assembler::name(Register b1, Disp d1, Register b2, Disp d2) {       \
1147     sse_form(op, b1, d1, b2, d2);                                          \
1148   }                                                                        \
1149   void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \
1150     name(opnd1.getBaseRegister(), opnd1.getDisplacement(),                 \
1151          opnd2.getBaseRegister(), opnd2.getDisplacement());                \
1152   }
sse_form(Opcode op,Register b1,Disp d1,Register b2,Disp d2)1153 void Assembler::sse_form(Opcode op, Register b1, Disp d1, Register b2,
1154                          Disp d2) {
1155   DCHECK(is_uint12(d2));
1156   DCHECK(is_uint12(d1));
1157   DCHECK(is_uint16(op));
1158   uint64_t code = (static_cast<uint64_t>(op)) * B32 |
1159                   (static_cast<uint64_t>(b1.code())) * B28 |
1160                   (static_cast<uint64_t>(d1)) * B16 |
1161                   (static_cast<uint64_t>(b2.code())) * B12 |
1162                   (static_cast<uint64_t>(d2));
1163   emit6bytes(code);
1164 }
1165 
1166 // SSF format: <insn> R3, D1(B1),D2(B2),R3
1167 //    +--------+----+----+----+-------------+----+------------+
1168 //    | OpCode | R3 |OpCd| B1 |     D1      | B2 |     D2     |
1169 //    +--------+----+----+----+-------------+----+------------+
1170 //    0        8    12   16   20            32   36           47
1171 #define SSF_FORM_EMIT(name, op)                                        \
1172   void Assembler::name(Register r3, Register b1, Disp d1, Register b2, \
1173                        Disp d2) {                                      \
1174     ssf_form(op, r3, b1, d1, b2, d2);                                  \
1175   }                                                                    \
1176   void Assembler::name(Register r3, const MemOperand& opnd1,           \
1177                        const MemOperand& opnd2) {                      \
1178     name(r3, opnd1.getBaseRegister(), opnd1.getDisplacement(),         \
1179          opnd2.getBaseRegister(), opnd2.getDisplacement());            \
1180   }
1181 
ssf_form(Opcode op,Register r3,Register b1,Disp d1,Register b2,Disp d2)1182 void Assembler::ssf_form(Opcode op, Register r3, Register b1, Disp d1,
1183                          Register b2, Disp d2) {
1184   DCHECK(is_uint12(d2));
1185   DCHECK(is_uint12(d1));
1186   DCHECK(is_uint12(op));
1187   uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 |
1188                   (static_cast<uint64_t>(r3.code())) * B36 |
1189                   (static_cast<uint64_t>(op & 0x00F)) * B32 |
1190                   (static_cast<uint64_t>(b1.code())) * B28 |
1191                   (static_cast<uint64_t>(d1)) * B16 |
1192                   (static_cast<uint64_t>(b2.code())) * B12 |
1193                   (static_cast<uint64_t>(d2));
1194   emit6bytes(code);
1195 }
1196 
1197 //  RRF1 format: <insn> R1,R2,R3
1198 //    +------------------+----+----+----+----+
1199 //    |      OpCode      | R3 |    | R1 | R2 |
1200 //    +------------------+----+----+----+----+
1201 //    0                  16   20   24   28  31
1202 #define RRF1_FORM_EMIT(name, op)                                        \
1203   void Assembler::name(Register r1, Register r2, Register r3) {         \
1204     rrf1_form(op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code()); \
1205   }
1206 
rrf1_form(Opcode op,Register r1,Register r2,Register r3)1207 void Assembler::rrf1_form(Opcode op, Register r1, Register r2, Register r3) {
1208   uint32_t code = op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code();
1209   emit4bytes(code);
1210 }
1211 
rrf1_form(uint32_t code)1212 void Assembler::rrf1_form(uint32_t code) { emit4bytes(code); }
1213 
1214 //  RRF2 format: <insn> R1,R2,M3
1215 //    +------------------+----+----+----+----+
1216 //    |      OpCode      | M3 |    | R1 | R2 |
1217 //    +------------------+----+----+----+----+
1218 //    0                  16   20   24   28  31
1219 #define RRF2_FORM_EMIT(name, op)                                 \
1220   void Assembler::name(Condition m3, Register r1, Register r2) { \
1221     rrf2_form(op << 16 | m3 * B12 | r1.code() * B4 | r2.code()); \
1222   }
1223 
rrf2_form(uint32_t code)1224 void Assembler::rrf2_form(uint32_t code) { emit4bytes(code); }
1225 
1226 //  RRF3 format: <insn> R1,R2,R3,M4
1227 //    +------------------+----+----+----+----+
1228 //    |      OpCode      | R3 | M4 | R1 | R2 |
1229 //    +------------------+----+----+----+----+
1230 //    0                  16   20   24   28  31
1231 #define RRF3_FORM_EMIT(name, op)                                             \
1232   void Assembler::name(Register r3, Conition m4, Register r1, Register r2) { \
1233     rrf3_form(op << 16 | r3.code() * B12 | m4 * B8 | r1.code() * B4 |        \
1234               r2.code());                                                    \
1235   }
1236 
rrf3_form(uint32_t code)1237 void Assembler::rrf3_form(uint32_t code) { emit4bytes(code); }
1238 
1239 //  RRF-e format: <insn> R1,M3,R2,M4
1240 //    +------------------+----+----+----+----+
1241 //    |      OpCode      | M3 | M4 | R1 | R2 |
1242 //    +------------------+----+----+----+----+
1243 //    0                  16   20   24   28  31
rrfe_form(Opcode op,Condition m3,Condition m4,Register r1,Register r2)1244 void Assembler::rrfe_form(Opcode op, Condition m3, Condition m4, Register r1,
1245                           Register r2) {
1246   uint32_t code = op << 16 | m3 * B12 | m4 * B8 | r1.code() * B4 | r2.code();
1247   emit4bytes(code);
1248 }
1249 
1250 // end of S390 Instruction generation
1251 
1252 // start of S390 instruction
SS1_FORM_EMIT(ed,ED)1253 SS1_FORM_EMIT(ed, ED)
1254 SS1_FORM_EMIT(mvn, MVN)
1255 SS1_FORM_EMIT(nc, NC)
1256 SI_FORM_EMIT(ni, NI)
1257 RI1_FORM_EMIT(nilh, NILH)
1258 RI1_FORM_EMIT(nill, NILL)
1259 RI1_FORM_EMIT(oill, OILL)
1260 RI1_FORM_EMIT(tmll, TMLL)
1261 SS1_FORM_EMIT(tr, TR)
1262 S_FORM_EMIT(ts, TS)
1263 
1264 // -------------------------
1265 // Load Address Instructions
1266 // -------------------------
1267 // Load Address Relative Long
1268 void Assembler::larl(Register r1, Label* l) {
1269   larl(r1, Operand(branch_offset(l)));
1270 }
1271 
1272 // -----------------
1273 // Load Instructions
1274 // -----------------
1275 // Load Halfword Immediate (32)
lhi(Register r,const Operand & imm)1276 void Assembler::lhi(Register r, const Operand& imm) { ri_form(LHI, r, imm); }
1277 
1278 // Load Halfword Immediate (64)
lghi(Register r,const Operand & imm)1279 void Assembler::lghi(Register r, const Operand& imm) { ri_form(LGHI, r, imm); }
1280 
1281 // -------------------------
1282 // Load Logical Instructions
1283 // -------------------------
1284 // Load On Condition R-R (32)
locr(Condition m3,Register r1,Register r2)1285 void Assembler::locr(Condition m3, Register r1, Register r2) {
1286   rrf2_form(LOCR << 16 | m3 * B12 | r1.code() * B4 | r2.code());
1287 }
1288 
1289 // Load On Condition R-R (64)
locgr(Condition m3,Register r1,Register r2)1290 void Assembler::locgr(Condition m3, Register r1, Register r2) {
1291   rrf2_form(LOCGR << 16 | m3 * B12 | r1.code() * B4 | r2.code());
1292 }
1293 
1294 // Load On Condition R-M (32)
loc(Condition m3,Register r1,const MemOperand & src)1295 void Assembler::loc(Condition m3, Register r1, const MemOperand& src) {
1296   rsy_form(LOC, r1, m3, src.rb(), src.offset());
1297 }
1298 
1299 // Load On Condition R-M (64)
locg(Condition m3,Register r1,const MemOperand & src)1300 void Assembler::locg(Condition m3, Register r1, const MemOperand& src) {
1301   rsy_form(LOCG, r1, m3, src.rb(), src.offset());
1302 }
1303 
1304 // -------------------
1305 // Branch Instructions
1306 // -------------------
1307 // Branch on Count (64)
1308 // Branch Relative and Save (32)
bras(Register r,const Operand & opnd)1309 void Assembler::bras(Register r, const Operand& opnd) {
1310   ri_form(BRAS, r, opnd);
1311 }
1312 
1313 // Branch relative on Condition (32)
brc(Condition c,const Operand & opnd)1314 void Assembler::brc(Condition c, const Operand& opnd) { ri_form(BRC, c, opnd); }
1315 
1316 // Branch On Count (32)
brct(Register r1,const Operand & imm)1317 void Assembler::brct(Register r1, const Operand& imm) {
1318   // BRCT encodes # of halfwords, so divide by 2.
1319   int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2;
1320   Operand halfwordOp = Operand(numHalfwords);
1321   halfwordOp.setBits(16);
1322   ri_form(BRCT, r1, halfwordOp);
1323 }
1324 
1325 // Branch On Count (32)
brctg(Register r1,const Operand & imm)1326 void Assembler::brctg(Register r1, const Operand& imm) {
1327   // BRCTG encodes # of halfwords, so divide by 2.
1328   int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2;
1329   Operand halfwordOp = Operand(numHalfwords);
1330   halfwordOp.setBits(16);
1331   ri_form(BRCTG, r1, halfwordOp);
1332 }
1333 
1334 // --------------------
1335 // Compare Instructions
1336 // --------------------
1337 // Compare Halfword Immediate (32)
chi(Register r,const Operand & opnd)1338 void Assembler::chi(Register r, const Operand& opnd) { ri_form(CHI, r, opnd); }
1339 
1340 // Compare Halfword Immediate (64)
cghi(Register r,const Operand & opnd)1341 void Assembler::cghi(Register r, const Operand& opnd) {
1342   ri_form(CGHI, r, opnd);
1343 }
1344 
1345 // ----------------------------
1346 // Compare Logical Instructions
1347 // ----------------------------
1348 // Compare Immediate (Mem - Imm) (8)
cli(const MemOperand & opnd,const Operand & imm)1349 void Assembler::cli(const MemOperand& opnd, const Operand& imm) {
1350   si_form(CLI, imm, opnd.rb(), opnd.offset());
1351 }
1352 
1353 // Compare Immediate (Mem - Imm) (8)
cliy(const MemOperand & opnd,const Operand & imm)1354 void Assembler::cliy(const MemOperand& opnd, const Operand& imm) {
1355   siy_form(CLIY, imm, opnd.rb(), opnd.offset());
1356 }
1357 
1358 // Compare logical - mem to mem operation
clc(const MemOperand & opnd1,const MemOperand & opnd2,Length length)1359 void Assembler::clc(const MemOperand& opnd1, const MemOperand& opnd2,
1360                     Length length) {
1361   ss_form(CLC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(),
1362           opnd2.getBaseRegister(), opnd2.getDisplacement());
1363 }
1364 
1365 // ----------------------------
1366 // Test Under Mask Instructions
1367 // ----------------------------
1368 // Test Under Mask (Mem - Imm) (8)
tm(const MemOperand & opnd,const Operand & imm)1369 void Assembler::tm(const MemOperand& opnd, const Operand& imm) {
1370   si_form(TM, imm, opnd.rb(), opnd.offset());
1371 }
1372 
1373 // Test Under Mask (Mem - Imm) (8)
tmy(const MemOperand & opnd,const Operand & imm)1374 void Assembler::tmy(const MemOperand& opnd, const Operand& imm) {
1375   siy_form(TMY, imm, opnd.rb(), opnd.offset());
1376 }
1377 
1378 // -------------------------------
1379 // Rotate and Insert Selected Bits
1380 // -------------------------------
1381 // Rotate-And-Insert-Selected-Bits
risbg(Register dst,Register src,const Operand & startBit,const Operand & endBit,const Operand & shiftAmt,bool zeroBits)1382 void Assembler::risbg(Register dst, Register src, const Operand& startBit,
1383                       const Operand& endBit, const Operand& shiftAmt,
1384                       bool zeroBits) {
1385   // High tag the top bit of I4/EndBit to zero out any unselected bits
1386   if (zeroBits)
1387     rie_f_form(RISBG, dst, src, startBit, Operand(endBit.imm_ | 0x80),
1388                shiftAmt);
1389   else
1390     rie_f_form(RISBG, dst, src, startBit, endBit, shiftAmt);
1391 }
1392 
1393 // Rotate-And-Insert-Selected-Bits
risbgn(Register dst,Register src,const Operand & startBit,const Operand & endBit,const Operand & shiftAmt,bool zeroBits)1394 void Assembler::risbgn(Register dst, Register src, const Operand& startBit,
1395                        const Operand& endBit, const Operand& shiftAmt,
1396                        bool zeroBits) {
1397   // High tag the top bit of I4/EndBit to zero out any unselected bits
1398   if (zeroBits)
1399     rie_f_form(RISBGN, dst, src, startBit, Operand(endBit.imm_ | 0x80),
1400                shiftAmt);
1401   else
1402     rie_f_form(RISBGN, dst, src, startBit, endBit, shiftAmt);
1403 }
1404 
1405 // ---------------------------
1406 // Move Character Instructions
1407 // ---------------------------
1408 // Move charactor - mem to mem operation
mvc(const MemOperand & opnd1,const MemOperand & opnd2,uint32_t length)1409 void Assembler::mvc(const MemOperand& opnd1, const MemOperand& opnd2,
1410                     uint32_t length) {
1411   ss_form(MVC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(),
1412           opnd2.getBaseRegister(), opnd2.getDisplacement());
1413 }
1414 
1415 // -----------------------
1416 // 32-bit Add Instructions
1417 // -----------------------
1418 // Add Halfword Immediate (32)
ahi(Register r1,const Operand & i2)1419 void Assembler::ahi(Register r1, const Operand& i2) { ri_form(AHI, r1, i2); }
1420 
1421 // Add Halfword Immediate (32)
ahik(Register r1,Register r3,const Operand & i2)1422 void Assembler::ahik(Register r1, Register r3, const Operand& i2) {
1423   rie_form(AHIK, r1, r3, i2);
1424 }
1425 
1426 // Add Register-Register-Register (32)
ark(Register r1,Register r2,Register r3)1427 void Assembler::ark(Register r1, Register r2, Register r3) {
1428   rrf1_form(ARK, r1, r2, r3);
1429 }
1430 
1431 // Add Storage-Imm (32)
asi(const MemOperand & opnd,const Operand & imm)1432 void Assembler::asi(const MemOperand& opnd, const Operand& imm) {
1433   DCHECK(is_int8(imm.imm_));
1434   DCHECK(is_int20(opnd.offset()));
1435   siy_form(ASI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset());
1436 }
1437 
1438 // -----------------------
1439 // 64-bit Add Instructions
1440 // -----------------------
1441 // Add Halfword Immediate (64)
aghi(Register r1,const Operand & i2)1442 void Assembler::aghi(Register r1, const Operand& i2) { ri_form(AGHI, r1, i2); }
1443 
1444 // Add Halfword Immediate (64)
aghik(Register r1,Register r3,const Operand & i2)1445 void Assembler::aghik(Register r1, Register r3, const Operand& i2) {
1446   rie_form(AGHIK, r1, r3, i2);
1447 }
1448 
1449 // Add Register-Register-Register (64)
agrk(Register r1,Register r2,Register r3)1450 void Assembler::agrk(Register r1, Register r2, Register r3) {
1451   rrf1_form(AGRK, r1, r2, r3);
1452 }
1453 
1454 // Add Storage-Imm (64)
agsi(const MemOperand & opnd,const Operand & imm)1455 void Assembler::agsi(const MemOperand& opnd, const Operand& imm) {
1456   DCHECK(is_int8(imm.imm_));
1457   DCHECK(is_int20(opnd.offset()));
1458   siy_form(AGSI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset());
1459 }
1460 
1461 // -------------------------------
1462 // 32-bit Add Logical Instructions
1463 // -------------------------------
1464 // Add Logical Register-Register-Register (32)
alrk(Register r1,Register r2,Register r3)1465 void Assembler::alrk(Register r1, Register r2, Register r3) {
1466   rrf1_form(ALRK, r1, r2, r3);
1467 }
1468 
1469 // -------------------------------
1470 // 64-bit Add Logical Instructions
1471 // -------------------------------
1472 // Add Logical Register-Register-Register (64)
algrk(Register r1,Register r2,Register r3)1473 void Assembler::algrk(Register r1, Register r2, Register r3) {
1474   rrf1_form(ALGRK, r1, r2, r3);
1475 }
1476 
1477 // ----------------------------
1478 // 32-bit Subtract Instructions
1479 // ----------------------------
1480 // Subtract Register-Register-Register (32)
srk(Register r1,Register r2,Register r3)1481 void Assembler::srk(Register r1, Register r2, Register r3) {
1482   rrf1_form(SRK, r1, r2, r3);
1483 }
1484 
1485 // ----------------------------
1486 // 64-bit Subtract Instructions
1487 // ----------------------------
1488 // Subtract Register-Register-Register (64)
sgrk(Register r1,Register r2,Register r3)1489 void Assembler::sgrk(Register r1, Register r2, Register r3) {
1490   rrf1_form(SGRK, r1, r2, r3);
1491 }
1492 
1493 // ------------------------------------
1494 // 32-bit Subtract Logical Instructions
1495 // ------------------------------------
1496 // Subtract Logical Register-Register-Register (32)
slrk(Register r1,Register r2,Register r3)1497 void Assembler::slrk(Register r1, Register r2, Register r3) {
1498   rrf1_form(SLRK, r1, r2, r3);
1499 }
1500 
1501 // ------------------------------------
1502 // 64-bit Subtract Logical Instructions
1503 // ------------------------------------
1504 // Subtract Logical Register-Register-Register (64)
slgrk(Register r1,Register r2,Register r3)1505 void Assembler::slgrk(Register r1, Register r2, Register r3) {
1506   rrf1_form(SLGRK, r1, r2, r3);
1507 }
1508 
1509 // ----------------------------
1510 // 32-bit Multiply Instructions
1511 // ----------------------------
1512 // Multiply Halfword Immediate (32)
mhi(Register r1,const Operand & opnd)1513 void Assembler::mhi(Register r1, const Operand& opnd) {
1514   ri_form(MHI, r1, opnd);
1515 }
1516 
1517 // Multiply Single Register (32)
msrkc(Register r1,Register r2,Register r3)1518 void Assembler::msrkc(Register r1, Register r2, Register r3) {
1519   rrf1_form(MSRKC, r1, r2, r3);
1520 }
1521 
1522 // Multiply Single Register (64)
msgrkc(Register r1,Register r2,Register r3)1523 void Assembler::msgrkc(Register r1, Register r2, Register r3) {
1524   rrf1_form(MSGRKC, r1, r2, r3);
1525 }
1526 
1527 // ----------------------------
1528 // 64-bit Multiply Instructions
1529 // ----------------------------
1530 // Multiply Halfword Immediate (64)
mghi(Register r1,const Operand & opnd)1531 void Assembler::mghi(Register r1, const Operand& opnd) {
1532   ri_form(MGHI, r1, opnd);
1533 }
1534 
1535 // --------------------
1536 // Bitwise Instructions
1537 // --------------------
1538 // AND Register-Register-Register (32)
nrk(Register r1,Register r2,Register r3)1539 void Assembler::nrk(Register r1, Register r2, Register r3) {
1540   rrf1_form(NRK, r1, r2, r3);
1541 }
1542 
1543 // AND Register-Register-Register (64)
ngrk(Register r1,Register r2,Register r3)1544 void Assembler::ngrk(Register r1, Register r2, Register r3) {
1545   rrf1_form(NGRK, r1, r2, r3);
1546 }
1547 
1548 // OR Register-Register-Register (32)
ork(Register r1,Register r2,Register r3)1549 void Assembler::ork(Register r1, Register r2, Register r3) {
1550   rrf1_form(ORK, r1, r2, r3);
1551 }
1552 
1553 // OR Register-Register-Register (64)
ogrk(Register r1,Register r2,Register r3)1554 void Assembler::ogrk(Register r1, Register r2, Register r3) {
1555   rrf1_form(OGRK, r1, r2, r3);
1556 }
1557 
1558 // XOR Register-Register-Register (32)
xrk(Register r1,Register r2,Register r3)1559 void Assembler::xrk(Register r1, Register r2, Register r3) {
1560   rrf1_form(XRK, r1, r2, r3);
1561 }
1562 
1563 // XOR Register-Register-Register (64)
xgrk(Register r1,Register r2,Register r3)1564 void Assembler::xgrk(Register r1, Register r2, Register r3) {
1565   rrf1_form(XGRK, r1, r2, r3);
1566 }
1567 
1568 // XOR Storage-Storage
xc(const MemOperand & opnd1,const MemOperand & opnd2,Length length)1569 void Assembler::xc(const MemOperand& opnd1, const MemOperand& opnd2,
1570                    Length length) {
1571   ss_form(XC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(),
1572           opnd2.getBaseRegister(), opnd2.getDisplacement());
1573 }
1574 
EnsureSpaceFor(int space_needed)1575 void Assembler::EnsureSpaceFor(int space_needed) {
1576   if (buffer_space() <= (kGap + space_needed)) {
1577     GrowBuffer(space_needed);
1578   }
1579 }
1580 
1581 // Rotate Left Single Logical (32)
rll(Register r1,Register r3,Register opnd)1582 void Assembler::rll(Register r1, Register r3, Register opnd) {
1583   DCHECK(!opnd.is(r0));
1584   rsy_form(RLL, r1, r3, opnd, 0);
1585 }
1586 
1587 // Rotate Left Single Logical (32)
rll(Register r1,Register r3,const Operand & opnd)1588 void Assembler::rll(Register r1, Register r3, const Operand& opnd) {
1589   rsy_form(RLL, r1, r3, r0, opnd.immediate());
1590 }
1591 
1592 // Rotate Left Single Logical (32)
rll(Register r1,Register r3,Register r2,const Operand & opnd)1593 void Assembler::rll(Register r1, Register r3, Register r2,
1594                     const Operand& opnd) {
1595   rsy_form(RLL, r1, r3, r2, opnd.immediate());
1596 }
1597 
1598 // Rotate Left Single Logical (64)
rllg(Register r1,Register r3,Register opnd)1599 void Assembler::rllg(Register r1, Register r3, Register opnd) {
1600   DCHECK(!opnd.is(r0));
1601   rsy_form(RLLG, r1, r3, opnd, 0);
1602 }
1603 
1604 // Rotate Left Single Logical (64)
rllg(Register r1,Register r3,const Operand & opnd)1605 void Assembler::rllg(Register r1, Register r3, const Operand& opnd) {
1606   rsy_form(RLLG, r1, r3, r0, opnd.immediate());
1607 }
1608 
1609 // Rotate Left Single Logical (64)
rllg(Register r1,Register r3,Register r2,const Operand & opnd)1610 void Assembler::rllg(Register r1, Register r3, Register r2,
1611                      const Operand& opnd) {
1612   rsy_form(RLLG, r1, r3, r2, opnd.immediate());
1613 }
1614 
1615 // Shift Left Single Logical (32)
sll(Register r1,Register opnd)1616 void Assembler::sll(Register r1, Register opnd) {
1617   DCHECK(!opnd.is(r0));
1618   rs_form(SLL, r1, r0, opnd, 0);
1619 }
1620 
1621 // Shift Left Single Logical (32)
sll(Register r1,const Operand & opnd)1622 void Assembler::sll(Register r1, const Operand& opnd) {
1623   rs_form(SLL, r1, r0, r0, opnd.immediate());
1624 }
1625 
1626 // Shift Left Single Logical (32)
sllk(Register r1,Register r3,Register opnd)1627 void Assembler::sllk(Register r1, Register r3, Register opnd) {
1628   DCHECK(!opnd.is(r0));
1629   rsy_form(SLLK, r1, r3, opnd, 0);
1630 }
1631 
1632 // Shift Left Single Logical (32)
sllk(Register r1,Register r3,const Operand & opnd)1633 void Assembler::sllk(Register r1, Register r3, const Operand& opnd) {
1634   rsy_form(SLLK, r1, r3, r0, opnd.immediate());
1635 }
1636 
1637 // Shift Left Single Logical (64)
sllg(Register r1,Register r3,Register opnd)1638 void Assembler::sllg(Register r1, Register r3, Register opnd) {
1639   DCHECK(!opnd.is(r0));
1640   rsy_form(SLLG, r1, r3, opnd, 0);
1641 }
1642 
1643 // Shift Left Single Logical (64)
sllg(Register r1,Register r3,const Operand & opnd)1644 void Assembler::sllg(Register r1, Register r3, const Operand& opnd) {
1645   rsy_form(SLLG, r1, r3, r0, opnd.immediate());
1646 }
1647 
1648 // Shift Left Double Logical (64)
sldl(Register r1,Register b2,const Operand & opnd)1649 void Assembler::sldl(Register r1, Register b2, const Operand& opnd) {
1650   DCHECK(r1.code() % 2 == 0);
1651   rs_form(SLDL, r1, r0, b2, opnd.immediate());
1652 }
1653 
1654 // Shift Right Single Logical (32)
srl(Register r1,Register opnd)1655 void Assembler::srl(Register r1, Register opnd) {
1656   DCHECK(!opnd.is(r0));
1657   rs_form(SRL, r1, r0, opnd, 0);
1658 }
1659 
1660 // Shift Right Double Arith (64)
srda(Register r1,Register b2,const Operand & opnd)1661 void Assembler::srda(Register r1, Register b2, const Operand& opnd) {
1662   DCHECK(r1.code() % 2 == 0);
1663   rs_form(SRDA, r1, r0, b2, opnd.immediate());
1664 }
1665 
1666 // Shift Right Double Logical (64)
srdl(Register r1,Register b2,const Operand & opnd)1667 void Assembler::srdl(Register r1, Register b2, const Operand& opnd) {
1668   DCHECK(r1.code() % 2 == 0);
1669   rs_form(SRDL, r1, r0, b2, opnd.immediate());
1670 }
1671 
1672 // Shift Right Single Logical (32)
srl(Register r1,const Operand & opnd)1673 void Assembler::srl(Register r1, const Operand& opnd) {
1674   rs_form(SRL, r1, r0, r0, opnd.immediate());
1675 }
1676 
1677 // Shift Right Single Logical (32)
srlk(Register r1,Register r3,Register opnd)1678 void Assembler::srlk(Register r1, Register r3, Register opnd) {
1679   DCHECK(!opnd.is(r0));
1680   rsy_form(SRLK, r1, r3, opnd, 0);
1681 }
1682 
1683 // Shift Right Single Logical (32)
srlk(Register r1,Register r3,const Operand & opnd)1684 void Assembler::srlk(Register r1, Register r3, const Operand& opnd) {
1685   rsy_form(SRLK, r1, r3, r0, opnd.immediate());
1686 }
1687 
1688 // Shift Right Single Logical (64)
srlg(Register r1,Register r3,Register opnd)1689 void Assembler::srlg(Register r1, Register r3, Register opnd) {
1690   DCHECK(!opnd.is(r0));
1691   rsy_form(SRLG, r1, r3, opnd, 0);
1692 }
1693 
1694 // Shift Right Single Logical (64)
srlg(Register r1,Register r3,const Operand & opnd)1695 void Assembler::srlg(Register r1, Register r3, const Operand& opnd) {
1696   rsy_form(SRLG, r1, r3, r0, opnd.immediate());
1697 }
1698 
1699 // Shift Left Single (32)
sla(Register r1,Register opnd)1700 void Assembler::sla(Register r1, Register opnd) {
1701   DCHECK(!opnd.is(r0));
1702   rs_form(SLA, r1, r0, opnd, 0);
1703 }
1704 
1705 // Shift Left Single (32)
sla(Register r1,const Operand & opnd)1706 void Assembler::sla(Register r1, const Operand& opnd) {
1707   rs_form(SLA, r1, r0, r0, opnd.immediate());
1708 }
1709 
1710 // Shift Left Single (32)
slak(Register r1,Register r3,Register opnd)1711 void Assembler::slak(Register r1, Register r3, Register opnd) {
1712   DCHECK(!opnd.is(r0));
1713   rsy_form(SLAK, r1, r3, opnd, 0);
1714 }
1715 
1716 // Shift Left Single (32)
slak(Register r1,Register r3,const Operand & opnd)1717 void Assembler::slak(Register r1, Register r3, const Operand& opnd) {
1718   rsy_form(SLAK, r1, r3, r0, opnd.immediate());
1719 }
1720 
1721 // Shift Left Single (64)
slag(Register r1,Register r3,Register opnd)1722 void Assembler::slag(Register r1, Register r3, Register opnd) {
1723   DCHECK(!opnd.is(r0));
1724   rsy_form(SLAG, r1, r3, opnd, 0);
1725 }
1726 
1727 // Shift Left Single (64)
slag(Register r1,Register r3,const Operand & opnd)1728 void Assembler::slag(Register r1, Register r3, const Operand& opnd) {
1729   rsy_form(SLAG, r1, r3, r0, opnd.immediate());
1730 }
1731 
1732 // Shift Right Single (32)
sra(Register r1,Register opnd)1733 void Assembler::sra(Register r1, Register opnd) {
1734   DCHECK(!opnd.is(r0));
1735   rs_form(SRA, r1, r0, opnd, 0);
1736 }
1737 
1738 // Shift Right Single (32)
sra(Register r1,const Operand & opnd)1739 void Assembler::sra(Register r1, const Operand& opnd) {
1740   rs_form(SRA, r1, r0, r0, opnd.immediate());
1741 }
1742 
1743 // Shift Right Single (32)
srak(Register r1,Register r3,Register opnd)1744 void Assembler::srak(Register r1, Register r3, Register opnd) {
1745   DCHECK(!opnd.is(r0));
1746   rsy_form(SRAK, r1, r3, opnd, 0);
1747 }
1748 
1749 // Shift Right Single (32)
srak(Register r1,Register r3,const Operand & opnd)1750 void Assembler::srak(Register r1, Register r3, const Operand& opnd) {
1751   rsy_form(SRAK, r1, r3, r0, opnd.immediate());
1752 }
1753 
1754 // Shift Right Single (64)
srag(Register r1,Register r3,Register opnd)1755 void Assembler::srag(Register r1, Register r3, Register opnd) {
1756   DCHECK(!opnd.is(r0));
1757   rsy_form(SRAG, r1, r3, opnd, 0);
1758 }
1759 
srag(Register r1,Register r3,const Operand & opnd)1760 void Assembler::srag(Register r1, Register r3, const Operand& opnd) {
1761   rsy_form(SRAG, r1, r3, r0, opnd.immediate());
1762 }
1763 
1764 // Shift Right Double
srda(Register r1,const Operand & opnd)1765 void Assembler::srda(Register r1, const Operand& opnd) {
1766   DCHECK(r1.code() % 2 == 0);
1767   rs_form(SRDA, r1, r0, r0, opnd.immediate());
1768 }
1769 
1770 // Shift Right Double Logical
srdl(Register r1,const Operand & opnd)1771 void Assembler::srdl(Register r1, const Operand& opnd) {
1772   DCHECK(r1.code() % 2 == 0);
1773   rs_form(SRDL, r1, r0, r0, opnd.immediate());
1774 }
1775 
call(Handle<Code> target,RelocInfo::Mode rmode,TypeFeedbackId ast_id)1776 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode,
1777                      TypeFeedbackId ast_id) {
1778   EnsureSpace ensure_space(this);
1779 
1780   int32_t target_index = emit_code_target(target, rmode, ast_id);
1781   brasl(r14, Operand(target_index));
1782 }
1783 
jump(Handle<Code> target,RelocInfo::Mode rmode,Condition cond)1784 void Assembler::jump(Handle<Code> target, RelocInfo::Mode rmode,
1785                      Condition cond) {
1786   EnsureSpace ensure_space(this);
1787 
1788   int32_t target_index = emit_code_target(target, rmode);
1789   brcl(cond, Operand(target_index));
1790 }
1791 
1792 // 32-bit Load Multiple - short displacement (12-bits unsigned)
lm(Register r1,Register r2,const MemOperand & src)1793 void Assembler::lm(Register r1, Register r2, const MemOperand& src) {
1794   rs_form(LM, r1, r2, src.rb(), src.offset());
1795 }
1796 
1797 // 32-bit Load Multiple - long displacement (20-bits signed)
lmy(Register r1,Register r2,const MemOperand & src)1798 void Assembler::lmy(Register r1, Register r2, const MemOperand& src) {
1799   rsy_form(LMY, r1, r2, src.rb(), src.offset());
1800 }
1801 
1802 // 64-bit Load Multiple - long displacement (20-bits signed)
lmg(Register r1,Register r2,const MemOperand & src)1803 void Assembler::lmg(Register r1, Register r2, const MemOperand& src) {
1804   rsy_form(LMG, r1, r2, src.rb(), src.offset());
1805 }
1806 
1807 // Move integer (32)
mvhi(const MemOperand & opnd1,const Operand & i2)1808 void Assembler::mvhi(const MemOperand& opnd1, const Operand& i2) {
1809   sil_form(MVHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2);
1810 }
1811 
1812 // Move integer (64)
mvghi(const MemOperand & opnd1,const Operand & i2)1813 void Assembler::mvghi(const MemOperand& opnd1, const Operand& i2) {
1814   sil_form(MVGHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2);
1815 }
1816 
1817 // Insert Immediate (high high)
iihh(Register r1,const Operand & opnd)1818 void Assembler::iihh(Register r1, const Operand& opnd) {
1819   ri_form(IIHH, r1, opnd);
1820 }
1821 
1822 // Insert Immediate (high low)
iihl(Register r1,const Operand & opnd)1823 void Assembler::iihl(Register r1, const Operand& opnd) {
1824   ri_form(IIHL, r1, opnd);
1825 }
1826 
1827 // Insert Immediate (low high)
iilh(Register r1,const Operand & opnd)1828 void Assembler::iilh(Register r1, const Operand& opnd) {
1829   ri_form(IILH, r1, opnd);
1830 }
1831 
1832 // Insert Immediate (low low)
iill(Register r1,const Operand & opnd)1833 void Assembler::iill(Register r1, const Operand& opnd) {
1834   ri_form(IILL, r1, opnd);
1835 }
1836 
1837 // GPR <-> FPR Instructions
1838 
1839 // Floating point instructions
1840 //
1841 // Add Register-Storage (LB)
adb(DoubleRegister r1,const MemOperand & opnd)1842 void Assembler::adb(DoubleRegister r1, const MemOperand& opnd) {
1843   rxe_form(ADB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1844            opnd.offset());
1845 }
1846 
1847 // Divide Register-Storage (LB)
ddb(DoubleRegister r1,const MemOperand & opnd)1848 void Assembler::ddb(DoubleRegister r1, const MemOperand& opnd) {
1849   rxe_form(DDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1850            opnd.offset());
1851 }
1852 
1853 // Multiply Register-Storage (LB)
mdb(DoubleRegister r1,const MemOperand & opnd)1854 void Assembler::mdb(DoubleRegister r1, const MemOperand& opnd) {
1855   rxe_form(MDB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(),
1856            opnd.offset());
1857 }
1858 
1859 // Subtract Register-Storage (LB)
sdb(DoubleRegister r1,const MemOperand & opnd)1860 void Assembler::sdb(DoubleRegister r1, const MemOperand& opnd) {
1861   rxe_form(SDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1862            opnd.offset());
1863 }
1864 
ceb(DoubleRegister r1,const MemOperand & opnd)1865 void Assembler::ceb(DoubleRegister r1, const MemOperand& opnd) {
1866   rxe_form(CEB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1867            opnd.offset());
1868 }
1869 
cdb(DoubleRegister r1,const MemOperand & opnd)1870 void Assembler::cdb(DoubleRegister r1, const MemOperand& opnd) {
1871   rxe_form(CDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1872            opnd.offset());
1873 }
1874 
1875 // Square Root (LB)
sqdb(DoubleRegister r1,const MemOperand & opnd)1876 void Assembler::sqdb(DoubleRegister r1, const MemOperand& opnd) {
1877   rxe_form(SQDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1878            opnd.offset());
1879 }
1880 
1881 // Convert to Fixed point (64<-S)
cgebr(Condition m,Register r1,DoubleRegister r2)1882 void Assembler::cgebr(Condition m, Register r1, DoubleRegister r2) {
1883   rrfe_form(CGEBR, m, Condition(0), r1, Register::from_code(r2.code()));
1884 }
1885 
1886 // Convert to Fixed point (64<-L)
cgdbr(Condition m,Register r1,DoubleRegister r2)1887 void Assembler::cgdbr(Condition m, Register r1, DoubleRegister r2) {
1888   rrfe_form(CGDBR, m, Condition(0), r1, Register::from_code(r2.code()));
1889 }
1890 
1891 // Convert to Fixed point (32<-L)
cfdbr(Condition m,Register r1,DoubleRegister r2)1892 void Assembler::cfdbr(Condition m, Register r1, DoubleRegister r2) {
1893   rrfe_form(CFDBR, m, Condition(0), r1, Register::from_code(r2.code()));
1894 }
1895 
1896 // Convert to Fixed Logical (64<-L)
clgdbr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1897 void Assembler::clgdbr(Condition m3, Condition m4, Register r1,
1898                        DoubleRegister r2) {
1899   DCHECK_EQ(m4, Condition(0));
1900   rrfe_form(CLGDBR, m3, m4, r1, Register::from_code(r2.code()));
1901 }
1902 
1903 // Convert to Fixed Logical (64<-F32)
clgebr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1904 void Assembler::clgebr(Condition m3, Condition m4, Register r1,
1905                        DoubleRegister r2) {
1906   DCHECK_EQ(m4, Condition(0));
1907   rrfe_form(CLGEBR, m3, m4, r1, Register::from_code(r2.code()));
1908 }
1909 
1910 // Convert to Fixed Logical (32<-F64)
clfdbr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1911 void Assembler::clfdbr(Condition m3, Condition m4, Register r1,
1912                        DoubleRegister r2) {
1913   DCHECK_EQ(m3, Condition(0));
1914   DCHECK_EQ(m4, Condition(0));
1915   rrfe_form(CLFDBR, Condition(0), Condition(0), r1,
1916             Register::from_code(r2.code()));
1917 }
1918 
1919 // Convert to Fixed Logical (32<-F32)
clfebr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1920 void Assembler::clfebr(Condition m3, Condition m4, Register r1,
1921                        DoubleRegister r2) {
1922   DCHECK_EQ(m4, Condition(0));
1923   rrfe_form(CLFEBR, m3, Condition(0), r1, Register::from_code(r2.code()));
1924 }
1925 
1926 // Convert from Fixed Logical (L<-64)
celgbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1927 void Assembler::celgbr(Condition m3, Condition m4, DoubleRegister r1,
1928                        Register r2) {
1929   DCHECK_EQ(m3, Condition(0));
1930   DCHECK_EQ(m4, Condition(0));
1931   rrfe_form(CELGBR, Condition(0), Condition(0), Register::from_code(r1.code()),
1932             r2);
1933 }
1934 
1935 // Convert from Fixed Logical (F32<-32)
celfbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1936 void Assembler::celfbr(Condition m3, Condition m4, DoubleRegister r1,
1937                        Register r2) {
1938   DCHECK_EQ(m4, Condition(0));
1939   rrfe_form(CELFBR, m3, Condition(0), Register::from_code(r1.code()), r2);
1940 }
1941 
1942 // Convert from Fixed Logical (L<-64)
cdlgbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1943 void Assembler::cdlgbr(Condition m3, Condition m4, DoubleRegister r1,
1944                        Register r2) {
1945   DCHECK_EQ(m3, Condition(0));
1946   DCHECK_EQ(m4, Condition(0));
1947   rrfe_form(CDLGBR, Condition(0), Condition(0), Register::from_code(r1.code()),
1948             r2);
1949 }
1950 
1951 // Convert from Fixed Logical (L<-32)
cdlfbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1952 void Assembler::cdlfbr(Condition m3, Condition m4, DoubleRegister r1,
1953                        Register r2) {
1954   DCHECK_EQ(m4, Condition(0));
1955   rrfe_form(CDLFBR, m3, Condition(0), Register::from_code(r1.code()), r2);
1956 }
1957 
1958 // Convert from Fixed point (S<-32)
cefbr(Condition m3,DoubleRegister r1,Register r2)1959 void Assembler::cefbr(Condition m3, DoubleRegister r1, Register r2) {
1960   rrfe_form(CEFBR, m3, Condition(0), Register::from_code(r1.code()), r2);
1961 }
1962 
1963 // Convert to Fixed point (32<-S)
cfebr(Condition m3,Register r1,DoubleRegister r2)1964 void Assembler::cfebr(Condition m3, Register r1, DoubleRegister r2) {
1965   rrfe_form(CFEBR, m3, Condition(0), r1, Register::from_code(r2.code()));
1966 }
1967 
1968 // Load (L <- S)
ldeb(DoubleRegister d1,const MemOperand & opnd)1969 void Assembler::ldeb(DoubleRegister d1, const MemOperand& opnd) {
1970   rxe_form(LDEB, Register::from_code(d1.code()), opnd.rx(), opnd.rb(),
1971            opnd.offset());
1972 }
1973 
1974 // Load FP Integer
fiebra(DoubleRegister d1,DoubleRegister d2,FIDBRA_MASK3 m3)1975 void Assembler::fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) {
1976   rrf2_form(FIEBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code());
1977 }
1978 
1979 // Load FP Integer
fidbra(DoubleRegister d1,DoubleRegister d2,FIDBRA_MASK3 m3)1980 void Assembler::fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) {
1981   rrf2_form(FIDBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code());
1982 }
1983 
1984 // end of S390instructions
1985 
IsNop(SixByteInstr instr,int type)1986 bool Assembler::IsNop(SixByteInstr instr, int type) {
1987   DCHECK((0 == type) || (DEBUG_BREAK_NOP == type));
1988   if (DEBUG_BREAK_NOP == type) {
1989     return ((instr & 0xffffffff) == 0xa53b0000);  // oill r3, 0
1990   }
1991   return ((instr & 0xffff) == 0x1800);  // lr r0,r0
1992 }
1993 
1994 // dummy instruction reserved for special use.
dumy(int r1,int x2,int b2,int d2)1995 void Assembler::dumy(int r1, int x2, int b2, int d2) {
1996 #if defined(USE_SIMULATOR)
1997   int op = 0xE353;
1998   uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
1999                   (static_cast<uint64_t>(r1) & 0xF) * B36 |
2000                   (static_cast<uint64_t>(x2) & 0xF) * B32 |
2001                   (static_cast<uint64_t>(b2) & 0xF) * B28 |
2002                   (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
2003                   (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 |
2004                   (static_cast<uint64_t>(op & 0x00FF));
2005   emit6bytes(code);
2006 #endif
2007 }
2008 
GrowBuffer(int needed)2009 void Assembler::GrowBuffer(int needed) {
2010   if (!own_buffer_) FATAL("external code buffer is too small");
2011 
2012   // Compute new buffer size.
2013   CodeDesc desc;  // the new buffer
2014   if (buffer_size_ < 4 * KB) {
2015     desc.buffer_size = 4 * KB;
2016   } else if (buffer_size_ < 1 * MB) {
2017     desc.buffer_size = 2 * buffer_size_;
2018   } else {
2019     desc.buffer_size = buffer_size_ + 1 * MB;
2020   }
2021   int space = buffer_space() + (desc.buffer_size - buffer_size_);
2022   if (space < needed) {
2023     desc.buffer_size += needed - space;
2024   }
2025   CHECK_GT(desc.buffer_size, 0);  // no overflow
2026 
2027   // Set up new buffer.
2028   desc.buffer = NewArray<byte>(desc.buffer_size);
2029   desc.origin = this;
2030 
2031   desc.instr_size = pc_offset();
2032   desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2033 
2034   // Copy the data.
2035   intptr_t pc_delta = desc.buffer - buffer_;
2036   intptr_t rc_delta =
2037       (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2038   memmove(desc.buffer, buffer_, desc.instr_size);
2039   memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
2040           desc.reloc_size);
2041 
2042   // Switch buffers.
2043   DeleteArray(buffer_);
2044   buffer_ = desc.buffer;
2045   buffer_size_ = desc.buffer_size;
2046   pc_ += pc_delta;
2047   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2048                                reloc_info_writer.last_pc() + pc_delta);
2049 
2050   // None of our relocation types are pc relative pointing outside the code
2051   // buffer nor pc absolute pointing inside the code buffer, so there is no need
2052   // to relocate any emitted relocation entries.
2053 }
2054 
db(uint8_t data)2055 void Assembler::db(uint8_t data) {
2056   CheckBuffer();
2057   *reinterpret_cast<uint8_t*>(pc_) = data;
2058   pc_ += sizeof(uint8_t);
2059 }
2060 
dd(uint32_t data)2061 void Assembler::dd(uint32_t data) {
2062   CheckBuffer();
2063   *reinterpret_cast<uint32_t*>(pc_) = data;
2064   pc_ += sizeof(uint32_t);
2065 }
2066 
dq(uint64_t value)2067 void Assembler::dq(uint64_t value) {
2068   CheckBuffer();
2069   *reinterpret_cast<uint64_t*>(pc_) = value;
2070   pc_ += sizeof(uint64_t);
2071 }
2072 
dp(uintptr_t data)2073 void Assembler::dp(uintptr_t data) {
2074   CheckBuffer();
2075   *reinterpret_cast<uintptr_t*>(pc_) = data;
2076   pc_ += sizeof(uintptr_t);
2077 }
2078 
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2079 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2080   if (RelocInfo::IsNone(rmode) ||
2081       // Don't record external references unless the heap will be serialized.
2082       (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() &&
2083        !emit_debug_code())) {
2084     return;
2085   }
2086   if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2087     data = RecordedAstId().ToInt();
2088     ClearRecordedAstId();
2089   }
2090   DeferredRelocInfo rinfo(pc_offset(), rmode, data);
2091   relocations_.push_back(rinfo);
2092 }
2093 
emit_label_addr(Label * label)2094 void Assembler::emit_label_addr(Label* label) {
2095   CheckBuffer();
2096   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2097   int position = link(label);
2098   DCHECK(label->is_bound());
2099   // Keep internal references relative until EmitRelocations.
2100   dp(position);
2101 }
2102 
EmitRelocations()2103 void Assembler::EmitRelocations() {
2104   EnsureSpaceFor(relocations_.size() * kMaxRelocSize);
2105 
2106   for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin();
2107        it != relocations_.end(); it++) {
2108     RelocInfo::Mode rmode = it->rmode();
2109     Address pc = buffer_ + it->position();
2110     Code* code = NULL;
2111     RelocInfo rinfo(isolate(), pc, rmode, it->data(), code);
2112 
2113     // Fix up internal references now that they are guaranteed to be bound.
2114     if (RelocInfo::IsInternalReference(rmode)) {
2115       // Jump table entry
2116       intptr_t pos = reinterpret_cast<intptr_t>(Memory::Address_at(pc));
2117       Memory::Address_at(pc) = buffer_ + pos;
2118     } else if (RelocInfo::IsInternalReferenceEncoded(rmode)) {
2119       // mov sequence
2120       intptr_t pos = reinterpret_cast<intptr_t>(target_address_at(pc, code));
2121       set_target_address_at(isolate(), pc, code, buffer_ + pos,
2122                             SKIP_ICACHE_FLUSH);
2123     }
2124 
2125     reloc_info_writer.Write(&rinfo);
2126   }
2127 }
2128 
2129 }  // namespace internal
2130 }  // namespace v8
2131 #endif  // V8_TARGET_ARCH_S390
2132