• 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 // 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 
77 namespace v8 {
78 namespace 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 
122 struct 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 
from_codeRegister142   static Register from_code(int code) {
143     DCHECK(code >= 0);
144     DCHECK(code < kNumRegisters);
145     Register r = {code};
146     return r;
147   }
148 
is_validRegister149   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
isRegister150   bool is(Register reg) const { return reg_code == reg.reg_code; }
codeRegister151   int code() const {
152     DCHECK(is_valid());
153     return reg_code;
154   }
bitRegister155   int bit() const {
156     DCHECK(is_valid());
157     return 1 << reg_code;
158   }
159 
set_codeRegister160   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 
177 typedef struct Register Register;
178 
179 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
180 GENERAL_REGISTERS(DECLARE_REGISTER)
181 #undef DECLARE_REGISTER
182 const Register no_reg = {Register::kCode_no_reg};
183 
184 // Register aliases
185 const Register kLithiumScratch = r1;  // lithium scratch.
186 const Register kRootRegister = r10;   // Roots array pointer.
187 const Register cp = r13;              // JavaScript context pointer.
188 
189 static const bool kSimpleFPAliasing = true;
190 static const bool kSimdMaskRegisters = false;
191 
192 // Double word FP register.
193 struct 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 
is_validDoubleRegister205   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
isDoubleRegister206   bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
207 
codeDoubleRegister208   int code() const {
209     DCHECK(is_valid());
210     return reg_code;
211   }
212 
bitDoubleRegister213   int bit() const {
214     DCHECK(is_valid());
215     return 1 << reg_code;
216   }
217 
from_codeDoubleRegister218   static DoubleRegister from_code(int code) {
219     DoubleRegister r = {code};
220     return r;
221   }
222 
223   int reg_code;
224 };
225 
226 typedef DoubleRegister FloatRegister;
227 
228 // TODO(john.yan) Define SIMD registers.
229 typedef DoubleRegister Simd128Register;
230 
231 #define DECLARE_REGISTER(R) \
232   const DoubleRegister R = {DoubleRegister::kCode_##R};
233 DOUBLE_REGISTERS(DECLARE_REGISTER)
234 #undef DECLARE_REGISTER
235 const 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 
243 Register ToRegister(int num);
244 
245 // Coprocessor register
246 struct CRegister {
is_validCRegister247   bool is_valid() const { return 0 <= reg_code && reg_code < 8; }
isCRegister248   bool is(CRegister creg) const { return reg_code == creg.reg_code; }
codeCRegister249   int code() const {
250     DCHECK(is_valid());
251     return reg_code;
252   }
bitCRegister253   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 
262 const CRegister no_creg = {-1};
263 
264 const CRegister cr0 = {0};
265 const CRegister cr1 = {1};
266 const CRegister cr2 = {2};
267 const CRegister cr3 = {3};
268 const CRegister cr4 = {4};
269 const CRegister cr5 = {5};
270 const CRegister cr6 = {6};
271 const CRegister cr7 = {7};
272 
273 // -----------------------------------------------------------------------------
274 // Machine instruction Operands
275 
276 #if V8_TARGET_ARCH_S390X
277 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64;
278 #else
279 const 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
284 typedef uint8_t Length;
285 
286 struct Mask {
287   uint8_t mask;
valueMask288   uint8_t value() { return mask; }
from_valueMask289   static Mask from_value(uint8_t input) {
290     DCHECK(input <= 0x0F);
291     Mask m = {input};
292     return m;
293   }
294 };
295 
296 class Operand BASE_EMBEDDED {
297  public:
298   // immediate
299   INLINE(explicit Operand(intptr_t immediate,
300                           RelocInfo::Mode rmode = kRelocInfo_NONEPTR));
INLINE(static Operand Zero ())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 
immediate()314   inline intptr_t immediate() const {
315     DCHECK(!rm_.is_valid());
316     return imm_;
317   }
318 
setBits(int n)319   inline void setBits(int n) {
320     imm_ = (static_cast<uint32_t>(imm_) << (32 - n)) >> (32 - n);
321   }
322 
rm()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 
334 typedef 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
341 class MemOperand BASE_EMBEDDED {
342  public:
343   explicit MemOperand(Register rx, Disp offset = 0);
344   explicit MemOperand(Register rx, Register rb, Disp offset = 0);
345 
offset()346   int32_t offset() const { return offset_; }
getDisplacement()347   uint32_t getDisplacement() const { return offset(); }
348 
349   // Base register
rb()350   Register rb() const {
351     DCHECK(!baseRegister.is(no_reg));
352     return baseRegister;
353   }
354 
getBaseRegister()355   Register getBaseRegister() const { return rb(); }
356 
357   // Index Register
rx()358   Register rx() const {
359     DCHECK(!indexRegister.is(no_reg));
360     return indexRegister;
361   }
getIndexRegister()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 
372 class DeferredRelocInfo {
373  public:
DeferredRelocInfo()374   DeferredRelocInfo() {}
DeferredRelocInfo(int position,RelocInfo::Mode rmode,intptr_t data)375   DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data)
376       : position_(position), rmode_(rmode), data_(data) {}
377 
position()378   int position() const { return position_; }
rmode()379   RelocInfo::Mode rmode() const { return rmode_; }
data()380   intptr_t data() const { return data_; }
381 
382  private:
383   int position_;
384   RelocInfo::Mode rmode_;
385   intptr_t data_;
386 };
387 
388 class 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);
~Assembler()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
branch_offset(Label * L)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 
encode_crbit(const CRegister & cr,enum CRBit crbit)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>
getfield(T value)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
e_format(Opcode opcode)553   inline void e_format(Opcode opcode) {
554     emit2bytes(getfield<uint16_t, 2, 0, 16>(opcode));
555   }
556 
i_format(Opcode opcode,int f1)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 
ie_format(Opcode opcode,int f1,int f2)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   }
mii_format(Opcode opcode,int f1,int f2,int f3)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 
ri_format(Opcode opcode,int f1,int f2)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 
rie_1_format(Opcode opcode,int f1,int f2,int f3,int f4)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 
rie_2_format(Opcode opcode,int f1,int f2,int f3,int f4)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 
rie_3_format(Opcode opcode,int f1,int f2,int f3,int f4,int f5)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 
ril_format(Opcode opcode,int f1,int f2)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)
S390_RIL_B_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 
rr_format(Opcode opcode,int f1,int f2)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   }
S390_RR_OPCODE_LIST(DECLARE_S390_RR_INSTRUCTIONS)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   }
S390_RRD_OPCODE_LIST(DECLARE_S390_RRD_INSTRUCTIONS)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   }
S390_RRE_OPCODE_LIST(DECLARE_S390_RRE_INSTRUCTIONS)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 
rrf_format(Opcode opcode,int f1,int f2,int f3,int f4)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 
rx_format(Opcode opcode,int f1,int f2,int f3,int f4)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   }
S390_RX_A_OPCODE_LIST(DECLARE_S390_RX_INSTRUCTIONS)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   }
bc(Condition cond,Register x2,Register b2,Disp d2)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 
rxy_format(Opcode opcode,int f1,int f2,int f3,int f4)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   }
S390_RXY_A_OPCODE_LIST(DECLARE_S390_RXY_INSTRUCTIONS)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   }
pfd(Condition cond,Register x2,Register b2,Disp d2)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
b(Register r,Label * l)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
b(Condition cond,Register r)798   void b(Condition cond, Register r) { bcr(cond, r); }
beq(Register r)799   void beq(Register r) { b(eq, r); }
bne(Register r)800   void bne(Register r) { b(ne, r); }
blt(Register r)801   void blt(Register r) { b(lt, r); }
ble(Register r)802   void ble(Register r) { b(le, r); }
bgt(Register r)803   void bgt(Register r) { b(gt, r); }
bge(Register r)804   void bge(Register r) { b(ge, r); }
b(Register r)805   void b(Register r) { b(al, r); }
jmp(Register r)806   void jmp(Register r) { b(al, r); }
bunordered(Register r)807   void bunordered(Register r) { b(unordered, r); }
bordered(Register 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 
breakpoint(bool do_print)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   }
S390_VRR_C_OPCODE_LIST(DECLARE_VRR_C_INSTRUCTIONS)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   }
vfs(DoubleRegister v1,DoubleRegister v2,DoubleRegister v3)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   }
vfm(DoubleRegister v1,DoubleRegister v2,DoubleRegister v3)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   }
vfd(DoubleRegister v1,DoubleRegister v2,DoubleRegister v3)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.
SizeOfCodeGeneratedSince(Label * label)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.
SetRecordedAstId(TypeFeedbackId ast_id)1264   void SetRecordedAstId(TypeFeedbackId ast_id) { recorded_ast_id_ = ast_id; }
1265 
RecordedAstId()1266   TypeFeedbackId RecordedAstId() {
1267     // roohack - another issue??? DCHECK(!recorded_ast_id_.IsNone());
1268     return recorded_ast_id_;
1269   }
1270 
ClearRecordedAstId()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 
PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)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
instr_at(int pos)1297   SixByteInstr instr_at(int pos) {
1298     return Instruction::InstructionBits(buffer_ + pos);
1299   }
1300   template <typename T>
instr_at_put(int pos,T instr)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
instr_length_at(int pos)1306   int32_t instr_length_at(int pos) {
1307     return Instruction::InstructionLength(buffer_ + pos);
1308   }
1309 
instr_at(byte * pc)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:
buffer_pos()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 
buffer_space()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 
1466 class EnsureSpace BASE_EMBEDDED {
1467  public:
EnsureSpace(Assembler * assembler)1468   explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1469 };
1470 
1471 }  // namespace internal
1472 }  // namespace v8
1473 
1474 #endif  // V8_S390_ASSEMBLER_S390_H_
1475