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// A light-weight S390 Assembler
38// Generates user mode instructions for z/Architecture
39
40#ifndef V8_S390_ASSEMBLER_S390_H_
41#define V8_S390_ASSEMBLER_S390_H_
42#include <stdio.h>
43#if V8_HOST_ARCH_S390
44// elf.h include is required for auxv check for STFLE facility used
45// for hardware detection, which is sensible only on s390 hosts.
46#include <elf.h>
47#endif
48
49#include <fcntl.h>
50#include <unistd.h>
51#include "src/assembler.h"
52#include "src/s390/constants-s390.h"
53
54#define ABI_USES_FUNCTION_DESCRIPTORS 0
55
56#define ABI_PASSES_HANDLES_IN_REGS 1
57
58// ObjectPair is defined under runtime/runtime-util.h.
59// On 31-bit, ObjectPair == uint64_t.  ABI dictates long long
60//            be returned with the lower addressed half in r2
61//            and the higher addressed half in r3. (Returns in Regs)
62// On 64-bit, ObjectPair is a Struct.  ABI dictaes Structs be
63//            returned in a storage buffer allocated by the caller,
64//            with the address of this buffer passed as a hidden
65//            argument in r2. (Does NOT return in Regs)
66// For x86 linux, ObjectPair is returned in registers.
67#if V8_TARGET_ARCH_S390X
68#define ABI_RETURNS_OBJECTPAIR_IN_REGS 0
69#else
70#define ABI_RETURNS_OBJECTPAIR_IN_REGS 1
71#endif
72
73#define ABI_CALL_VIA_IP 1
74
75#define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC
76
77namespace v8 {
78namespace internal {
79
80// clang-format off
81#define GENERAL_REGISTERS(V)                              \
82  V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  \
83  V(r8)  V(r9)  V(r10) V(fp) V(ip) V(r13) V(r14) V(sp)
84
85#define ALLOCATABLE_GENERAL_REGISTERS(V)                  \
86  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)                \
87  V(r8)  V(r9)  V(r13)
88
89#define DOUBLE_REGISTERS(V)                               \
90  V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
91  V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13) V(d14) V(d15)
92
93#define FLOAT_REGISTERS DOUBLE_REGISTERS
94#define SIMD128_REGISTERS DOUBLE_REGISTERS
95
96#define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
97  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)         \
98  V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d15) V(d0)
99// clang-format on
100
101// CPU Registers.
102//
103// 1) We would prefer to use an enum, but enum values are assignment-
104// compatible with int, which has caused code-generation bugs.
105//
106// 2) We would prefer to use a class instead of a struct but we don't like
107// the register initialization to depend on the particular initialization
108// order (which appears to be different on OS X, Linux, and Windows for the
109// installed versions of C++ we tried). Using a struct permits C-style
110// "initialization". Also, the Register objects cannot be const as this
111// forces initialization stubs in MSVC, making us dependent on initialization
112// order.
113//
114// 3) By not using an enum, we are possibly preventing the compiler from
115// doing certain constant folds, which may significantly reduce the
116// code generated for some assembly instructions (because they boil down
117// to a few constants). If this is a problem, we could change the code
118// such that we use an enum in optimized mode, and the struct in debug
119// mode. This way we get the compile-time error checking in debug mode
120// and best performance in optimized code.
121
122struct Register {
123  enum Code {
124#define REGISTER_CODE(R) kCode_##R,
125    GENERAL_REGISTERS(REGISTER_CODE)
126#undef REGISTER_CODE
127        kAfterLast,
128    kCode_no_reg = -1
129  };
130  static const int kNumRegisters = Code::kAfterLast;
131
132#define REGISTER_COUNT(R) 1 +
133  static const int kNumAllocatable =
134      ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0;
135#undef REGISTER_COUNT
136
137#define REGISTER_BIT(R) 1 << kCode_##R |
138  static const RegList kAllocatable =
139      ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0;
140#undef REGISTER_BIT
141
142  static Register from_code(int code) {
143    DCHECK(code >= 0);
144    DCHECK(code < kNumRegisters);
145    Register r = {code};
146    return r;
147  }
148
149  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
150  bool is(Register reg) const { return reg_code == reg.reg_code; }
151  int code() const {
152    DCHECK(is_valid());
153    return reg_code;
154  }
155  int bit() const {
156    DCHECK(is_valid());
157    return 1 << reg_code;
158  }
159
160  void set_code(int code) {
161    reg_code = code;
162    DCHECK(is_valid());
163  }
164
165#if V8_TARGET_LITTLE_ENDIAN
166  static const int kMantissaOffset = 0;
167  static const int kExponentOffset = 4;
168#else
169  static const int kMantissaOffset = 4;
170  static const int kExponentOffset = 0;
171#endif
172
173  // Unfortunately we can't make this private in a struct.
174  int reg_code;
175};
176
177typedef struct Register Register;
178
179#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
180GENERAL_REGISTERS(DECLARE_REGISTER)
181#undef DECLARE_REGISTER
182const Register no_reg = {Register::kCode_no_reg};
183
184// Register aliases
185const Register kLithiumScratch = r1;  // lithium scratch.
186const Register kRootRegister = r10;   // Roots array pointer.
187const Register cp = r13;              // JavaScript context pointer.
188
189static const bool kSimpleFPAliasing = true;
190static const bool kSimdMaskRegisters = false;
191
192// Double word FP register.
193struct DoubleRegister {
194  enum Code {
195#define REGISTER_CODE(R) kCode_##R,
196    DOUBLE_REGISTERS(REGISTER_CODE)
197#undef REGISTER_CODE
198        kAfterLast,
199    kCode_no_reg = -1
200  };
201
202  static const int kNumRegisters = Code::kAfterLast;
203  static const int kMaxNumRegisters = kNumRegisters;
204
205  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
206  bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
207
208  int code() const {
209    DCHECK(is_valid());
210    return reg_code;
211  }
212
213  int bit() const {
214    DCHECK(is_valid());
215    return 1 << reg_code;
216  }
217
218  static DoubleRegister from_code(int code) {
219    DoubleRegister r = {code};
220    return r;
221  }
222
223  int reg_code;
224};
225
226typedef DoubleRegister FloatRegister;
227
228// TODO(john.yan) Define SIMD registers.
229typedef DoubleRegister Simd128Register;
230
231#define DECLARE_REGISTER(R) \
232  const DoubleRegister R = {DoubleRegister::kCode_##R};
233DOUBLE_REGISTERS(DECLARE_REGISTER)
234#undef DECLARE_REGISTER
235const Register no_dreg = {Register::kCode_no_reg};
236
237// Aliases for double registers.  Defined using #define instead of
238// "static const DoubleRegister&" because Clang complains otherwise when a
239// compilation unit that includes this header doesn't use the variables.
240#define kDoubleRegZero d14
241#define kScratchDoubleReg d13
242
243Register ToRegister(int num);
244
245// Coprocessor register
246struct CRegister {
247  bool is_valid() const { return 0 <= reg_code && reg_code < 8; }
248  bool is(CRegister creg) const { return reg_code == creg.reg_code; }
249  int code() const {
250    DCHECK(is_valid());
251    return reg_code;
252  }
253  int bit() const {
254    DCHECK(is_valid());
255    return 1 << reg_code;
256  }
257
258  // Unfortunately we can't make this private in a struct.
259  int reg_code;
260};
261
262const CRegister no_creg = {-1};
263
264const CRegister cr0 = {0};
265const CRegister cr1 = {1};
266const CRegister cr2 = {2};
267const CRegister cr3 = {3};
268const CRegister cr4 = {4};
269const CRegister cr5 = {5};
270const CRegister cr6 = {6};
271const CRegister cr7 = {7};
272
273// -----------------------------------------------------------------------------
274// Machine instruction Operands
275
276#if V8_TARGET_ARCH_S390X
277const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64;
278#else
279const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32;
280#endif
281
282// Class Operand represents a shifter operand in data processing instructions
283// defining immediate numbers and masks
284typedef uint8_t Length;
285
286struct Mask {
287  uint8_t mask;
288  uint8_t value() { return mask; }
289  static Mask from_value(uint8_t input) {
290    DCHECK(input <= 0x0F);
291    Mask m = {input};
292    return m;
293  }
294};
295
296class Operand BASE_EMBEDDED {
297 public:
298  // immediate
299  INLINE(explicit Operand(intptr_t immediate,
300                          RelocInfo::Mode rmode = kRelocInfo_NONEPTR));
301  INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); }
302  INLINE(explicit Operand(const ExternalReference& f));
303  explicit Operand(Handle<Object> handle);
304  INLINE(explicit Operand(Smi* value));
305
306  // rm
307  INLINE(explicit Operand(Register rm));
308
309  // Return true if this is a register operand.
310  INLINE(bool is_reg() const);
311
312  bool must_output_reloc_info(const Assembler* assembler) const;
313
314  inline intptr_t immediate() const {
315    DCHECK(!rm_.is_valid());
316    return imm_;
317  }
318
319  inline void setBits(int n) {
320    imm_ = (static_cast<uint32_t>(imm_) << (32 - n)) >> (32 - n);
321  }
322
323  Register rm() const { return rm_; }
324
325 private:
326  Register rm_;
327  intptr_t imm_;  // valid if rm_ == no_reg
328  RelocInfo::Mode rmode_;
329
330  friend class Assembler;
331  friend class MacroAssembler;
332};
333
334typedef int32_t Disp;
335
336// Class MemOperand represents a memory operand in load and store instructions
337// On S390, we have various flavours of memory operands:
338//   1) a base register + 16 bit unsigned displacement
339//   2) a base register + index register + 16 bit unsigned displacement
340//   3) a base register + index register + 20 bit signed displacement
341class MemOperand BASE_EMBEDDED {
342 public:
343  explicit MemOperand(Register rx, Disp offset = 0);
344  explicit MemOperand(Register rx, Register rb, Disp offset = 0);
345
346  int32_t offset() const { return offset_; }
347  uint32_t getDisplacement() const { return offset(); }
348
349  // Base register
350  Register rb() const {
351    DCHECK(!baseRegister.is(no_reg));
352    return baseRegister;
353  }
354
355  Register getBaseRegister() const { return rb(); }
356
357  // Index Register
358  Register rx() const {
359    DCHECK(!indexRegister.is(no_reg));
360    return indexRegister;
361  }
362  Register getIndexRegister() const { return rx(); }
363
364 private:
365  Register baseRegister;   // base
366  Register indexRegister;  // index
367  int32_t offset_;         // offset
368
369  friend class Assembler;
370};
371
372class DeferredRelocInfo {
373 public:
374  DeferredRelocInfo() {}
375  DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data)
376      : position_(position), rmode_(rmode), data_(data) {}
377
378  int position() const { return position_; }
379  RelocInfo::Mode rmode() const { return rmode_; }
380  intptr_t data() const { return data_; }
381
382 private:
383  int position_;
384  RelocInfo::Mode rmode_;
385  intptr_t data_;
386};
387
388class Assembler : public AssemblerBase {
389 public:
390  // Create an assembler. Instructions and relocation information are emitted
391  // into a buffer, with the instructions starting from the beginning and the
392  // relocation information starting from the end of the buffer. See CodeDesc
393  // for a detailed comment on the layout (globals.h).
394  //
395  // If the provided buffer is NULL, the assembler allocates and grows its own
396  // buffer, and buffer_size determines the initial buffer size. The buffer is
397  // owned by the assembler and deallocated upon destruction of the assembler.
398  //
399  // If the provided buffer is not NULL, the assembler uses the provided buffer
400  // for code generation and assumes its size to be buffer_size. If the buffer
401  // is too small, a fatal error occurs. No deallocation of the buffer is done
402  // upon destruction of the assembler.
403  Assembler(Isolate* isolate, void* buffer, int buffer_size);
404  virtual ~Assembler() {}
405
406  // GetCode emits any pending (non-emitted) code and fills the descriptor
407  // desc. GetCode() is idempotent; it returns the same result if no other
408  // Assembler functions are invoked in between GetCode() calls.
409  void GetCode(CodeDesc* desc);
410
411  // Label operations & relative jumps (PPUM Appendix D)
412  //
413  // Takes a branch opcode (cc) and a label (L) and generates
414  // either a backward branch or a forward branch and links it
415  // to the label fixup chain. Usage:
416  //
417  // Label L;    // unbound label
418  // j(cc, &L);  // forward branch to unbound label
419  // bind(&L);   // bind label to the current pc
420  // j(cc, &L);  // backward branch to bound label
421  // bind(&L);   // illegal: a label may be bound only once
422  //
423  // Note: The same Label can be used for forward and backward branches
424  // but it may be bound only once.
425
426  void bind(Label* L);  // binds an unbound label L to the current code position
427
428  // Links a label at the current pc_offset().  If already bound, returns the
429  // bound position.  If already linked, returns the position of the prior link.
430  // Otherwise, returns the current pc_offset().
431  int link(Label* L);
432
433  // Determines if Label is bound and near enough so that a single
434  // branch instruction can be used to reach it.
435  bool is_near(Label* L, Condition cond);
436
437  // Returns the branch offset to the given label from the current code position
438  // Links the label to the current position if it is still unbound
439  int branch_offset(Label* L) { return link(L) - pc_offset(); }
440
441  // Puts a labels target address at the given position.
442  // The high 8 bits are set to zero.
443  void label_at_put(Label* L, int at_offset);
444  void load_label_offset(Register r1, Label* L);
445
446  // Read/Modify the code target address in the branch/call instruction at pc.
447  INLINE(static Address target_address_at(Address pc, Address constant_pool));
448  INLINE(static void set_target_address_at(
449      Isolate* isolate, Address pc, Address constant_pool, Address target,
450      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
451  INLINE(static Address target_address_at(Address pc, Code* code));
452  INLINE(static void set_target_address_at(
453      Isolate* isolate, Address pc, Code* code, Address target,
454      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
455
456  // Return the code target address at a call site from the return address
457  // of that call in the instruction stream.
458  inline static Address target_address_from_return_address(Address pc);
459
460  // Given the address of the beginning of a call, return the address
461  // in the instruction stream that the call will return to.
462  INLINE(static Address return_address_from_call_start(Address pc));
463
464  inline Handle<Object> code_target_object_handle_at(Address pc);
465  // This sets the branch destination.
466  // This is for calls and branches within generated code.
467  inline static void deserialization_set_special_target_at(
468      Isolate* isolate, Address instruction_payload, Code* code,
469      Address target);
470
471  // This sets the internal reference at the pc.
472  inline static void deserialization_set_target_internal_reference_at(
473      Isolate* isolate, Address pc, Address target,
474      RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
475
476  // Here we are patching the address in the IIHF/IILF instruction pair.
477  // These values are used in the serialization process and must be zero for
478  // S390 platform, as Code, Embedded Object or External-reference pointers
479  // are split across two consecutive instructions and don't exist separately
480  // in the code, so the serializer should not step forwards in memory after
481  // a target is resolved and written.
482  static const int kSpecialTargetSize = 0;
483
484// Number of bytes for instructions used to store pointer sized constant.
485#if V8_TARGET_ARCH_S390X
486  static const int kBytesForPtrConstant = 12;  // IIHF + IILF
487#else
488  static const int kBytesForPtrConstant = 6;  // IILF
489#endif
490
491  // Distance between the instruction referring to the address of the call
492  // target and the return address.
493
494  // Offset between call target address and return address
495  // for BRASL calls
496  // Patch will be appiled to other FIXED_SEQUENCE call
497  static const int kCallTargetAddressOffset = 6;
498
499// The length of FIXED_SEQUENCE call
500// iihf    r8, <address_hi>  // <64-bit only>
501// iilf    r8, <address_lo>
502// basr    r14, r8
503#if V8_TARGET_ARCH_S390X
504  static const int kCallSequenceLength = 14;
505#else
506  static const int kCallSequenceLength = 8;
507#endif
508
509  // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn()
510  // code patch FIXED_SEQUENCE in bytes!
511  // JS Return Sequence = Call Sequence + BKPT
512  // static const int kJSReturnSequenceLength = kCallSequenceLength + 2;
513
514  // This is the length of the code sequence from SetDebugBreakAtSlot()
515  // FIXED_SEQUENCE in bytes!
516  static const int kDebugBreakSlotLength = kCallSequenceLength;
517  static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset;
518
519  // Length to patch between the start of the JS return sequence
520  // from SetDebugBreakAtReturn and the address from
521  // break_address_from_return_address.
522  //
523  // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in
524  // JS return sequence, so the length to patch will not include BKPT
525  // instruction length.
526  // static const int kPatchReturnSequenceAddressOffset =
527  //     kCallSequenceLength - kPatchDebugBreakSlotReturnOffset;
528
529  // Length to patch between the start of the FIXED call sequence from
530  // SetDebugBreakAtSlot() and the the address from
531  // break_address_from_return_address.
532  static const int kPatchDebugBreakSlotAddressOffset =
533      kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset;
534
535  static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
536    return ((cr.code() * CRWIDTH) + crbit);
537  }
538
539  // ---------------------------------------------------------------------------
540  // Code generation
541
542  template <class T, int size, int lo, int hi>
543  inline T getfield(T value) {
544    DCHECK(lo < hi);
545    DCHECK(size > 0);
546    int mask = hi - lo;
547    int shift = size * 8 - hi;
548    uint32_t mask_value = (mask == 32) ? 0xffffffff : (1 << mask) - 1;
549    return (value & mask_value) << shift;
550  }
551
552  // Declare generic instruction formats by fields
553  inline void e_format(Opcode opcode) {
554    emit2bytes(getfield<uint16_t, 2, 0, 16>(opcode));
555  }
556
557  inline void i_format(Opcode opcode, int f1) {
558    emit2bytes(getfield<uint16_t, 2, 0, 8>(opcode) |
559               getfield<uint16_t, 2, 8, 16>(f1));
560  }
561
562  inline void ie_format(Opcode opcode, int f1, int f2) {
563    emit4bytes(getfield<uint32_t, 4, 0, 16>(opcode) |
564               getfield<uint32_t, 4, 24, 28>(f1) |
565               getfield<uint32_t, 4, 28, 32>(f2));
566  }
567  inline void mii_format(Opcode opcode, int f1, int f2, int f3) {
568    emit6bytes(
569        getfield<uint64_t, 6, 0, 8>(opcode) | getfield<uint64_t, 6, 8, 12>(f1) |
570        getfield<uint64_t, 6, 12, 24>(f2) | getfield<uint64_t, 6, 24, 48>(f3));
571  }
572
573  inline void ri_format(Opcode opcode, int f1, int f2) {
574    uint32_t op1 = opcode >> 4;
575    uint32_t op2 = opcode & 0xf;
576    emit4bytes(
577        getfield<uint32_t, 4, 0, 8>(op1) | getfield<uint32_t, 4, 8, 12>(f1) |
578        getfield<uint32_t, 4, 12, 16>(op2) | getfield<uint32_t, 4, 16, 32>(f2));
579  }
580
581  inline void rie_1_format(Opcode opcode, int f1, int f2, int f3, int f4) {
582    uint32_t op1 = opcode >> 8;
583    uint32_t op2 = opcode & 0xff;
584    emit6bytes(
585        getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) |
586        getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 32>(f3) |
587        getfield<uint64_t, 6, 32, 36>(f4) | getfield<uint64_t, 6, 40, 48>(op2));
588  }
589
590  inline void rie_2_format(Opcode opcode, int f1, int f2, int f3, int f4) {
591    uint32_t op1 = opcode >> 8;
592    uint32_t op2 = opcode & 0xff;
593    emit6bytes(
594        getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) |
595        getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 32>(f3) |
596        getfield<uint64_t, 6, 32, 40>(f4) | getfield<uint64_t, 6, 40, 48>(op2));
597  }
598
599  inline void rie_3_format(Opcode opcode, int f1, int f2, int f3, int f4,
600                           int f5) {
601    uint32_t op1 = opcode >> 8;
602    uint32_t op2 = opcode & 0xff;
603    emit6bytes(
604        getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) |
605        getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 24>(f3) |
606        getfield<uint64_t, 6, 24, 32>(f4) | getfield<uint64_t, 6, 32, 40>(f5) |
607        getfield<uint64_t, 6, 40, 48>(op2));
608  }
609
610#define DECLARE_S390_RIL_AB_INSTRUCTIONS(name, op_name, op_value) \
611  template <class R1>                                             \
612  inline void name(R1 r1, const Operand& i2) {                    \
613    ril_format(op_name, r1.code(), i2.immediate());               \
614  }
615#define DECLARE_S390_RIL_C_INSTRUCTIONS(name, op_name, op_value) \
616  inline void name(Condition m1, const Operand& i2) {            \
617    ril_format(op_name, m1, i2.immediate());                     \
618  }
619
620  inline void ril_format(Opcode opcode, int f1, int f2) {
621    uint32_t op1 = opcode >> 4;
622    uint32_t op2 = opcode & 0xf;
623    emit6bytes(
624        getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) |
625        getfield<uint64_t, 6, 12, 16>(op2) | getfield<uint64_t, 6, 16, 48>(f2));
626  }
627  S390_RIL_A_OPCODE_LIST(DECLARE_S390_RIL_AB_INSTRUCTIONS)
628  S390_RIL_B_OPCODE_LIST(DECLARE_S390_RIL_AB_INSTRUCTIONS)
629  S390_RIL_C_OPCODE_LIST(DECLARE_S390_RIL_C_INSTRUCTIONS)
630#undef DECLARE_S390_RIL_AB_INSTRUCTIONS
631#undef DECLARE_S390_RIL_C_INSTRUCTIONS
632
633  inline void ris_format(Opcode opcode, int f1, int f2, int f3, int f4,
634                         int f5) {
635    uint32_t op1 = opcode >> 8;
636    uint32_t op2 = opcode & 0xff;
637    emit6bytes(
638        getfield<uint64_t, 6, 0, 8>(op1) | getfield<uint64_t, 6, 8, 12>(f1) |
639        getfield<uint64_t, 6, 12, 16>(f2) | getfield<uint64_t, 6, 16, 20>(f3) |
640        getfield<uint64_t, 6, 20, 32>(f4) | getfield<uint64_t, 6, 32, 40>(f5) |
641        getfield<uint64_t, 6, 40, 48>(op2));
642  }
643
644#define DECLARE_S390_RR_INSTRUCTIONS(name, op_name, op_value) \
645  inline void name(Register r1, Register r2) {                \
646    rr_format(op_name, r1.code(), r2.code());                 \
647  }                                                           \
648  inline void name(DoubleRegister r1, DoubleRegister r2) {    \
649    rr_format(op_name, r1.code(), r2.code());                 \
650  }                                                           \
651  inline void name(Condition m1, Register r2) {               \
652    rr_format(op_name, m1, r2.code());                        \
653  }
654
655  inline void rr_format(Opcode opcode, int f1, int f2) {
656    emit2bytes(getfield<uint16_t, 2, 0, 8>(opcode) |
657               getfield<uint16_t, 2, 8, 12>(f1) |
658               getfield<uint16_t, 2, 12, 16>(f2));
659  }
660  S390_RR_OPCODE_LIST(DECLARE_S390_RR_INSTRUCTIONS)
661#undef DECLARE_S390_RR_INSTRUCTIONS
662
663#define DECLARE_S390_RRD_INSTRUCTIONS(name, op_name, op_value) \
664  template <class R1, class R2, class R3>                      \
665  inline void name(R1 r1, R3 r3, R2 r2) {                      \
666    rrd_format(op_name, r1.code(), r3.code(), r2.code());      \
667  }
668  inline void rrd_format(Opcode opcode, int f1, int f2, int f3) {
669    emit4bytes(getfield<uint32_t, 4, 0, 16>(opcode) |
670               getfield<uint32_t, 4, 16, 20>(f1) |
671               getfield<uint32_t, 4, 24, 28>(f2) |
672               getfield<uint32_t, 4, 28, 32>(f3));
673  }
674  S390_RRD_OPCODE_LIST(DECLARE_S390_RRD_INSTRUCTIONS)
675#undef DECLARE_S390_RRD_INSTRUCTIONS
676
677#define DECLARE_S390_RRE_INSTRUCTIONS(name, op_name, op_value) \
678  template <class R1, class R2>                                \
679  inline void name(R1 r1, R2 r2) {                             \
680    rre_format(op_name, r1.code(), r2.code());                 \
681  }
682  inline void rre_format(Opcode opcode, int f1, int f2) {
683    emit4bytes(getfield<uint32_t, 4, 0, 16>(opcode) |
684               getfield<uint32_t, 4, 24, 28>(f1) |
685               getfield<uint32_t, 4, 28, 32>(f2));
686  }
687  S390_RRE_OPCODE_LIST(DECLARE_S390_RRE_INSTRUCTIONS)
688  // Special format
689  void lzdr(DoubleRegister r1) { rre_format(LZDR, r1.code(), 0); }
690#undef DECLARE_S390_RRE_INSTRUCTIONS
691
692  inline void rrf_format(Opcode opcode, int f1, int f2, int f3, int f4) {
693    emit4bytes(
694        getfield<uint32_t, 4, 0, 16>(opcode) |
695        getfield<uint32_t, 4, 16, 20>(f1) | getfield<uint32_t, 4, 20, 24>(f2) |
696        getfield<uint32_t, 4, 24, 28>(f3) | getfield<uint32_t, 4, 28, 32>(f4));
697  }
698
699#define DECLARE_S390_RX_INSTRUCTIONS(name, op_name, op_value)        \
700  template <class R1>                                                \
701  inline void name(R1 r1, Register x2, Register b2, Disp d2) {       \
702    rx_format(op_name, r1.code(), x2.code(), b2.code(), d2);         \
703  }                                                                  \
704  template <class R1>                                                \
705  inline void name(R1 r1, const MemOperand& opnd) {                  \
706    name(r1, opnd.getIndexRegister(),                                \
707         opnd.getBaseRegister(), opnd.getDisplacement());            \
708  }
709
710  inline void rx_format(Opcode opcode, int f1, int f2, int f3, int f4) {
711    DCHECK(is_uint8(opcode));
712    DCHECK(is_uint12(f4));
713    emit4bytes(getfield<uint32_t, 4, 0, 8>(opcode) |
714               getfield<uint32_t, 4, 8, 12>(f1) |
715               getfield<uint32_t, 4, 12, 16>(f2) |
716               getfield<uint32_t, 4, 16, 20>(f3) |
717               getfield<uint32_t, 4, 20, 32>(f4));
718  }
719  S390_RX_A_OPCODE_LIST(DECLARE_S390_RX_INSTRUCTIONS)
720
721  void bc(Condition cond, const MemOperand& opnd) {
722    bc(cond, opnd.getIndexRegister(),
723       opnd.getBaseRegister(), opnd.getDisplacement());
724  }
725  void bc(Condition cond, Register x2, Register b2, Disp d2) {
726    rx_format(BC, cond, x2.code(), b2.code(), d2);
727  }
728#undef DECLARE_S390_RX_INSTRUCTIONS
729
730#define DECLARE_S390_RXY_INSTRUCTIONS(name, op_name, op_value)       \
731  template <class R1, class R2>                                      \
732  inline void name(R1 r1, R2 r2, Register b2, Disp d2) {             \
733    rxy_format(op_name, r1.code(), r2.code(), b2.code(), d2);        \
734  }                                                                  \
735  template <class R1>                                                \
736  inline void name(R1 r1, const MemOperand& opnd) {                  \
737    name(r1, opnd.getIndexRegister(),                                \
738         opnd.getBaseRegister(), opnd.getDisplacement());            \
739  }
740
741  inline void rxy_format(Opcode opcode, int f1, int f2, int f3, int f4) {
742    DCHECK(is_uint16(opcode));
743    DCHECK(is_int20(f4));
744    emit6bytes(getfield<uint64_t, 6, 0, 8>(opcode >> 8) |
745               getfield<uint64_t, 6, 8, 12>(f1) |
746               getfield<uint64_t, 6, 12, 16>(f2) |
747               getfield<uint64_t, 6, 16, 20>(f3) |
748               getfield<uint64_t, 6, 20, 32>(f4 & 0x0fff) |
749               getfield<uint64_t, 6, 32, 40>(f4 >> 12) |
750               getfield<uint64_t, 6, 40, 48>(opcode & 0x00ff));
751  }
752  S390_RXY_A_OPCODE_LIST(DECLARE_S390_RXY_INSTRUCTIONS)
753
754  void pfd(Condition cond, const MemOperand& opnd) {
755    pfd(cond, opnd.getIndexRegister(),
756        opnd.getBaseRegister(), opnd.getDisplacement());
757  }
758  void pfd(Condition cond, Register x2, Register b2, Disp d2) {
759    rxy_format(PFD, cond, x2.code(), b2.code(), d2);
760  }
761#undef DECLARE_S390_RXY_INSTRUCTIONS
762
763  // Helper for unconditional branch to Label with update to save register
764  void b(Register r, Label* l) {
765    int32_t halfwords = branch_offset(l) / 2;
766    brasl(r, Operand(halfwords));
767  }
768
769  // Conditional Branch Instruction - Generates either BRC / BRCL
770  void branchOnCond(Condition c, int branch_offset, bool is_bound = false);
771
772  // Helpers for conditional branch to Label
773  void b(Condition cond, Label* l, Label::Distance dist = Label::kFar) {
774    branchOnCond(cond, branch_offset(l),
775                 l->is_bound() || (dist == Label::kNear));
776  }
777
778  void bc_short(Condition cond, Label* l, Label::Distance dist = Label::kFar) {
779    b(cond, l, Label::kNear);
780  }
781  // Helpers for conditional branch to Label
782  void beq(Label* l, Label::Distance dist = Label::kFar) { b(eq, l, dist); }
783  void bne(Label* l, Label::Distance dist = Label::kFar) { b(ne, l, dist); }
784  void blt(Label* l, Label::Distance dist = Label::kFar) { b(lt, l, dist); }
785  void ble(Label* l, Label::Distance dist = Label::kFar) { b(le, l, dist); }
786  void bgt(Label* l, Label::Distance dist = Label::kFar) { b(gt, l, dist); }
787  void bge(Label* l, Label::Distance dist = Label::kFar) { b(ge, l, dist); }
788  void b(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); }
789  void jmp(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); }
790  void bunordered(Label* l, Label::Distance dist = Label::kFar) {
791    b(unordered, l, dist);
792  }
793  void bordered(Label* l, Label::Distance dist = Label::kFar) {
794    b(ordered, l, dist);
795  }
796
797  // Helpers for conditional indirect branch off register
798  void b(Condition cond, Register r) { bcr(cond, r); }
799  void beq(Register r) { b(eq, r); }
800  void bne(Register r) { b(ne, r); }
801  void blt(Register r) { b(lt, r); }
802  void ble(Register r) { b(le, r); }
803  void bgt(Register r) { b(gt, r); }
804  void bge(Register r) { b(ge, r); }
805  void b(Register r) { b(al, r); }
806  void jmp(Register r) { b(al, r); }
807  void bunordered(Register r) { b(unordered, r); }
808  void bordered(Register r) { b(ordered, r); }
809
810  // ---------------------------------------------------------------------------
811  // Code generation
812
813  // Insert the smallest number of nop instructions
814  // possible to align the pc offset to a multiple
815  // of m. m must be a power of 2 (>= 4).
816  void Align(int m);
817  // Insert the smallest number of zero bytes possible to align the pc offset
818  // to a mulitple of m. m must be a power of 2 (>= 2).
819  void DataAlign(int m);
820  // Aligns code to something that's optimal for a jump target for the platform.
821  void CodeTargetAlign();
822
823  void breakpoint(bool do_print) {
824    if (do_print) {
825      PrintF("DebugBreak is inserted to %p\n", static_cast<void*>(pc_));
826    }
827#if V8_HOST_ARCH_64_BIT
828    int64_t value = reinterpret_cast<uint64_t>(&v8::base::OS::DebugBreak);
829    int32_t hi_32 = static_cast<int64_t>(value) >> 32;
830    int32_t lo_32 = static_cast<int32_t>(value);
831
832    iihf(r1, Operand(hi_32));
833    iilf(r1, Operand(lo_32));
834#else
835    iilf(r1, Operand(reinterpret_cast<uint32_t>(&v8::base::OS::DebugBreak)));
836#endif
837    basr(r14, r1);
838  }
839
840  void call(Handle<Code> target, RelocInfo::Mode rmode,
841            TypeFeedbackId ast_id = TypeFeedbackId::None());
842  void jump(Handle<Code> target, RelocInfo::Mode rmode, Condition cond);
843
844// S390 instruction generation
845#define I_FORM(name) void name(const Operand& i)
846
847#define RR_FORM(name) void name(Register r1, Register r2)
848
849#define RR2_FORM(name) void name(Condition m1, Register r2)
850
851#define RI1_FORM(name) void name(Register r, const Operand& i)
852
853#define RI2_FORM(name) void name(Condition m, const Operand& i)
854
855#define RIE_FORM(name) void name(Register r1, Register R3, const Operand& i)
856
857#define RIE_F_FORM(name)                                                    \
858  void name(Register r1, Register r2, const Operand& i3, const Operand& i4, \
859            const Operand& i5)
860
861#define RXE_FORM(name)                            \
862  void name(Register r1, const MemOperand& opnd); \
863  void name(Register r1, Register b2, Register x2, Disp d2)
864
865#define RXF_FORM(name)                                         \
866  void name(Register r1, Register r3, const MemOperand& opnd); \
867  void name(Register r1, Register r3, Register b2, Register x2, Disp d2)
868
869#define RSI_FORM(name) void name(Register r1, Register r3, const Operand& i)
870
871#define RIS_FORM(name)                                       \
872  void name(Register r1, Condition m3, Register b4, Disp d4, \
873            const Operand& i2);                              \
874  void name(Register r1, const Operand& i2, Condition m3,    \
875            const MemOperand& opnd)
876
877#define SI_FORM(name)                                  \
878  void name(const MemOperand& opnd, const Operand& i); \
879  void name(const Operand& i2, Register b1, Disp d1)
880
881#define SIL_FORM(name)                                \
882  void name(Register b1, Disp d1, const Operand& i2); \
883  void name(const MemOperand& opnd, const Operand& i2)
884
885#define RRF1_FORM(name) void name(Register r1, Register r2, Register r3)
886
887#define RRF2_FORM(name) void name(Condition m1, Register r1, Register r2)
888
889#define RRF3_FORM(name) \
890  void name(Register r3, Condition m4, Register r1, Register r2)
891
892#define RS1_FORM(name)                                         \
893  void name(Register r1, Register r3, const MemOperand& opnd); \
894  void name(Register r1, Register r3, Register b2, Disp d2)
895
896#define RS2_FORM(name)                                          \
897  void name(Register r1, Condition m3, const MemOperand& opnd); \
898  void name(Register r1, Condition m3, Register b2, Disp d2)
899
900#define RSE_FORM(name)                                         \
901  void name(Register r1, Register r3, const MemOperand& opnd); \
902  void name(Register r1, Register r3, Register b2, Disp d2)
903
904#define RSL_FORM(name)                       \
905  void name(Length l, Register b2, Disp d2); \
906  void name(const MemOperand& opnd)
907
908#define RSY1_FORM(name)                                      \
909  void name(Register r1, Register r3, Register b2, Disp d2); \
910  void name(Register r1, Register r3, const MemOperand& opnd)
911
912#define RSY2_FORM(name)                                       \
913  void name(Register r1, Condition m3, Register b2, Disp d2); \
914  void name(Register r1, Condition m3, const MemOperand& opnd)
915
916#define RRS_FORM(name)                                                     \
917  void name(Register r1, Register r2, Register b4, Disp d4, Condition m3); \
918  void name(Register r1, Register r2, Condition m3, const MemOperand& opnd)
919
920#define S_FORM(name)               \
921  void name(Register b2, Disp d2); \
922  void name(const MemOperand& opnd)
923
924#define SIY_FORM(name)                                \
925  void name(const Operand& i2, Register b1, Disp d1); \
926  void name(const MemOperand& opnd, const Operand& i)
927
928#define SS1_FORM(name)                                                  \
929  void name(Register b1, Disp d1, Register b3, Disp d2, Length length); \
930  void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length)
931
932#define SS2_FORM(name)                                                        \
933  void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length1, \
934            Length length2);                                                  \
935  void name(Register b1, Disp d1, Register b2, Disp d2, Length l1, Length l2)
936
937#define SS3_FORM(name)                                                        \
938  void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length); \
939  void name(const Operand& i3, Register b1, Disp d1, Register b2, Disp d2,    \
940            Length l1)
941
942#define SS4_FORM(name)                                                   \
943  void name(const MemOperand& opnd1, const MemOperand& opnd2);           \
944  void name(Register r1, Register r3, Register b1, Disp d1, Register b2, \
945            Disp d2)
946
947#define SS5_FORM(name)                                                   \
948  void name(const MemOperand& opnd1, const MemOperand& opnd2);           \
949  void name(Register r1, Register r3, Register b3, Disp d2, Register b4, \
950            Disp d4)
951
952#define SSE_FORM(name)                                   \
953  void name(Register b1, Disp d1, Register b2, Disp d2); \
954  void name(const MemOperand& opnd1, const MemOperand& opnd2)
955
956#define SSF_FORM(name)                                                \
957  void name(Register r3, Register b1, Disp d1, Register b2, Disp d2); \
958  void name(Register r3, const MemOperand& opnd1, const MemOperand& opnd2)
959
960#define DECLARE_VRR_A_INSTRUCTIONS(name, opcode_name, opcode_value)           \
961  void name(DoubleRegister v1, DoubleRegister v2, Condition m5, Condition m4, \
962            Condition m3) {                                                   \
963    uint64_t code = (static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 |    \
964                    (static_cast<uint64_t>(v1.code())) * B36 |                \
965                    (static_cast<uint64_t>(v2.code())) * B32 |                \
966                    (static_cast<uint64_t>(m5 & 0xF)) * B20 |                 \
967                    (static_cast<uint64_t>(m4 & 0xF)) * B16 |                 \
968                    (static_cast<uint64_t>(m3 & 0xF)) * B12 |                 \
969                    (static_cast<uint64_t>(opcode_value & 0x00FF));           \
970    emit6bytes(code);                                                         \
971  }
972  S390_VRR_A_OPCODE_LIST(DECLARE_VRR_A_INSTRUCTIONS)
973#undef DECLARE_VRR_A_INSTRUCTIONS
974
975#define DECLARE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value)        \
976  void name(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3,       \
977            Condition m6, Condition m5, Condition m4) {                    \
978    uint64_t code = (static_cast<uint64_t>(opcode_value & 0xFF00)) * B32 | \
979                    (static_cast<uint64_t>(v1.code())) * B36 |             \
980                    (static_cast<uint64_t>(v2.code())) * B32 |             \
981                    (static_cast<uint64_t>(v3.code())) * B28 |             \
982                    (static_cast<uint64_t>(m6 & 0xF)) * B20 |              \
983                    (static_cast<uint64_t>(m5 & 0xF)) * B16 |              \
984                    (static_cast<uint64_t>(m4 & 0xF)) * B12 |              \
985                    (static_cast<uint64_t>(opcode_value & 0x00FF));        \
986    emit6bytes(code);                                                      \
987  }
988  S390_VRR_C_OPCODE_LIST(DECLARE_VRR_C_INSTRUCTIONS)
989#undef DECLARE_VRR_C_INSTRUCTIONS
990
991  // Single Element format
992  void vfa(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3) {
993    vfa(v1, v2, v3, static_cast<Condition>(0), static_cast<Condition>(8),
994        static_cast<Condition>(3));
995  }
996  void vfs(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3) {
997    vfs(v1, v2, v3, static_cast<Condition>(0), static_cast<Condition>(8),
998        static_cast<Condition>(3));
999  }
1000  void vfm(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3) {
1001    vfm(v1, v2, v3, static_cast<Condition>(0), static_cast<Condition>(8),
1002        static_cast<Condition>(3));
1003  }
1004  void vfd(DoubleRegister v1, DoubleRegister v2, DoubleRegister v3) {
1005    vfd(v1, v2, v3, static_cast<Condition>(0), static_cast<Condition>(8),
1006        static_cast<Condition>(3));
1007  }
1008
1009  // S390 instruction sets
1010  RXE_FORM(ddb);
1011  SS1_FORM(ed);
1012  RRF2_FORM(fidbr);
1013  RI1_FORM(iihh);
1014  RI1_FORM(iihl);
1015  RI1_FORM(iilh);
1016  RI1_FORM(iill);
1017  RSY1_FORM(loc);
1018  RXE_FORM(mdb);
1019  SS4_FORM(mvck);
1020  SSF_FORM(mvcos);
1021  SS4_FORM(mvcs);
1022  SS1_FORM(mvn);
1023  SS1_FORM(nc);
1024  SI_FORM(ni);
1025  RI1_FORM(nilh);
1026  RI1_FORM(nill);
1027  RI1_FORM(oill);
1028  RXE_FORM(sdb);
1029  RS1_FORM(srdl);
1030  RI1_FORM(tmll);
1031  SS1_FORM(tr);
1032  S_FORM(ts);
1033
1034  // Load Address Instructions
1035  void larl(Register r, Label* l);
1036
1037  // Load Instructions
1038  void lhi(Register r, const Operand& imm);
1039  void lghi(Register r, const Operand& imm);
1040
1041  // Load Multiple Instructions
1042  void lm(Register r1, Register r2, const MemOperand& src);
1043  void lmy(Register r1, Register r2, const MemOperand& src);
1044  void lmg(Register r1, Register r2, const MemOperand& src);
1045
1046  // Load On Condition Instructions
1047  void locr(Condition m3, Register r1, Register r2);
1048  void locgr(Condition m3, Register r1, Register r2);
1049  void loc(Condition m3, Register r1, const MemOperand& src);
1050  void locg(Condition m3, Register r1, const MemOperand& src);
1051
1052  // Store Instructions
1053
1054  // Store Multiple Instructions
1055  void stm(Register r1, Register r2, const MemOperand& src);
1056  void stmy(Register r1, Register r2, const MemOperand& src);
1057  void stmg(Register r1, Register r2, const MemOperand& src);
1058
1059  // Compare Instructions
1060  void chi(Register r, const Operand& opnd);
1061  void cghi(Register r, const Operand& opnd);
1062
1063  // Compare Logical Instructions
1064  void cli(const MemOperand& mem, const Operand& imm);
1065  void cliy(const MemOperand& mem, const Operand& imm);
1066  void clc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
1067
1068  // Test Under Mask Instructions
1069  void tm(const MemOperand& mem, const Operand& imm);
1070  void tmy(const MemOperand& mem, const Operand& imm);
1071
1072  // Rotate Instructions
1073  void rll(Register r1, Register r3, Register opnd);
1074  void rll(Register r1, Register r3, const Operand& opnd);
1075  void rll(Register r1, Register r3, Register r2, const Operand& opnd);
1076  void rllg(Register r1, Register r3, const Operand& opnd);
1077  void rllg(Register r1, Register r3, const Register opnd);
1078  void rllg(Register r1, Register r3, Register r2, const Operand& opnd);
1079
1080  // Shift Instructions (32)
1081  void sll(Register r1, Register opnd);
1082  void sll(Register r1, const Operand& opnd);
1083  void sllk(Register r1, Register r3, Register opnd);
1084  void sllk(Register r1, Register r3, const Operand& opnd);
1085  void srl(Register r1, Register opnd);
1086  void srl(Register r1, const Operand& opnd);
1087  void srlk(Register r1, Register r3, Register opnd);
1088  void srlk(Register r1, Register r3, const Operand& opnd);
1089  void sra(Register r1, Register opnd);
1090  void sra(Register r1, const Operand& opnd);
1091  void srak(Register r1, Register r3, Register opnd);
1092  void srak(Register r1, Register r3, const Operand& opnd);
1093  void sla(Register r1, Register opnd);
1094  void sla(Register r1, const Operand& opnd);
1095  void slak(Register r1, Register r3, Register opnd);
1096  void slak(Register r1, Register r3, const Operand& opnd);
1097
1098  // Shift Instructions (64)
1099  void sllg(Register r1, Register r3, const Operand& opnd);
1100  void sllg(Register r1, Register r3, const Register opnd);
1101  void srlg(Register r1, Register r3, const Operand& opnd);
1102  void srlg(Register r1, Register r3, const Register opnd);
1103  void srag(Register r1, Register r3, const Operand& opnd);
1104  void srag(Register r1, Register r3, const Register opnd);
1105  void srda(Register r1, const Operand& opnd);
1106  void srdl(Register r1, const Operand& opnd);
1107  void slag(Register r1, Register r3, const Operand& opnd);
1108  void slag(Register r1, Register r3, const Register opnd);
1109  void sldl(Register r1, Register b2, const Operand& opnd);
1110  void srdl(Register r1, Register b2, const Operand& opnd);
1111  void srda(Register r1, Register b2, const Operand& opnd);
1112
1113  // Rotate and Insert Selected Bits
1114  void risbg(Register dst, Register src, const Operand& startBit,
1115             const Operand& endBit, const Operand& shiftAmt,
1116             bool zeroBits = true);
1117  void risbgn(Register dst, Register src, const Operand& startBit,
1118              const Operand& endBit, const Operand& shiftAmt,
1119              bool zeroBits = true);
1120
1121  // Move Character (Mem to Mem)
1122  void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length);
1123
1124  // Branch Instructions
1125  void bras(Register r, const Operand& opnd);
1126  void brc(Condition c, const Operand& opnd);
1127  void brct(Register r1, const Operand& opnd);
1128  void brctg(Register r1, const Operand& opnd);
1129
1130  // 32-bit Add Instructions
1131  void ahi(Register r1, const Operand& opnd);
1132  void ahik(Register r1, Register r3, const Operand& opnd);
1133  void ark(Register r1, Register r2, Register r3);
1134  void asi(const MemOperand&, const Operand&);
1135
1136  // 64-bit Add Instructions
1137  void aghi(Register r1, const Operand& opnd);
1138  void aghik(Register r1, Register r3, const Operand& opnd);
1139  void agrk(Register r1, Register r2, Register r3);
1140  void agsi(const MemOperand&, const Operand&);
1141
1142  // 32-bit Add Logical Instructions
1143  void alrk(Register r1, Register r2, Register r3);
1144
1145  // 64-bit Add Logical Instructions
1146  void algrk(Register r1, Register r2, Register r3);
1147
1148  // 32-bit Subtract Instructions
1149  void srk(Register r1, Register r2, Register r3);
1150
1151  // 64-bit Subtract Instructions
1152  void sgrk(Register r1, Register r2, Register r3);
1153
1154  // 32-bit Subtract Logical Instructions
1155  void slrk(Register r1, Register r2, Register r3);
1156
1157  // 64-bit Subtract Logical Instructions
1158  void slgrk(Register r1, Register r2, Register r3);
1159
1160  // 32-bit Multiply Instructions
1161  void mhi(Register r1, const Operand& opnd);
1162  void msrkc(Register r1, Register r2, Register r3);
1163  void msgrkc(Register r1, Register r2, Register r3);
1164
1165  // 64-bit Multiply Instructions
1166  void mghi(Register r1, const Operand& opnd);
1167
1168  // Bitwise Instructions (AND / OR / XOR)
1169  void nrk(Register r1, Register r2, Register r3);
1170  void ngrk(Register r1, Register r2, Register r3);
1171  void ork(Register r1, Register r2, Register r3);
1172  void ogrk(Register r1, Register r2, Register r3);
1173  void xrk(Register r1, Register r2, Register r3);
1174  void xgrk(Register r1, Register r2, Register r3);
1175  void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
1176
1177  // Floating <-> Fixed Point Conversion Instructions
1178  void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg,
1179              Register fixReg);
1180  void cdlgbr(Condition m3, Condition m4, DoubleRegister fltReg,
1181              Register fixReg);
1182  void celgbr(Condition m3, Condition m4, DoubleRegister fltReg,
1183              Register fixReg);
1184  void celfbr(Condition m3, Condition m4, DoubleRegister fltReg,
1185              Register fixReg);
1186  void clfdbr(Condition m3, Condition m4, Register fixReg,
1187              DoubleRegister fltReg);
1188  void clfebr(Condition m3, Condition m4, Register fixReg,
1189              DoubleRegister fltReg);
1190  void clgdbr(Condition m3, Condition m4, Register fixReg,
1191              DoubleRegister fltReg);
1192  void clgebr(Condition m3, Condition m4, Register fixReg,
1193              DoubleRegister fltReg);
1194  void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg);
1195  void cgebr(Condition m, Register fixReg, DoubleRegister fltReg);
1196  void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg);
1197  void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg);
1198  void cefbr(Condition m3, DoubleRegister fltReg, Register fixReg);
1199
1200  // Floating Point Compare Instructions
1201  void cdb(DoubleRegister r1, const MemOperand& opnd);
1202  void ceb(DoubleRegister r1, const MemOperand& opnd);
1203
1204  // Floating Point Arithmetic Instructions
1205  void adb(DoubleRegister r1, const MemOperand& opnd);
1206  void sdb(DoubleRegister r1, const MemOperand& opnd);
1207  void mdb(DoubleRegister r1, const MemOperand& opnd);
1208  void ddb(DoubleRegister r1, const MemOperand& opnd);
1209  void sqdb(DoubleRegister r1, const MemOperand& opnd);
1210  void ldeb(DoubleRegister r1, const MemOperand& opnd);
1211
1212  enum FIDBRA_MASK3 {
1213    FIDBRA_CURRENT_ROUNDING_MODE = 0,
1214    FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1,
1215    // ...
1216    FIDBRA_ROUND_TOWARD_0 = 5,
1217    FIDBRA_ROUND_TOWARD_POS_INF = 6,
1218    FIDBRA_ROUND_TOWARD_NEG_INF = 7
1219  };
1220  void fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3);
1221  void fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3);
1222
1223  // Move integer
1224  void mvhi(const MemOperand& opnd1, const Operand& i2);
1225  void mvghi(const MemOperand& opnd1, const Operand& i2);
1226
1227  // Exception-generating instructions and debugging support
1228  void stop(const char* msg, Condition cond = al,
1229            int32_t code = kDefaultStopCode, CRegister cr = cr7);
1230
1231  void bkpt(uint32_t imm16);  // v5 and above
1232
1233  // Different nop operations are used by the code generator to detect certain
1234  // states of the generated code.
1235  enum NopMarkerTypes {
1236    NON_MARKING_NOP = 0,
1237    GROUP_ENDING_NOP,
1238    DEBUG_BREAK_NOP,
1239    // IC markers.
1240    PROPERTY_ACCESS_INLINED,
1241    PROPERTY_ACCESS_INLINED_CONTEXT,
1242    PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1243    // Helper values.
1244    LAST_CODE_MARKER,
1245    FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1246  };
1247
1248  void nop(int type = 0);  // 0 is the default non-marking type.
1249
1250  void dumy(int r1, int x2, int b2, int d2);
1251
1252  // Check the code size generated from label to here.
1253  int SizeOfCodeGeneratedSince(Label* label) {
1254    return pc_offset() - label->pos();
1255  }
1256
1257  // Debugging
1258
1259  // Mark address of a debug break slot.
1260  void RecordDebugBreakSlot(RelocInfo::Mode mode);
1261
1262  // Record the AST id of the CallIC being compiled, so that it can be placed
1263  // in the relocation information.
1264  void SetRecordedAstId(TypeFeedbackId ast_id) { recorded_ast_id_ = ast_id; }
1265
1266  TypeFeedbackId RecordedAstId() {
1267    // roohack - another issue??? DCHECK(!recorded_ast_id_.IsNone());
1268    return recorded_ast_id_;
1269  }
1270
1271  void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
1272
1273  // Record a comment relocation entry that can be used by a disassembler.
1274  // Use --code-comments to enable.
1275  void RecordComment(const char* msg);
1276
1277  // Record a deoptimization reason that can be used by a log or cpu profiler.
1278  // Use --trace-deopt to enable.
1279  void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1280                         int id);
1281
1282  // Writes a single byte or word of data in the code stream.  Used
1283  // for inline tables, e.g., jump-tables.
1284  void db(uint8_t data);
1285  void dd(uint32_t data);
1286  void dq(uint64_t data);
1287  void dp(uintptr_t data);
1288
1289  void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1290                                          ConstantPoolEntry::Access access,
1291                                          ConstantPoolEntry::Type type) {
1292    // No embedded constant pool support.
1293    UNREACHABLE();
1294  }
1295
1296  // Read/patch instructions
1297  SixByteInstr instr_at(int pos) {
1298    return Instruction::InstructionBits(buffer_ + pos);
1299  }
1300  template <typename T>
1301  void instr_at_put(int pos, T instr) {
1302    Instruction::SetInstructionBits<T>(buffer_ + pos, instr);
1303  }
1304
1305  // Decodes instruction at pos, and returns its length
1306  int32_t instr_length_at(int pos) {
1307    return Instruction::InstructionLength(buffer_ + pos);
1308  }
1309
1310  static SixByteInstr instr_at(byte* pc) {
1311    return Instruction::InstructionBits(pc);
1312  }
1313
1314  static Condition GetCondition(Instr instr);
1315
1316  static bool IsBranch(Instr instr);
1317#if V8_TARGET_ARCH_S390X
1318  static bool Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2);
1319#else
1320  static bool Is32BitLoadIntoIP(SixByteInstr instr);
1321#endif
1322
1323  static bool IsCmpRegister(Instr instr);
1324  static bool IsCmpImmediate(Instr instr);
1325  static bool IsNop(SixByteInstr instr, int type = NON_MARKING_NOP);
1326
1327  // The code currently calls CheckBuffer() too often. This has the side
1328  // effect of randomly growing the buffer in the middle of multi-instruction
1329  // sequences.
1330  //
1331  // This function allows outside callers to check and grow the buffer
1332  void EnsureSpaceFor(int space_needed);
1333
1334  void EmitRelocations();
1335  void emit_label_addr(Label* label);
1336
1337 public:
1338  byte* buffer_pos() const { return buffer_; }
1339
1340 protected:
1341  // Relocation for a type-recording IC has the AST id added to it.  This
1342  // member variable is a way to pass the information from the call site to
1343  // the relocation info.
1344  TypeFeedbackId recorded_ast_id_;
1345
1346  int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1347
1348  // Decode instruction(s) at pos and return backchain to previous
1349  // label reference or kEndOfChain.
1350  int target_at(int pos);
1351
1352  // Patch instruction(s) at pos to target target_pos (e.g. branch)
1353  void target_at_put(int pos, int target_pos, bool* is_branch = nullptr);
1354
1355  // Record reloc info for current pc_
1356  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1357
1358 private:
1359  // Code generation
1360  // The relocation writer's position is at least kGap bytes below the end of
1361  // the generated instructions. This is so that multi-instruction sequences do
1362  // not have to check for overflow. The same is true for writes of large
1363  // relocation info entries.
1364  static const int kGap = 32;
1365
1366  // Relocation info generation
1367  // Each relocation is encoded as a variable size value
1368  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1369  RelocInfoWriter reloc_info_writer;
1370  std::vector<DeferredRelocInfo> relocations_;
1371
1372  // The bound position, before this we cannot do instruction elimination.
1373  int last_bound_pos_;
1374
1375  // Code emission
1376  inline void CheckBuffer();
1377  void GrowBuffer(int needed = 0);
1378  inline void TrackBranch();
1379  inline void UntrackBranch();
1380
1381  inline int32_t emit_code_target(
1382      Handle<Code> target, RelocInfo::Mode rmode,
1383      TypeFeedbackId ast_id = TypeFeedbackId::None());
1384
1385  // Helpers to emit binary encoding of 2/4/6 byte instructions.
1386  inline void emit2bytes(uint16_t x);
1387  inline void emit4bytes(uint32_t x);
1388  inline void emit6bytes(uint64_t x);
1389
1390  // Helpers to emit binary encoding for various instruction formats.
1391
1392  inline void rr2_form(uint8_t op, Condition m1, Register r2);
1393
1394  inline void ri_form(Opcode op, Register r1, const Operand& i2);
1395  inline void ri_form(Opcode op, Condition m1, const Operand& i2);
1396
1397  inline void rie_form(Opcode op, Register r1, Register r3, const Operand& i2);
1398  inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3,
1399                         const Operand& i4, const Operand& i5);
1400
1401  inline void ris_form(Opcode op, Register r1, Condition m3, Register b4,
1402                       Disp d4, const Operand& i2);
1403
1404  inline void rrf1_form(Opcode op, Register r1, Register r2, Register r3);
1405  inline void rrf1_form(uint32_t x);
1406  inline void rrf2_form(uint32_t x);
1407  inline void rrf3_form(uint32_t x);
1408  inline void rrfe_form(Opcode op, Condition m3, Condition m4, Register r1,
1409                        Register r2);
1410
1411  inline void rrs_form(Opcode op, Register r1, Register r2, Register b4,
1412                       Disp d4, Condition m3);
1413
1414  inline void rs_form(Opcode op, Register r1, Condition m3, Register b2,
1415                      const Disp d2);
1416  inline void rs_form(Opcode op, Register r1, Register r3, Register b2,
1417                      const Disp d2);
1418
1419  inline void rsi_form(Opcode op, Register r1, Register r3, const Operand& i2);
1420  inline void rsl_form(Opcode op, Length l1, Register b2, Disp d2);
1421
1422  inline void rsy_form(Opcode op, Register r1, Register r3, Register b2,
1423                       const Disp d2);
1424  inline void rsy_form(Opcode op, Register r1, Condition m3, Register b2,
1425                       const Disp d2);
1426
1427  inline void rxe_form(Opcode op, Register r1, Register x2, Register b2,
1428                       Disp d2);
1429
1430  inline void rxf_form(Opcode op, Register r1, Register r3, Register b2,
1431                       Register x2, Disp d2);
1432
1433  inline void s_form(Opcode op, Register b1, Disp d2);
1434
1435  inline void si_form(Opcode op, const Operand& i2, Register b1, Disp d1);
1436  inline void siy_form(Opcode op, const Operand& i2, Register b1, Disp d1);
1437
1438  inline void sil_form(Opcode op, Register b1, Disp d1, const Operand& i2);
1439
1440  inline void ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2,
1441                      Disp d2);
1442  inline void ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1,
1443                      Register b2, Disp d2);
1444  inline void ss_form(Opcode op, Length l1, const Operand& i3, Register b1,
1445                      Disp d1, Register b2, Disp d2);
1446  inline void ss_form(Opcode op, Register r1, Register r2, Register b1, Disp d1,
1447                      Register b2, Disp d2);
1448  inline void sse_form(Opcode op, Register b1, Disp d1, Register b2, Disp d2);
1449  inline void ssf_form(Opcode op, Register r3, Register b1, Disp d1,
1450                       Register b2, Disp d2);
1451
1452  // Labels
1453  void print(Label* L);
1454  int max_reach_from(int pos);
1455  void bind_to(Label* L, int pos);
1456  void next(Label* L);
1457
1458  friend class RegExpMacroAssemblerS390;
1459  friend class RelocInfo;
1460  friend class CodePatcher;
1461
1462  List<Handle<Code> > code_targets_;
1463  friend class EnsureSpace;
1464};
1465
1466class EnsureSpace BASE_EMBEDDED {
1467 public:
1468  explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1469};
1470
1471}  // namespace internal
1472}  // namespace v8
1473
1474#endif  // V8_S390_ASSEMBLER_S390_H_
1475