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 
191 // Double word FP register.
192 struct DoubleRegister {
193   enum Code {
194 #define REGISTER_CODE(R) kCode_##R,
195     DOUBLE_REGISTERS(REGISTER_CODE)
196 #undef REGISTER_CODE
197         kAfterLast,
198     kCode_no_reg = -1
199   };
200 
201   static const int kNumRegisters = Code::kAfterLast;
202   static const int kMaxNumRegisters = kNumRegisters;
203 
is_validDoubleRegister204   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
isDoubleRegister205   bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
206 
codeDoubleRegister207   int code() const {
208     DCHECK(is_valid());
209     return reg_code;
210   }
211 
bitDoubleRegister212   int bit() const {
213     DCHECK(is_valid());
214     return 1 << reg_code;
215   }
216 
from_codeDoubleRegister217   static DoubleRegister from_code(int code) {
218     DoubleRegister r = {code};
219     return r;
220   }
221 
222   int reg_code;
223 };
224 
225 typedef DoubleRegister FloatRegister;
226 
227 // TODO(john.yan) Define SIMD registers.
228 typedef DoubleRegister Simd128Register;
229 
230 #define DECLARE_REGISTER(R) \
231   const DoubleRegister R = {DoubleRegister::kCode_##R};
232 DOUBLE_REGISTERS(DECLARE_REGISTER)
233 #undef DECLARE_REGISTER
234 const Register no_dreg = {Register::kCode_no_reg};
235 
236 // Aliases for double registers.  Defined using #define instead of
237 // "static const DoubleRegister&" because Clang complains otherwise when a
238 // compilation unit that includes this header doesn't use the variables.
239 #define kDoubleRegZero d14
240 #define kScratchDoubleReg d13
241 
242 Register ToRegister(int num);
243 
244 // Coprocessor register
245 struct CRegister {
is_validCRegister246   bool is_valid() const { return 0 <= reg_code && reg_code < 8; }
isCRegister247   bool is(CRegister creg) const { return reg_code == creg.reg_code; }
codeCRegister248   int code() const {
249     DCHECK(is_valid());
250     return reg_code;
251   }
bitCRegister252   int bit() const {
253     DCHECK(is_valid());
254     return 1 << reg_code;
255   }
256 
257   // Unfortunately we can't make this private in a struct.
258   int reg_code;
259 };
260 
261 const CRegister no_creg = {-1};
262 
263 const CRegister cr0 = {0};
264 const CRegister cr1 = {1};
265 const CRegister cr2 = {2};
266 const CRegister cr3 = {3};
267 const CRegister cr4 = {4};
268 const CRegister cr5 = {5};
269 const CRegister cr6 = {6};
270 const CRegister cr7 = {7};
271 
272 // -----------------------------------------------------------------------------
273 // Machine instruction Operands
274 
275 #if V8_TARGET_ARCH_S390X
276 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64;
277 #else
278 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32;
279 #endif
280 
281 // Class Operand represents a shifter operand in data processing instructions
282 // defining immediate numbers and masks
283 typedef uint8_t Length;
284 
285 struct Mask {
286   uint8_t mask;
valueMask287   uint8_t value() { return mask; }
from_valueMask288   static Mask from_value(uint8_t input) {
289     DCHECK(input <= 0x0F);
290     Mask m = {input};
291     return m;
292   }
293 };
294 
295 class Operand BASE_EMBEDDED {
296  public:
297   // immediate
298   INLINE(explicit Operand(intptr_t immediate,
299                           RelocInfo::Mode rmode = kRelocInfo_NONEPTR));
INLINE(static Operand Zero ())300   INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); }
301   INLINE(explicit Operand(const ExternalReference& f));
302   explicit Operand(Handle<Object> handle);
303   INLINE(explicit Operand(Smi* value));
304 
305   // rm
306   INLINE(explicit Operand(Register rm));
307 
308   // Return true if this is a register operand.
309   INLINE(bool is_reg() const);
310 
311   bool must_output_reloc_info(const Assembler* assembler) const;
312 
immediate()313   inline intptr_t immediate() const {
314     DCHECK(!rm_.is_valid());
315     return imm_;
316   }
317 
setBits(int n)318   inline void setBits(int n) {
319     imm_ = (static_cast<uint32_t>(imm_) << (32 - n)) >> (32 - n);
320   }
321 
rm()322   Register rm() const { return rm_; }
323 
324  private:
325   Register rm_;
326   intptr_t imm_;  // valid if rm_ == no_reg
327   RelocInfo::Mode rmode_;
328 
329   friend class Assembler;
330   friend class MacroAssembler;
331 };
332 
333 typedef int32_t Disp;
334 
335 // Class MemOperand represents a memory operand in load and store instructions
336 // On S390, we have various flavours of memory operands:
337 //   1) a base register + 16 bit unsigned displacement
338 //   2) a base register + index register + 16 bit unsigned displacement
339 //   3) a base register + index register + 20 bit signed displacement
340 class MemOperand BASE_EMBEDDED {
341  public:
342   explicit MemOperand(Register rx, Disp offset = 0);
343   explicit MemOperand(Register rx, Register rb, Disp offset = 0);
344 
offset()345   int32_t offset() const { return offset_; }
getDisplacement()346   uint32_t getDisplacement() const { return offset(); }
347 
348   // Base register
rb()349   Register rb() const {
350     DCHECK(!baseRegister.is(no_reg));
351     return baseRegister;
352   }
353 
getBaseRegister()354   Register getBaseRegister() const { return rb(); }
355 
356   // Index Register
rx()357   Register rx() const {
358     DCHECK(!indexRegister.is(no_reg));
359     return indexRegister;
360   }
getIndexRegister()361   Register getIndexRegister() const { return rx(); }
362 
363  private:
364   Register baseRegister;   // base
365   Register indexRegister;  // index
366   int32_t offset_;         // offset
367 
368   friend class Assembler;
369 };
370 
371 class DeferredRelocInfo {
372  public:
DeferredRelocInfo()373   DeferredRelocInfo() {}
DeferredRelocInfo(int position,RelocInfo::Mode rmode,intptr_t data)374   DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data)
375       : position_(position), rmode_(rmode), data_(data) {}
376 
position()377   int position() const { return position_; }
rmode()378   RelocInfo::Mode rmode() const { return rmode_; }
data()379   intptr_t data() const { return data_; }
380 
381  private:
382   int position_;
383   RelocInfo::Mode rmode_;
384   intptr_t data_;
385 };
386 
387 class Assembler : public AssemblerBase {
388  public:
389   // Create an assembler. Instructions and relocation information are emitted
390   // into a buffer, with the instructions starting from the beginning and the
391   // relocation information starting from the end of the buffer. See CodeDesc
392   // for a detailed comment on the layout (globals.h).
393   //
394   // If the provided buffer is NULL, the assembler allocates and grows its own
395   // buffer, and buffer_size determines the initial buffer size. The buffer is
396   // owned by the assembler and deallocated upon destruction of the assembler.
397   //
398   // If the provided buffer is not NULL, the assembler uses the provided buffer
399   // for code generation and assumes its size to be buffer_size. If the buffer
400   // is too small, a fatal error occurs. No deallocation of the buffer is done
401   // upon destruction of the assembler.
402   Assembler(Isolate* isolate, void* buffer, int buffer_size);
~Assembler()403   virtual ~Assembler() {}
404 
405   // GetCode emits any pending (non-emitted) code and fills the descriptor
406   // desc. GetCode() is idempotent; it returns the same result if no other
407   // Assembler functions are invoked in between GetCode() calls.
408   void GetCode(CodeDesc* desc);
409 
410   // Label operations & relative jumps (PPUM Appendix D)
411   //
412   // Takes a branch opcode (cc) and a label (L) and generates
413   // either a backward branch or a forward branch and links it
414   // to the label fixup chain. Usage:
415   //
416   // Label L;    // unbound label
417   // j(cc, &L);  // forward branch to unbound label
418   // bind(&L);   // bind label to the current pc
419   // j(cc, &L);  // backward branch to bound label
420   // bind(&L);   // illegal: a label may be bound only once
421   //
422   // Note: The same Label can be used for forward and backward branches
423   // but it may be bound only once.
424 
425   void bind(Label* L);  // binds an unbound label L to the current code position
426 
427   // Links a label at the current pc_offset().  If already bound, returns the
428   // bound position.  If already linked, returns the position of the prior link.
429   // Otherwise, returns the current pc_offset().
430   int link(Label* L);
431 
432   // Determines if Label is bound and near enough so that a single
433   // branch instruction can be used to reach it.
434   bool is_near(Label* L, Condition cond);
435 
436   // Returns the branch offset to the given label from the current code position
437   // Links the label to the current position if it is still unbound
branch_offset(Label * L)438   int branch_offset(Label* L) { return link(L) - pc_offset(); }
439 
440   // Puts a labels target address at the given position.
441   // The high 8 bits are set to zero.
442   void label_at_put(Label* L, int at_offset);
443   void load_label_offset(Register r1, Label* L);
444 
445   // Read/Modify the code target address in the branch/call instruction at pc.
446   INLINE(static Address target_address_at(Address pc, Address constant_pool));
447   INLINE(static void set_target_address_at(
448       Isolate* isolate, Address pc, Address constant_pool, Address target,
449       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
INLINE(static Address target_address_at (Address pc,Code * code))450   INLINE(static Address target_address_at(Address pc, Code* code)) {
451     Address constant_pool = NULL;
452     return target_address_at(pc, constant_pool);
453   }
INLINE(static void set_target_address_at (Isolate * isolate,Address pc,Code * code,Address target,ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED))454   INLINE(static void set_target_address_at(
455       Isolate* isolate, Address pc, Code* code, Address target,
456       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
457     Address constant_pool = NULL;
458     set_target_address_at(isolate, pc, constant_pool, target,
459                           icache_flush_mode);
460   }
461 
462   // Return the code target address at a call site from the return address
463   // of that call in the instruction stream.
464   inline static Address target_address_from_return_address(Address pc);
465 
466   // Given the address of the beginning of a call, return the address
467   // in the instruction stream that the call will return to.
468   INLINE(static Address return_address_from_call_start(Address pc));
469 
470   inline Handle<Object> code_target_object_handle_at(Address pc);
471   // This sets the branch destination.
472   // This is for calls and branches within generated code.
473   inline static void deserialization_set_special_target_at(
474       Isolate* isolate, Address instruction_payload, Code* code,
475       Address target);
476 
477   // This sets the internal reference at the pc.
478   inline static void deserialization_set_target_internal_reference_at(
479       Isolate* isolate, Address pc, Address target,
480       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
481 
482   // Here we are patching the address in the IIHF/IILF instruction pair.
483   // These values are used in the serialization process and must be zero for
484   // S390 platform, as Code, Embedded Object or External-reference pointers
485   // are split across two consecutive instructions and don't exist separately
486   // in the code, so the serializer should not step forwards in memory after
487   // a target is resolved and written.
488   static const int kSpecialTargetSize = 0;
489 
490 // Number of bytes for instructions used to store pointer sized constant.
491 #if V8_TARGET_ARCH_S390X
492   static const int kBytesForPtrConstant = 12;  // IIHF + IILF
493 #else
494   static const int kBytesForPtrConstant = 6;  // IILF
495 #endif
496 
497   // Distance between the instruction referring to the address of the call
498   // target and the return address.
499 
500   // Offset between call target address and return address
501   // for BRASL calls
502   // Patch will be appiled to other FIXED_SEQUENCE call
503   static const int kCallTargetAddressOffset = 6;
504 
505 // The length of FIXED_SEQUENCE call
506 // iihf    r8, <address_hi>  // <64-bit only>
507 // iilf    r8, <address_lo>
508 // basr    r14, r8
509 #if V8_TARGET_ARCH_S390X
510   static const int kCallSequenceLength = 14;
511 #else
512   static const int kCallSequenceLength = 8;
513 #endif
514 
515   // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn()
516   // code patch FIXED_SEQUENCE in bytes!
517   // JS Return Sequence = Call Sequence + BKPT
518   // static const int kJSReturnSequenceLength = kCallSequenceLength + 2;
519 
520   // This is the length of the code sequence from SetDebugBreakAtSlot()
521   // FIXED_SEQUENCE in bytes!
522   static const int kDebugBreakSlotLength = kCallSequenceLength;
523   static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset;
524 
525   // Length to patch between the start of the JS return sequence
526   // from SetDebugBreakAtReturn and the address from
527   // break_address_from_return_address.
528   //
529   // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in
530   // JS return sequence, so the length to patch will not include BKPT
531   // instruction length.
532   // static const int kPatchReturnSequenceAddressOffset =
533   //     kCallSequenceLength - kPatchDebugBreakSlotReturnOffset;
534 
535   // Length to patch between the start of the FIXED call sequence from
536   // SetDebugBreakAtSlot() and the the address from
537   // break_address_from_return_address.
538   static const int kPatchDebugBreakSlotAddressOffset =
539       kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset;
540 
encode_crbit(const CRegister & cr,enum CRBit crbit)541   static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
542     return ((cr.code() * CRWIDTH) + crbit);
543   }
544 
545   // ---------------------------------------------------------------------------
546   // Code generation
547 
548   // Helper for unconditional branch to Label with update to save register
b(Register r,Label * l)549   void b(Register r, Label* l) {
550     int32_t halfwords = branch_offset(l) / 2;
551     brasl(r, Operand(halfwords));
552   }
553 
554   // Conditional Branch Instruction - Generates either BRC / BRCL
555   void branchOnCond(Condition c, int branch_offset, bool is_bound = false);
556 
557   // Helpers for conditional branch to Label
558   void b(Condition cond, Label* l, Label::Distance dist = Label::kFar) {
559     branchOnCond(cond, branch_offset(l),
560                  l->is_bound() || (dist == Label::kNear));
561   }
562 
563   void bc_short(Condition cond, Label* l, Label::Distance dist = Label::kFar) {
564     b(cond, l, Label::kNear);
565   }
566   // Helpers for conditional branch to Label
567   void beq(Label* l, Label::Distance dist = Label::kFar) { b(eq, l, dist); }
568   void bne(Label* l, Label::Distance dist = Label::kFar) { b(ne, l, dist); }
569   void blt(Label* l, Label::Distance dist = Label::kFar) { b(lt, l, dist); }
570   void ble(Label* l, Label::Distance dist = Label::kFar) { b(le, l, dist); }
571   void bgt(Label* l, Label::Distance dist = Label::kFar) { b(gt, l, dist); }
572   void bge(Label* l, Label::Distance dist = Label::kFar) { b(ge, l, dist); }
573   void b(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); }
574   void jmp(Label* l, Label::Distance dist = Label::kFar) { b(al, l, dist); }
575   void bunordered(Label* l, Label::Distance dist = Label::kFar) {
576     b(unordered, l, dist);
577   }
578   void bordered(Label* l, Label::Distance dist = Label::kFar) {
579     b(ordered, l, dist);
580   }
581 
582   // Helpers for conditional indirect branch off register
b(Condition cond,Register r)583   void b(Condition cond, Register r) { bcr(cond, r); }
beq(Register r)584   void beq(Register r) { b(eq, r); }
bne(Register r)585   void bne(Register r) { b(ne, r); }
blt(Register r)586   void blt(Register r) { b(lt, r); }
ble(Register r)587   void ble(Register r) { b(le, r); }
bgt(Register r)588   void bgt(Register r) { b(gt, r); }
bge(Register r)589   void bge(Register r) { b(ge, r); }
b(Register r)590   void b(Register r) { b(al, r); }
jmp(Register r)591   void jmp(Register r) { b(al, r); }
bunordered(Register r)592   void bunordered(Register r) { b(unordered, r); }
bordered(Register r)593   void bordered(Register r) { b(ordered, r); }
594 
595   // ---------------------------------------------------------------------------
596   // Code generation
597 
598   // Insert the smallest number of nop instructions
599   // possible to align the pc offset to a multiple
600   // of m. m must be a power of 2 (>= 4).
601   void Align(int m);
602   // Insert the smallest number of zero bytes possible to align the pc offset
603   // to a mulitple of m. m must be a power of 2 (>= 2).
604   void DataAlign(int m);
605   // Aligns code to something that's optimal for a jump target for the platform.
606   void CodeTargetAlign();
607 
breakpoint(bool do_print)608   void breakpoint(bool do_print) {
609     if (do_print) {
610       PrintF("DebugBreak is inserted to %p\n", static_cast<void*>(pc_));
611     }
612 #if V8_HOST_ARCH_64_BIT
613     int64_t value = reinterpret_cast<uint64_t>(&v8::base::OS::DebugBreak);
614     int32_t hi_32 = static_cast<int64_t>(value) >> 32;
615     int32_t lo_32 = static_cast<int32_t>(value);
616 
617     iihf(r1, Operand(hi_32));
618     iilf(r1, Operand(lo_32));
619 #else
620     iilf(r1, Operand(reinterpret_cast<uint32_t>(&v8::base::OS::DebugBreak)));
621 #endif
622     basr(r14, r1);
623   }
624 
625   void call(Handle<Code> target, RelocInfo::Mode rmode,
626             TypeFeedbackId ast_id = TypeFeedbackId::None());
627   void jump(Handle<Code> target, RelocInfo::Mode rmode, Condition cond);
628 
629 // S390 instruction generation
630 #define I_FORM(name) void name(const Operand& i)
631 
632 #define RR_FORM(name) void name(Register r1, Register r2)
633 
634 #define RR2_FORM(name) void name(Condition m1, Register r2)
635 
636 #define RX_FORM(name)                                        \
637   void name(Register r1, Register x2, Register b2, Disp d2); \
638   void name(Register r1, const MemOperand& opnd)
639 
640 #define RI1_FORM(name) void name(Register r, const Operand& i)
641 
642 #define RI2_FORM(name) void name(Condition m, const Operand& i)
643 
644 #define RIE_FORM(name) void name(Register r1, Register R3, const Operand& i)
645 
646 #define RIE_F_FORM(name)                                                    \
647   void name(Register r1, Register r2, const Operand& i3, const Operand& i4, \
648             const Operand& i5)
649 
650 #define RIL1_FORM(name) void name(Register r1, const Operand& i2)
651 
652 #define RIL2_FORM(name) void name(Condition m1, const Operand& i2)
653 
654 #define RXE_FORM(name)                            \
655   void name(Register r1, const MemOperand& opnd); \
656   void name(Register r1, Register b2, Register x2, Disp d2)
657 
658 #define RXF_FORM(name)                                         \
659   void name(Register r1, Register r3, const MemOperand& opnd); \
660   void name(Register r1, Register r3, Register b2, Register x2, Disp d2)
661 
662 #define RXY_FORM(name)                                       \
663   void name(Register r1, Register x2, Register b2, Disp d2); \
664   void name(Register r1, const MemOperand& opnd)
665 
666 #define RSI_FORM(name) void name(Register r1, Register r3, const Operand& i)
667 
668 #define RIS_FORM(name)                                       \
669   void name(Register r1, Condition m3, Register b4, Disp d4, \
670             const Operand& i2);                              \
671   void name(Register r1, const Operand& i2, Condition m3,    \
672             const MemOperand& opnd)
673 
674 #define SI_FORM(name)                                  \
675   void name(const MemOperand& opnd, const Operand& i); \
676   void name(const Operand& i2, Register b1, Disp d1)
677 
678 #define SIL_FORM(name)                                \
679   void name(Register b1, Disp d1, const Operand& i2); \
680   void name(const MemOperand& opnd, const Operand& i2)
681 
682 #define RRE_FORM(name) void name(Register r1, Register r2)
683 
684 #define RRF1_FORM(name) void name(Register r1, Register r2, Register r3)
685 
686 #define RRF2_FORM(name) void name(Condition m1, Register r1, Register r2)
687 
688 #define RRF3_FORM(name) \
689   void name(Register r3, Condition m4, Register r1, Register r2)
690 
691 #define RS1_FORM(name)                                         \
692   void name(Register r1, Register r3, const MemOperand& opnd); \
693   void name(Register r1, Register r3, Register b2, Disp d2)
694 
695 #define RS2_FORM(name)                                          \
696   void name(Register r1, Condition m3, const MemOperand& opnd); \
697   void name(Register r1, Condition m3, Register b2, Disp d2)
698 
699 #define RSE_FORM(name)                                         \
700   void name(Register r1, Register r3, const MemOperand& opnd); \
701   void name(Register r1, Register r3, Register b2, Disp d2)
702 
703 #define RSL_FORM(name)                       \
704   void name(Length l, Register b2, Disp d2); \
705   void name(const MemOperand& opnd)
706 
707 #define RSY1_FORM(name)                                      \
708   void name(Register r1, Register r3, Register b2, Disp d2); \
709   void name(Register r1, Register r3, const MemOperand& opnd)
710 
711 #define RSY2_FORM(name)                                       \
712   void name(Register r1, Condition m3, Register b2, Disp d2); \
713   void name(Register r1, Condition m3, const MemOperand& opnd)
714 
715 #define RRD_FORM(name) void name(Register r1, Register r3, Register r2)
716 
717 #define RRS_FORM(name)                                                     \
718   void name(Register r1, Register r2, Register b4, Disp d4, Condition m3); \
719   void name(Register r1, Register r2, Condition m3, const MemOperand& opnd)
720 
721 #define S_FORM(name)               \
722   void name(Register b2, Disp d2); \
723   void name(const MemOperand& opnd)
724 
725 #define SIY_FORM(name)                                \
726   void name(const Operand& i2, Register b1, Disp d1); \
727   void name(const MemOperand& opnd, const Operand& i)
728 
729 #define SS1_FORM(name)                                                  \
730   void name(Register b1, Disp d1, Register b3, Disp d2, Length length); \
731   void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length)
732 
733 #define SS2_FORM(name)                                                        \
734   void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length1, \
735             Length length2);                                                  \
736   void name(Register b1, Disp d1, Register b2, Disp d2, Length l1, Length l2)
737 
738 #define SS3_FORM(name)                                                        \
739   void name(const MemOperand& opnd1, const MemOperand& opnd2, Length length); \
740   void name(const Operand& i3, Register b1, Disp d1, Register b2, Disp d2,    \
741             Length l1)
742 
743 #define SS4_FORM(name)                                                   \
744   void name(const MemOperand& opnd1, const MemOperand& opnd2);           \
745   void name(Register r1, Register r3, Register b1, Disp d1, Register b2, \
746             Disp d2)
747 
748 #define SS5_FORM(name)                                                   \
749   void name(const MemOperand& opnd1, const MemOperand& opnd2);           \
750   void name(Register r1, Register r3, Register b3, Disp d2, Register b4, \
751             Disp d4)
752 
753 #define SSE_FORM(name)                                   \
754   void name(Register b1, Disp d1, Register b2, Disp d2); \
755   void name(const MemOperand& opnd1, const MemOperand& opnd2)
756 
757 #define SSF_FORM(name)                                                \
758   void name(Register r3, Register b1, Disp d1, Register b2, Disp d2); \
759   void name(Register r3, const MemOperand& opnd1, const MemOperand& opnd2)
760 
761   // S390 instruction sets
762   RX_FORM(bc);
763   RR_FORM(bctr);
764   RX_FORM(cd);
765   RRE_FORM(cdr);
766   RXE_FORM(cdb);
767   RXE_FORM(ceb);
768   RXE_FORM(ddb);
769   RRE_FORM(ddbr);
770   SS1_FORM(ed);
771   RRE_FORM(epair);
772   RX_FORM(ex);
773   RRF2_FORM(fidbr);
774   RRE_FORM(flogr);
775   RX_FORM(ic_z);
776   RXY_FORM(icy);
777   RIL1_FORM(iihf);
778   RI1_FORM(iihh);
779   RI1_FORM(iihl);
780   RIL1_FORM(iilf);
781   RIL1_FORM(lgfi);
782   RI1_FORM(iilh);
783   RI1_FORM(iill);
784   RRE_FORM(lcgr);
785   RR_FORM(lcr);
786   RX_FORM(le_z);
787   RXY_FORM(ley);
788   RIL1_FORM(llihf);
789   RIL1_FORM(llilf);
790   RRE_FORM(lngr);
791   RR_FORM(lnr);
792   RSY1_FORM(loc);
793   RXY_FORM(lrv);
794   RRE_FORM(lrvr);
795   RRE_FORM(lrvgr);
796   RXY_FORM(lrvh);
797   RXY_FORM(lrvg);
798   RXE_FORM(mdb);
799   RRE_FORM(mdbr);
800   SS4_FORM(mvck);
801   SSF_FORM(mvcos);
802   SS4_FORM(mvcs);
803   SS1_FORM(mvn);
804   SS1_FORM(nc);
805   SI_FORM(ni);
806   RIL1_FORM(nihf);
807   RIL1_FORM(nilf);
808   RI1_FORM(nilh);
809   RI1_FORM(nill);
810   RIL1_FORM(oihf);
811   RIL1_FORM(oilf);
812   RI1_FORM(oill);
813   RRE_FORM(popcnt);
814   RXE_FORM(sdb);
815   RRE_FORM(sdbr);
816   RIL1_FORM(slfi);
817   RXY_FORM(slgf);
818   RIL1_FORM(slgfi);
819   RS1_FORM(srdl);
820   RX_FORM(ste);
821   RXY_FORM(stey);
822   RXY_FORM(strv);
823   RXY_FORM(strvh);
824   RXY_FORM(strvg);
825   RI1_FORM(tmll);
826   SS1_FORM(tr);
827   S_FORM(ts);
828   RIL1_FORM(xihf);
829   RIL1_FORM(xilf);
830 
831   // Load Address Instructions
832   void la(Register r, const MemOperand& opnd);
833   void lay(Register r, const MemOperand& opnd);
834   void larl(Register r1, const Operand& opnd);
835   void larl(Register r, Label* l);
836 
837   // Load Instructions
838   void lb(Register r, const MemOperand& src);
839   void lbr(Register r1, Register r2);
840   void lgb(Register r, const MemOperand& src);
841   void lgbr(Register r1, Register r2);
842   void lh(Register r, const MemOperand& src);
843   void lhy(Register r, const MemOperand& src);
844   void lhr(Register r1, Register r2);
845   void lgh(Register r, const MemOperand& src);
846   void lghr(Register r1, Register r2);
847   void l(Register r, const MemOperand& src);
848   void ly(Register r, const MemOperand& src);
849   void lr(Register r1, Register r2);
850   void lg(Register r, const MemOperand& src);
851   void lgr(Register r1, Register r2);
852   void lgf(Register r, const MemOperand& src);
853   void lgfr(Register r1, Register r2);
854   void lhi(Register r, const Operand& imm);
855   void lghi(Register r, const Operand& imm);
856 
857   // Load And Test Instructions
858   void lt_z(Register r, const MemOperand& src);
859   void ltg(Register r, const MemOperand& src);
860   void ltr(Register r1, Register r2);
861   void ltgr(Register r1, Register r2);
862   void ltgfr(Register r1, Register r2);
863 
864   // Load Logical Instructions
865   void llc(Register r, const MemOperand& src);
866   void llgc(Register r, const MemOperand& src);
867   void llgf(Register r, const MemOperand& src);
868   void llgfr(Register r1, Register r2);
869   void llh(Register r, const MemOperand& src);
870   void llgh(Register r, const MemOperand& src);
871   void llhr(Register r1, Register r2);
872   void llghr(Register r1, Register r2);
873 
874   // Load Multiple Instructions
875   void lm(Register r1, Register r2, const MemOperand& src);
876   void lmy(Register r1, Register r2, const MemOperand& src);
877   void lmg(Register r1, Register r2, const MemOperand& src);
878 
879   // Load On Condition Instructions
880   void locr(Condition m3, Register r1, Register r2);
881   void locgr(Condition m3, Register r1, Register r2);
882   void loc(Condition m3, Register r1, const MemOperand& src);
883   void locg(Condition m3, Register r1, const MemOperand& src);
884 
885   // Store Instructions
886   void st(Register r, const MemOperand& src);
887   void stc(Register r, const MemOperand& src);
888   void stcy(Register r, const MemOperand& src);
889   void stg(Register r, const MemOperand& src);
890   void sth(Register r, const MemOperand& src);
891   void sthy(Register r, const MemOperand& src);
892   void sty(Register r, const MemOperand& src);
893 
894   // Store Multiple Instructions
895   void stm(Register r1, Register r2, const MemOperand& src);
896   void stmy(Register r1, Register r2, const MemOperand& src);
897   void stmg(Register r1, Register r2, const MemOperand& src);
898 
899   // Compare Instructions
900   void c(Register r, const MemOperand& opnd);
901   void cy(Register r, const MemOperand& opnd);
902   void cr_z(Register r1, Register r2);
903   void cg(Register r, const MemOperand& opnd);
904   void cgr(Register r1, Register r2);
905   void ch(Register r, const MemOperand& opnd);
906   void chy(Register r, const MemOperand& opnd);
907   void chi(Register r, const Operand& opnd);
908   void cghi(Register r, const Operand& opnd);
909   void cfi(Register r, const Operand& opnd);
910   void cgfi(Register r, const Operand& opnd);
911 
912   // Compare Logical Instructions
913   void cl(Register r, const MemOperand& opnd);
914   void cly(Register r, const MemOperand& opnd);
915   void clr(Register r1, Register r2);
916   void clg(Register r, const MemOperand& opnd);
917   void clgr(Register r1, Register r2);
918   void clfi(Register r, const Operand& opnd);
919   void clgfi(Register r, const Operand& opnd);
920   void cli(const MemOperand& mem, const Operand& imm);
921   void cliy(const MemOperand& mem, const Operand& imm);
922   void clc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
923 
924   // Test Under Mask Instructions
925   void tm(const MemOperand& mem, const Operand& imm);
926   void tmy(const MemOperand& mem, const Operand& imm);
927 
928   // Rotate Instructions
929   void rll(Register r1, Register r3, Register opnd);
930   void rll(Register r1, Register r3, const Operand& opnd);
931   void rll(Register r1, Register r3, Register r2, const Operand& opnd);
932   void rllg(Register r1, Register r3, const Operand& opnd);
933   void rllg(Register r1, Register r3, const Register opnd);
934   void rllg(Register r1, Register r3, Register r2, const Operand& opnd);
935 
936   // Shift Instructions (32)
937   void sll(Register r1, Register opnd);
938   void sll(Register r1, const Operand& opnd);
939   void sllk(Register r1, Register r3, Register opnd);
940   void sllk(Register r1, Register r3, const Operand& opnd);
941   void srl(Register r1, Register opnd);
942   void srl(Register r1, const Operand& opnd);
943   void srlk(Register r1, Register r3, Register opnd);
944   void srlk(Register r1, Register r3, const Operand& opnd);
945   void sra(Register r1, Register opnd);
946   void sra(Register r1, const Operand& opnd);
947   void srak(Register r1, Register r3, Register opnd);
948   void srak(Register r1, Register r3, const Operand& opnd);
949   void sla(Register r1, Register opnd);
950   void sla(Register r1, const Operand& opnd);
951   void slak(Register r1, Register r3, Register opnd);
952   void slak(Register r1, Register r3, const Operand& opnd);
953 
954   // Shift Instructions (64)
955   void sllg(Register r1, Register r3, const Operand& opnd);
956   void sllg(Register r1, Register r3, const Register opnd);
957   void srlg(Register r1, Register r3, const Operand& opnd);
958   void srlg(Register r1, Register r3, const Register opnd);
959   void srag(Register r1, Register r3, const Operand& opnd);
960   void srag(Register r1, Register r3, const Register opnd);
961   void srda(Register r1, const Operand& opnd);
962   void srdl(Register r1, const Operand& opnd);
963   void slag(Register r1, Register r3, const Operand& opnd);
964   void slag(Register r1, Register r3, const Register opnd);
965   void sldl(Register r1, Register b2, const Operand& opnd);
966   void srdl(Register r1, Register b2, const Operand& opnd);
967   void srda(Register r1, Register b2, const Operand& opnd);
968 
969   // Rotate and Insert Selected Bits
970   void risbg(Register dst, Register src, const Operand& startBit,
971              const Operand& endBit, const Operand& shiftAmt,
972              bool zeroBits = true);
973   void risbgn(Register dst, Register src, const Operand& startBit,
974               const Operand& endBit, const Operand& shiftAmt,
975               bool zeroBits = true);
976 
977   // Move Character (Mem to Mem)
978   void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length);
979 
980   // Branch Instructions
981   void basr(Register r1, Register r2);
982   void bcr(Condition m, Register target);
983   void bct(Register r, const MemOperand& opnd);
984   void bctg(Register r, const MemOperand& opnd);
985   void bras(Register r, const Operand& opnd);
986   void brasl(Register r, const Operand& opnd);
987   void brc(Condition c, const Operand& opnd);
988   void brcl(Condition m, const Operand& opnd, bool isCodeTarget = false);
989   void brct(Register r1, const Operand& opnd);
990   void brctg(Register r1, const Operand& opnd);
991 
992   // 32-bit Add Instructions
993   void a(Register r1, const MemOperand& opnd);
994   void ay(Register r1, const MemOperand& opnd);
995   void afi(Register r1, const Operand& opnd);
996   void ah(Register r1, const MemOperand& opnd);
997   void ahy(Register r1, const MemOperand& opnd);
998   void ahi(Register r1, const Operand& opnd);
999   void ahik(Register r1, Register r3, const Operand& opnd);
1000   void ar(Register r1, Register r2);
1001   void ark(Register r1, Register r2, Register r3);
1002   void asi(const MemOperand&, const Operand&);
1003 
1004   // 64-bit Add Instructions
1005   void ag(Register r1, const MemOperand& opnd);
1006   void agf(Register r1, const MemOperand& opnd);
1007   void agfi(Register r1, const Operand& opnd);
1008   void agfr(Register r1, Register r2);
1009   void aghi(Register r1, const Operand& opnd);
1010   void aghik(Register r1, Register r3, const Operand& opnd);
1011   void agr(Register r1, Register r2);
1012   void agrk(Register r1, Register r2, Register r3);
1013   void agsi(const MemOperand&, const Operand&);
1014 
1015   // 32-bit Add Logical Instructions
1016   void al_z(Register r1, const MemOperand& opnd);
1017   void aly(Register r1, const MemOperand& opnd);
1018   void alfi(Register r1, const Operand& opnd);
1019   void alr(Register r1, Register r2);
1020   void alcr(Register r1, Register r2);
1021   void alrk(Register r1, Register r2, Register r3);
1022 
1023   // 64-bit Add Logical Instructions
1024   void alg(Register r1, const MemOperand& opnd);
1025   void algfi(Register r1, const Operand& opnd);
1026   void algr(Register r1, Register r2);
1027   void algrk(Register r1, Register r2, Register r3);
1028 
1029   // 32-bit Subtract Instructions
1030   void s(Register r1, const MemOperand& opnd);
1031   void sy(Register r1, const MemOperand& opnd);
1032   void sh(Register r1, const MemOperand& opnd);
1033   void shy(Register r1, const MemOperand& opnd);
1034   void sr(Register r1, Register r2);
1035   void srk(Register r1, Register r2, Register r3);
1036 
1037   // 64-bit Subtract Instructions
1038   void sg(Register r1, const MemOperand& opnd);
1039   void sgf(Register r1, const MemOperand& opnd);
1040   void sgr(Register r1, Register r2);
1041   void sgfr(Register r1, Register r2);
1042   void sgrk(Register r1, Register r2, Register r3);
1043 
1044   // 32-bit Subtract Logical Instructions
1045   void sl(Register r1, const MemOperand& opnd);
1046   void sly(Register r1, const MemOperand& opnd);
1047   void slr(Register r1, Register r2);
1048   void slrk(Register r1, Register r2, Register r3);
1049   void slbr(Register r1, Register r2);
1050 
1051   // 64-bit Subtract Logical Instructions
1052   void slg(Register r1, const MemOperand& opnd);
1053   void slgr(Register r1, Register r2);
1054   void slgrk(Register r1, Register r2, Register r3);
1055 
1056   // 32-bit Multiply Instructions
1057   void m(Register r1, const MemOperand& opnd);
1058   void mfy(Register r1, const MemOperand& opnd);
1059   void mr_z(Register r1, Register r2);
1060   void ml(Register r1, const MemOperand& opnd);
1061   void mlr(Register r1, Register r2);
1062   void ms(Register r1, const MemOperand& opnd);
1063   void msy(Register r1, const MemOperand& opnd);
1064   void msfi(Register r1, const Operand& opnd);
1065   void msr(Register r1, Register r2);
1066   void mh(Register r1, const MemOperand& opnd);
1067   void mhy(Register r1, const MemOperand& opnd);
1068   void mhi(Register r1, const Operand& opnd);
1069 
1070   // 64-bit Multiply Instructions
1071   void mlg(Register r1, const MemOperand& opnd);
1072   void mlgr(Register r1, Register r2);
1073   void mghi(Register r1, const Operand& opnd);
1074   void msgfi(Register r1, const Operand& opnd);
1075   void msg(Register r1, const MemOperand& opnd);
1076   void msgr(Register r1, Register r2);
1077 
1078   // 32-bit Divide Instructions
1079   void d(Register r1, const MemOperand& opnd);
1080   void dr(Register r1, Register r2);
1081   void dl(Register r1, const MemOperand& opnd);
1082   void dlr(Register r1, Register r2);
1083 
1084   // 64-bit Divide Instructions
1085   void dlgr(Register r1, Register r2);
1086   void dsgr(Register r1, Register r2);
1087 
1088   // Bitwise Instructions (AND / OR / XOR)
1089   void n(Register r1, const MemOperand& opnd);
1090   void ny(Register r1, const MemOperand& opnd);
1091   void nr(Register r1, Register r2);
1092   void nrk(Register r1, Register r2, Register r3);
1093   void ng(Register r1, const MemOperand& opnd);
1094   void ngr(Register r1, Register r2);
1095   void ngrk(Register r1, Register r2, Register r3);
1096   void o(Register r1, const MemOperand& opnd);
1097   void oy(Register r1, const MemOperand& opnd);
1098   void or_z(Register r1, Register r2);
1099   void ork(Register r1, Register r2, Register r3);
1100   void og(Register r1, const MemOperand& opnd);
1101   void ogr(Register r1, Register r2);
1102   void ogrk(Register r1, Register r2, Register r3);
1103   void x(Register r1, const MemOperand& opnd);
1104   void xy(Register r1, const MemOperand& opnd);
1105   void xr(Register r1, Register r2);
1106   void xrk(Register r1, Register r2, Register r3);
1107   void xg(Register r1, const MemOperand& opnd);
1108   void xgr(Register r1, Register r2);
1109   void xgrk(Register r1, Register r2, Register r3);
1110   void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
1111 
1112   // Bitwise GPR <-> FPR Conversion Instructions
1113   void lgdr(Register r1, DoubleRegister f2);
1114   void ldgr(DoubleRegister f1, Register r2);
1115 
1116   // Floating Point Load / Store Instructions
1117   void ld(DoubleRegister r1, const MemOperand& opnd);
1118   void ldy(DoubleRegister r1, const MemOperand& opnd);
1119   void le_z(DoubleRegister r1, const MemOperand& opnd);
1120   void ley(DoubleRegister r1, const MemOperand& opnd);
1121   void ldr(DoubleRegister r1, DoubleRegister r2);
1122   void ltdbr(DoubleRegister r1, DoubleRegister r2);
1123   void ltebr(DoubleRegister r1, DoubleRegister r2);
1124   void std(DoubleRegister r1, const MemOperand& opnd);
1125   void stdy(DoubleRegister r1, const MemOperand& opnd);
1126   void ste(DoubleRegister r1, const MemOperand& opnd);
1127   void stey(DoubleRegister r1, const MemOperand& opnd);
1128 
1129   // Floating Point Load Rounded/Positive Instructions
1130   void ledbr(DoubleRegister r1, DoubleRegister r2);
1131   void ldebr(DoubleRegister r1, DoubleRegister r2);
1132   void lpebr(DoubleRegister r1, DoubleRegister r2);
1133   void lpdbr(DoubleRegister r1, DoubleRegister r2);
1134 
1135   // Floating <-> Fixed Point Conversion Instructions
1136   void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg,
1137               Register fixReg);
1138   void cdlgbr(Condition m3, Condition m4, DoubleRegister fltReg,
1139               Register fixReg);
1140   void celgbr(Condition m3, Condition m4, DoubleRegister fltReg,
1141               Register fixReg);
1142   void celfbr(Condition m3, Condition m4, DoubleRegister fltReg,
1143               Register fixReg);
1144   void clfdbr(Condition m3, Condition m4, Register fixReg,
1145               DoubleRegister fltReg);
1146   void clfebr(Condition m3, Condition m4, Register fixReg,
1147               DoubleRegister fltReg);
1148   void clgdbr(Condition m3, Condition m4, Register fixReg,
1149               DoubleRegister fltReg);
1150   void clgebr(Condition m3, Condition m4, Register fixReg,
1151               DoubleRegister fltReg);
1152   void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg);
1153   void cdfbr(DoubleRegister fltReg, Register fixReg);
1154   void cgebr(Condition m, Register fixReg, DoubleRegister fltReg);
1155   void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg);
1156   void cegbr(DoubleRegister fltReg, Register fixReg);
1157   void cdgbr(DoubleRegister fltReg, Register fixReg);
1158   void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg);
1159   void cefbr(Condition m3, DoubleRegister fltReg, Register fixReg);
1160 
1161   // Floating Point Compare Instructions
1162   void cebr(DoubleRegister r1, DoubleRegister r2);
1163   void cdb(DoubleRegister r1, const MemOperand& opnd);
1164   void cdbr(DoubleRegister r1, DoubleRegister r2);
1165 
1166   // Floating Point Arithmetic Instructions
1167   void aebr(DoubleRegister r1, DoubleRegister r2);
1168   void adb(DoubleRegister r1, const MemOperand& opnd);
1169   void adbr(DoubleRegister r1, DoubleRegister r2);
1170   void lzdr(DoubleRegister r1);
1171   void sebr(DoubleRegister r1, DoubleRegister r2);
1172   void sdb(DoubleRegister r1, const MemOperand& opnd);
1173   void sdbr(DoubleRegister r1, DoubleRegister r2);
1174   void meebr(DoubleRegister r1, DoubleRegister r2);
1175   void mdb(DoubleRegister r1, const MemOperand& opnd);
1176   void mdbr(DoubleRegister r1, DoubleRegister r2);
1177   void debr(DoubleRegister r1, DoubleRegister r2);
1178   void ddb(DoubleRegister r1, const MemOperand& opnd);
1179   void ddbr(DoubleRegister r1, DoubleRegister r2);
1180   void madbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3);
1181   void msdbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3);
1182   void sqebr(DoubleRegister r1, DoubleRegister r2);
1183   void sqdb(DoubleRegister r1, const MemOperand& opnd);
1184   void sqdbr(DoubleRegister r1, DoubleRegister r2);
1185   void lcdbr(DoubleRegister r1, DoubleRegister r2);
1186   void lcebr(DoubleRegister r1, DoubleRegister r2);
1187   void ldeb(DoubleRegister r1, const MemOperand& opnd);
1188 
1189   enum FIDBRA_MASK3 {
1190     FIDBRA_CURRENT_ROUNDING_MODE = 0,
1191     FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1,
1192     // ...
1193     FIDBRA_ROUND_TOWARD_0 = 5,
1194     FIDBRA_ROUND_TOWARD_POS_INF = 6,
1195     FIDBRA_ROUND_TOWARD_NEG_INF = 7
1196   };
1197   void fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3);
1198   void fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3);
1199 
1200   // Move integer
1201   void mvhi(const MemOperand& opnd1, const Operand& i2);
1202   void mvghi(const MemOperand& opnd1, const Operand& i2);
1203 
1204   // Exception-generating instructions and debugging support
1205   void stop(const char* msg, Condition cond = al,
1206             int32_t code = kDefaultStopCode, CRegister cr = cr7);
1207 
1208   void bkpt(uint32_t imm16);  // v5 and above
1209 
1210   // Different nop operations are used by the code generator to detect certain
1211   // states of the generated code.
1212   enum NopMarkerTypes {
1213     NON_MARKING_NOP = 0,
1214     GROUP_ENDING_NOP,
1215     DEBUG_BREAK_NOP,
1216     // IC markers.
1217     PROPERTY_ACCESS_INLINED,
1218     PROPERTY_ACCESS_INLINED_CONTEXT,
1219     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1220     // Helper values.
1221     LAST_CODE_MARKER,
1222     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1223   };
1224 
1225   void nop(int type = 0);  // 0 is the default non-marking type.
1226 
1227   // Check the code size generated from label to here.
SizeOfCodeGeneratedSince(Label * label)1228   int SizeOfCodeGeneratedSince(Label* label) {
1229     return pc_offset() - label->pos();
1230   }
1231 
1232   // Debugging
1233 
1234   // Mark generator continuation.
1235   void RecordGeneratorContinuation();
1236 
1237   // Mark address of a debug break slot.
1238   void RecordDebugBreakSlot(RelocInfo::Mode mode);
1239 
1240   // Record the AST id of the CallIC being compiled, so that it can be placed
1241   // in the relocation information.
SetRecordedAstId(TypeFeedbackId ast_id)1242   void SetRecordedAstId(TypeFeedbackId ast_id) { recorded_ast_id_ = ast_id; }
1243 
RecordedAstId()1244   TypeFeedbackId RecordedAstId() {
1245     // roohack - another issue??? DCHECK(!recorded_ast_id_.IsNone());
1246     return recorded_ast_id_;
1247   }
1248 
ClearRecordedAstId()1249   void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
1250 
1251   // Record a comment relocation entry that can be used by a disassembler.
1252   // Use --code-comments to enable.
1253   void RecordComment(const char* msg);
1254 
1255   // Record a deoptimization reason that can be used by a log or cpu profiler.
1256   // Use --trace-deopt to enable.
1257   void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1258                          int id);
1259 
1260   // Writes a single byte or word of data in the code stream.  Used
1261   // for inline tables, e.g., jump-tables.
1262   void db(uint8_t data);
1263   void dd(uint32_t data);
1264   void dq(uint64_t data);
1265   void dp(uintptr_t data);
1266 
PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)1267   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1268                                           ConstantPoolEntry::Access access,
1269                                           ConstantPoolEntry::Type type) {
1270     // No embedded constant pool support.
1271     UNREACHABLE();
1272   }
1273 
1274   // Read/patch instructions
instr_at(int pos)1275   SixByteInstr instr_at(int pos) {
1276     return Instruction::InstructionBits(buffer_ + pos);
1277   }
1278   template <typename T>
instr_at_put(int pos,T instr)1279   void instr_at_put(int pos, T instr) {
1280     Instruction::SetInstructionBits<T>(buffer_ + pos, instr);
1281   }
1282 
1283   // Decodes instruction at pos, and returns its length
instr_length_at(int pos)1284   int32_t instr_length_at(int pos) {
1285     return Instruction::InstructionLength(buffer_ + pos);
1286   }
1287 
instr_at(byte * pc)1288   static SixByteInstr instr_at(byte* pc) {
1289     return Instruction::InstructionBits(pc);
1290   }
1291 
1292   static Condition GetCondition(Instr instr);
1293 
1294   static bool IsBranch(Instr instr);
1295 #if V8_TARGET_ARCH_S390X
1296   static bool Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2);
1297 #else
1298   static bool Is32BitLoadIntoIP(SixByteInstr instr);
1299 #endif
1300 
1301   static bool IsCmpRegister(Instr instr);
1302   static bool IsCmpImmediate(Instr instr);
1303   static bool IsNop(SixByteInstr instr, int type = NON_MARKING_NOP);
1304 
1305   // The code currently calls CheckBuffer() too often. This has the side
1306   // effect of randomly growing the buffer in the middle of multi-instruction
1307   // sequences.
1308   //
1309   // This function allows outside callers to check and grow the buffer
1310   void EnsureSpaceFor(int space_needed);
1311 
1312   void EmitRelocations();
1313   void emit_label_addr(Label* label);
1314 
1315  public:
buffer_pos()1316   byte* buffer_pos() const { return buffer_; }
1317 
1318  protected:
1319   // Relocation for a type-recording IC has the AST id added to it.  This
1320   // member variable is a way to pass the information from the call site to
1321   // the relocation info.
1322   TypeFeedbackId recorded_ast_id_;
1323 
buffer_space()1324   int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1325 
1326   // Decode instruction(s) at pos and return backchain to previous
1327   // label reference or kEndOfChain.
1328   int target_at(int pos);
1329 
1330   // Patch instruction(s) at pos to target target_pos (e.g. branch)
1331   void target_at_put(int pos, int target_pos, bool* is_branch = nullptr);
1332 
1333   // Record reloc info for current pc_
1334   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1335 
1336  private:
1337   // Code generation
1338   // The relocation writer's position is at least kGap bytes below the end of
1339   // the generated instructions. This is so that multi-instruction sequences do
1340   // not have to check for overflow. The same is true for writes of large
1341   // relocation info entries.
1342   static const int kGap = 32;
1343 
1344   // Relocation info generation
1345   // Each relocation is encoded as a variable size value
1346   static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1347   RelocInfoWriter reloc_info_writer;
1348   std::vector<DeferredRelocInfo> relocations_;
1349 
1350   // The bound position, before this we cannot do instruction elimination.
1351   int last_bound_pos_;
1352 
1353   // Code emission
1354   inline void CheckBuffer();
1355   void GrowBuffer(int needed = 0);
1356   inline void TrackBranch();
1357   inline void UntrackBranch();
1358 
1359   inline int32_t emit_code_target(
1360       Handle<Code> target, RelocInfo::Mode rmode,
1361       TypeFeedbackId ast_id = TypeFeedbackId::None());
1362 
1363   // Helpers to emit binary encoding of 2/4/6 byte instructions.
1364   inline void emit2bytes(uint16_t x);
1365   inline void emit4bytes(uint32_t x);
1366   inline void emit6bytes(uint64_t x);
1367 
1368   // Helpers to emit binary encoding for various instruction formats.
1369 
1370   inline void rr_form(Opcode op, Register r1, Register r2);
1371   inline void rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2);
1372   inline void rr_form(Opcode op, Condition m1, Register r2);
1373   inline void rr2_form(uint8_t op, Condition m1, Register r2);
1374 
1375   inline void rx_form(Opcode op, Register r1, Register x2, Register b2,
1376                       Disp d2);
1377   inline void rx_form(Opcode op, DoubleRegister r1, Register x2, Register b2,
1378                       Disp d2);
1379 
1380   inline void ri_form(Opcode op, Register r1, const Operand& i2);
1381   inline void ri_form(Opcode op, Condition m1, const Operand& i2);
1382 
1383   inline void rie_form(Opcode op, Register r1, Register r3, const Operand& i2);
1384   inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3,
1385                          const Operand& i4, const Operand& i5);
1386 
1387   inline void ril_form(Opcode op, Register r1, const Operand& i2);
1388   inline void ril_form(Opcode op, Condition m1, const Operand& i2);
1389 
1390   inline void ris_form(Opcode op, Register r1, Condition m3, Register b4,
1391                        Disp d4, const Operand& i2);
1392 
1393   inline void rrd_form(Opcode op, Register r1, Register r3, Register r2);
1394 
1395   inline void rre_form(Opcode op, Register r1, Register r2);
1396   inline void rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2);
1397 
1398   inline void rrf1_form(Opcode op, Register r1, Register r2, Register r3);
1399   inline void rrf1_form(uint32_t x);
1400   inline void rrf2_form(uint32_t x);
1401   inline void rrf3_form(uint32_t x);
1402   inline void rrfe_form(Opcode op, Condition m3, Condition m4, Register r1,
1403                         Register r2);
1404 
1405   inline void rrs_form(Opcode op, Register r1, Register r2, Register b4,
1406                        Disp d4, Condition m3);
1407 
1408   inline void rs_form(Opcode op, Register r1, Condition m3, Register b2,
1409                       const Disp d2);
1410   inline void rs_form(Opcode op, Register r1, Register r3, Register b2,
1411                       const Disp d2);
1412 
1413   inline void rsi_form(Opcode op, Register r1, Register r3, const Operand& i2);
1414   inline void rsl_form(Opcode op, Length l1, Register b2, Disp d2);
1415 
1416   inline void rsy_form(Opcode op, Register r1, Register r3, Register b2,
1417                        const Disp d2);
1418   inline void rsy_form(Opcode op, Register r1, Condition m3, Register b2,
1419                        const Disp d2);
1420 
1421   inline void rxe_form(Opcode op, Register r1, Register x2, Register b2,
1422                        Disp d2);
1423 
1424   inline void rxf_form(Opcode op, Register r1, Register r3, Register b2,
1425                        Register x2, Disp d2);
1426 
1427   inline void rxy_form(Opcode op, Register r1, Register x2, Register b2,
1428                        Disp d2);
1429   inline void rxy_form(Opcode op, Register r1, Condition m3, Register b2,
1430                        Disp d2);
1431   inline void rxy_form(Opcode op, DoubleRegister r1, Register x2, Register b2,
1432                        Disp d2);
1433 
1434   inline void s_form(Opcode op, Register b1, Disp d2);
1435 
1436   inline void si_form(Opcode op, const Operand& i2, Register b1, Disp d1);
1437   inline void siy_form(Opcode op, const Operand& i2, Register b1, Disp d1);
1438 
1439   inline void sil_form(Opcode op, Register b1, Disp d1, const Operand& i2);
1440 
1441   inline void ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2,
1442                       Disp d2);
1443   inline void ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1,
1444                       Register b2, Disp d2);
1445   inline void ss_form(Opcode op, Length l1, const Operand& i3, Register b1,
1446                       Disp d1, Register b2, Disp d2);
1447   inline void ss_form(Opcode op, Register r1, Register r2, Register b1, Disp d1,
1448                       Register b2, Disp d2);
1449   inline void sse_form(Opcode op, Register b1, Disp d1, Register b2, Disp d2);
1450   inline void ssf_form(Opcode op, Register r3, Register b1, Disp d1,
1451                        Register b2, Disp d2);
1452 
1453   // Labels
1454   void print(Label* L);
1455   int max_reach_from(int pos);
1456   void bind_to(Label* L, int pos);
1457   void next(Label* L);
1458 
1459   friend class RegExpMacroAssemblerS390;
1460   friend class RelocInfo;
1461   friend class CodePatcher;
1462 
1463   List<Handle<Code> > code_targets_;
1464   friend class EnsureSpace;
1465 };
1466 
1467 class EnsureSpace BASE_EMBEDDED {
1468  public:
EnsureSpace(Assembler * assembler)1469   explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1470 };
1471 
1472 }  // namespace internal
1473 }  // namespace v8
1474 
1475 #endif  // V8_S390_ASSEMBLER_S390_H_
1476