blob: 0b9fa385395cb354ac5ef5233a05861cb6c96688 [file] [log] [blame]
Ben Murdochda12d292016-06-02 14:46:10 +01001// Copyright (c) 1994-2006 Sun Microsystems Inc.
2// All Rights Reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7//
8// - Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// - Redistribution in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the
14// distribution.
15//
16// - Neither the name of Sun Microsystems or the names of contributors may
17// be used to endorse or promote products derived from this software without
18// specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31// OF THE POSSIBILITY OF SUCH DAMAGE.
32
33// The original source code covered by the above license above has been
34// modified significantly by Google Inc.
35// Copyright 2014 the V8 project authors. All rights reserved.
36
37// A light-weight S390 Assembler
38// Generates user mode instructions for z/Architecture
39
40#ifndef V8_S390_ASSEMBLER_S390_H_
41#define V8_S390_ASSEMBLER_S390_H_
42#include <stdio.h>
43#if V8_HOST_ARCH_S390
44// elf.h include is required for auxv check for STFLE facility used
45// for hardware detection, which is sensible only on s390 hosts.
46#include <elf.h>
47#endif
48
49#include <fcntl.h>
50#include <unistd.h>
51#include "src/assembler.h"
52#include "src/s390/constants-s390.h"
53
54#define ABI_USES_FUNCTION_DESCRIPTORS 0
55
56#define ABI_PASSES_HANDLES_IN_REGS 1
57
58// ObjectPair is defined under runtime/runtime-util.h.
59// On 31-bit, ObjectPair == uint64_t. ABI dictates long long
60// be returned with the lower addressed half in r2
61// and the higher addressed half in r3. (Returns in Regs)
62// On 64-bit, ObjectPair is a Struct. ABI dictaes Structs be
63// returned in a storage buffer allocated by the caller,
64// with the address of this buffer passed as a hidden
65// argument in r2. (Does NOT return in Regs)
66// For x86 linux, ObjectPair is returned in registers.
67#if V8_TARGET_ARCH_S390X
68#define ABI_RETURNS_OBJECTPAIR_IN_REGS 0
69#else
70#define ABI_RETURNS_OBJECTPAIR_IN_REGS 1
71#endif
72
73#define ABI_CALL_VIA_IP 1
74
75#define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC
76
77namespace v8 {
78namespace internal {
79
80// clang-format off
81#define GENERAL_REGISTERS(V) \
82 V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \
83 V(r8) V(r9) V(r10) V(fp) V(ip) V(r13) V(r14) V(sp)
84
85#define ALLOCATABLE_GENERAL_REGISTERS(V) \
86 V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \
87 V(r8) V(r9) V(r13)
88
89#define DOUBLE_REGISTERS(V) \
90 V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
91 V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15)
92
93#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
94 V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
95 V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) V(d0)
96// clang-format on
97
98// CPU Registers.
99//
100// 1) We would prefer to use an enum, but enum values are assignment-
101// compatible with int, which has caused code-generation bugs.
102//
103// 2) We would prefer to use a class instead of a struct but we don't like
104// the register initialization to depend on the particular initialization
105// order (which appears to be different on OS X, Linux, and Windows for the
106// installed versions of C++ we tried). Using a struct permits C-style
107// "initialization". Also, the Register objects cannot be const as this
108// forces initialization stubs in MSVC, making us dependent on initialization
109// order.
110//
111// 3) By not using an enum, we are possibly preventing the compiler from
112// doing certain constant folds, which may significantly reduce the
113// code generated for some assembly instructions (because they boil down
114// to a few constants). If this is a problem, we could change the code
115// such that we use an enum in optimized mode, and the struct in debug
116// mode. This way we get the compile-time error checking in debug mode
117// and best performance in optimized code.
118
119struct Register {
120 enum Code {
121#define REGISTER_CODE(R) kCode_##R,
122 GENERAL_REGISTERS(REGISTER_CODE)
123#undef REGISTER_CODE
124 kAfterLast,
125 kCode_no_reg = -1
126 };
127 static const int kNumRegisters = Code::kAfterLast;
128
129#define REGISTER_COUNT(R) 1 +
130 static const int kNumAllocatable =
131 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0;
132#undef REGISTER_COUNT
133
134#define REGISTER_BIT(R) 1 << kCode_##R |
135 static const RegList kAllocatable =
136 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0;
137#undef REGISTER_BIT
138
139 static Register from_code(int code) {
140 DCHECK(code >= 0);
141 DCHECK(code < kNumRegisters);
142 Register r = {code};
143 return r;
144 }
145
146 const char* ToString();
147 bool IsAllocatable() const;
148 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
149 bool is(Register reg) const { return reg_code == reg.reg_code; }
150 int code() const {
151 DCHECK(is_valid());
152 return reg_code;
153 }
154 int bit() const {
155 DCHECK(is_valid());
156 return 1 << reg_code;
157 }
158
159 void set_code(int code) {
160 reg_code = code;
161 DCHECK(is_valid());
162 }
163
164#if V8_TARGET_LITTLE_ENDIAN
165 static const int kMantissaOffset = 0;
166 static const int kExponentOffset = 4;
167#else
168 static const int kMantissaOffset = 4;
169 static const int kExponentOffset = 0;
170#endif
171
172 // Unfortunately we can't make this private in a struct.
173 int reg_code;
174};
175
176typedef struct Register Register;
177
178#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
179GENERAL_REGISTERS(DECLARE_REGISTER)
180#undef DECLARE_REGISTER
181const Register no_reg = {Register::kCode_no_reg};
182
183// Register aliases
184const Register kLithiumScratch = r1; // lithium scratch.
185const Register kRootRegister = r10; // Roots array pointer.
186const Register cp = r13; // JavaScript context pointer.
187
188// Double word FP register.
189struct DoubleRegister {
190 enum Code {
191#define REGISTER_CODE(R) kCode_##R,
192 DOUBLE_REGISTERS(REGISTER_CODE)
193#undef REGISTER_CODE
194 kAfterLast,
195 kCode_no_reg = -1
196 };
197
198 static const int kNumRegisters = Code::kAfterLast;
199 static const int kMaxNumRegisters = kNumRegisters;
200
201 const char* ToString();
202 bool IsAllocatable() const;
203 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
204 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
205
206 int code() const {
207 DCHECK(is_valid());
208 return reg_code;
209 }
210
211 int bit() const {
212 DCHECK(is_valid());
213 return 1 << reg_code;
214 }
215
216 static DoubleRegister from_code(int code) {
217 DoubleRegister r = {code};
218 return r;
219 }
220
221 int reg_code;
222};
223
224typedef DoubleRegister DoubleRegister;
225
226#define DECLARE_REGISTER(R) \
227 const DoubleRegister R = {DoubleRegister::kCode_##R};
228DOUBLE_REGISTERS(DECLARE_REGISTER)
229#undef DECLARE_REGISTER
230const Register no_dreg = {Register::kCode_no_reg};
231
232// Aliases for double registers. Defined using #define instead of
233// "static const DoubleRegister&" because Clang complains otherwise when a
234// compilation unit that includes this header doesn't use the variables.
235#define kDoubleRegZero d14
236#define kScratchDoubleReg d13
237
238Register ToRegister(int num);
239
240// Coprocessor register
241struct CRegister {
242 bool is_valid() const { return 0 <= reg_code && reg_code < 8; }
243 bool is(CRegister creg) const { return reg_code == creg.reg_code; }
244 int code() const {
245 DCHECK(is_valid());
246 return reg_code;
247 }
248 int bit() const {
249 DCHECK(is_valid());
250 return 1 << reg_code;
251 }
252
253 // Unfortunately we can't make this private in a struct.
254 int reg_code;
255};
256
257const CRegister no_creg = {-1};
258
259const CRegister cr0 = {0};
260const CRegister cr1 = {1};
261const CRegister cr2 = {2};
262const CRegister cr3 = {3};
263const CRegister cr4 = {4};
264const CRegister cr5 = {5};
265const CRegister cr6 = {6};
266const CRegister cr7 = {7};
267
268// TODO(john.yan) Define SIMD registers.
269typedef DoubleRegister Simd128Register;
270
271// -----------------------------------------------------------------------------
272// Machine instruction Operands
273
274#if V8_TARGET_ARCH_S390X
275const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64;
276#else
277const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32;
278#endif
279
280// Class Operand represents a shifter operand in data processing instructions
281// defining immediate numbers and masks
282typedef uint8_t Length;
283
284struct Mask {
285 uint8_t mask;
286 uint8_t value() { return mask; }
287 static Mask from_value(uint8_t input) {
288 DCHECK(input <= 0x0F);
289 Mask m = {input};
290 return m;
291 }
292};
293
294class Operand BASE_EMBEDDED {
295 public:
296 // immediate
297 INLINE(explicit Operand(intptr_t immediate,
298 RelocInfo::Mode rmode = kRelocInfo_NONEPTR));
299 INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); }
300 INLINE(explicit Operand(const ExternalReference& f));
301 explicit Operand(Handle<Object> handle);
302 INLINE(explicit Operand(Smi* value));
303
304 // rm
305 INLINE(explicit Operand(Register rm));
306
307 // Return true if this is a register operand.
308 INLINE(bool is_reg() const);
309
310 bool must_output_reloc_info(const Assembler* assembler) const;
311
312 inline intptr_t immediate() const {
313 DCHECK(!rm_.is_valid());
314 return imm_;
315 }
316
317 inline void setBits(int n) {
318 imm_ = (static_cast<uint32_t>(imm_) << (32 - n)) >> (32 - n);
319 }
320
321 Register rm() const { return rm_; }
322
323 private:
324 Register rm_;
325 intptr_t imm_; // valid if rm_ == no_reg
326 RelocInfo::Mode rmode_;
327
328 friend class Assembler;
329 friend class MacroAssembler;
330};
331
332typedef int32_t Disp;
333
334// Class MemOperand represents a memory operand in load and store instructions
335// On S390, we have various flavours of memory operands:
336// 1) a base register + 16 bit unsigned displacement
337// 2) a base register + index register + 16 bit unsigned displacement
338// 3) a base register + index register + 20 bit signed displacement
339class MemOperand BASE_EMBEDDED {
340 public:
341 explicit MemOperand(Register rx, Disp offset = 0);
342 explicit MemOperand(Register rx, Register rb, Disp offset = 0);
343
344 int32_t offset() const { return offset_; }
345 uint32_t getDisplacement() const { return offset(); }
346
347 // Base register
348 Register rb() const {
349 DCHECK(!baseRegister.is(no_reg));
350 return baseRegister;
351 }
352
353 Register getBaseRegister() const { return rb(); }
354
355 // Index Register
356 Register rx() const {
357 DCHECK(!indexRegister.is(no_reg));
358 return indexRegister;
359 }
360 Register getIndexRegister() const { return rx(); }
361
362 private:
363 Register baseRegister; // base
364 Register indexRegister; // index
365 int32_t offset_; // offset
366
367 friend class Assembler;
368};
369
370class DeferredRelocInfo {
371 public:
372 DeferredRelocInfo() {}
373 DeferredRelocInfo(int position, RelocInfo::Mode rmode, intptr_t data)
374 : position_(position), rmode_(rmode), data_(data) {}
375
376 int position() const { return position_; }
377 RelocInfo::Mode rmode() const { return rmode_; }
378 intptr_t data() const { return data_; }
379
380 private:
381 int position_;
382 RelocInfo::Mode rmode_;
383 intptr_t data_;
384};
385
386class Assembler : public AssemblerBase {
387 public:
388 // Create an assembler. Instructions and relocation information are emitted
389 // into a buffer, with the instructions starting from the beginning and the
390 // relocation information starting from the end of the buffer. See CodeDesc
391 // for a detailed comment on the layout (globals.h).
392 //
393 // If the provided buffer is NULL, the assembler allocates and grows its own
394 // buffer, and buffer_size determines the initial buffer size. The buffer is
395 // owned by the assembler and deallocated upon destruction of the assembler.
396 //
397 // If the provided buffer is not NULL, the assembler uses the provided buffer
398 // for code generation and assumes its size to be buffer_size. If the buffer
399 // is too small, a fatal error occurs. No deallocation of the buffer is done
400 // upon destruction of the assembler.
401 Assembler(Isolate* isolate, void* buffer, int buffer_size);
402 virtual ~Assembler() {}
403
404 // GetCode emits any pending (non-emitted) code and fills the descriptor
405 // desc. GetCode() is idempotent; it returns the same result if no other
406 // Assembler functions are invoked in between GetCode() calls.
407 void GetCode(CodeDesc* desc);
408
409 // Label operations & relative jumps (PPUM Appendix D)
410 //
411 // Takes a branch opcode (cc) and a label (L) and generates
412 // either a backward branch or a forward branch and links it
413 // to the label fixup chain. Usage:
414 //
415 // Label L; // unbound label
416 // j(cc, &L); // forward branch to unbound label
417 // bind(&L); // bind label to the current pc
418 // j(cc, &L); // backward branch to bound label
419 // bind(&L); // illegal: a label may be bound only once
420 //
421 // Note: The same Label can be used for forward and backward branches
422 // but it may be bound only once.
423
424 void bind(Label* L); // binds an unbound label L to the current code position
425
426 // Links a label at the current pc_offset(). If already bound, returns the
427 // bound position. If already linked, returns the position of the prior link.
428 // Otherwise, returns the current pc_offset().
429 int link(Label* L);
430
431 // Determines if Label is bound and near enough so that a single
432 // branch instruction can be used to reach it.
433 bool is_near(Label* L, Condition cond);
434
435 // Returns the branch offset to the given label from the current code position
436 // Links the label to the current position if it is still unbound
437 int branch_offset(Label* L) { return link(L) - pc_offset(); }
438
439 // Puts a labels target address at the given position.
440 // The high 8 bits are set to zero.
441 void label_at_put(Label* L, int at_offset);
442 void load_label_offset(Register r1, Label* L);
443
444 // Read/Modify the code target address in the branch/call instruction at pc.
445 INLINE(static Address target_address_at(Address pc, Address constant_pool));
446 INLINE(static void set_target_address_at(
447 Isolate* isolate, Address pc, Address constant_pool, Address target,
448 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
449 INLINE(static Address target_address_at(Address pc, Code* code)) {
450 Address constant_pool = NULL;
451 return target_address_at(pc, constant_pool);
452 }
453 INLINE(static void set_target_address_at(
454 Isolate* isolate, Address pc, Code* code, Address target,
455 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
456 Address constant_pool = NULL;
457 set_target_address_at(isolate, pc, constant_pool, target,
458 icache_flush_mode);
459 }
460
461 // Return the code target address at a call site from the return address
462 // of that call in the instruction stream.
463 inline static Address target_address_from_return_address(Address pc);
464
465 // Given the address of the beginning of a call, return the address
466 // in the instruction stream that the call will return to.
467 INLINE(static Address return_address_from_call_start(Address pc));
468
469 inline Handle<Object> code_target_object_handle_at(Address pc);
470 // This sets the branch destination.
471 // This is for calls and branches within generated code.
472 inline static void deserialization_set_special_target_at(
473 Isolate* isolate, Address instruction_payload, Code* code,
474 Address target);
475
476 // This sets the internal reference at the pc.
477 inline static void deserialization_set_target_internal_reference_at(
478 Isolate* isolate, Address pc, Address target,
479 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
480
481 // Here we are patching the address in the IIHF/IILF instruction pair.
482 // These values are used in the serialization process and must be zero for
483 // S390 platform, as Code, Embedded Object or External-reference pointers
484 // are split across two consecutive instructions and don't exist separately
485 // in the code, so the serializer should not step forwards in memory after
486 // a target is resolved and written.
487 static const int kSpecialTargetSize = 0;
488
489// Number of bytes for instructions used to store pointer sized constant.
490#if V8_TARGET_ARCH_S390X
491 static const int kBytesForPtrConstant = 12; // IIHF + IILF
492#else
493 static const int kBytesForPtrConstant = 6; // IILF
494#endif
495
496 // Distance between the instruction referring to the address of the call
497 // target and the return address.
498
499 // Offset between call target address and return address
500 // for BRASL calls
501 // Patch will be appiled to other FIXED_SEQUENCE call
502 static const int kCallTargetAddressOffset = 6;
503
504// The length of FIXED_SEQUENCE call
505// iihf r8, <address_hi> // <64-bit only>
506// iilf r8, <address_lo>
507// basr r14, r8
508#if V8_TARGET_ARCH_S390X
509 static const int kCallSequenceLength = 14;
510#else
511 static const int kCallSequenceLength = 8;
512#endif
513
514 // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn()
515 // code patch FIXED_SEQUENCE in bytes!
516 // JS Return Sequence = Call Sequence + BKPT
517 // static const int kJSReturnSequenceLength = kCallSequenceLength + 2;
518
519 // This is the length of the code sequence from SetDebugBreakAtSlot()
520 // FIXED_SEQUENCE in bytes!
521 static const int kDebugBreakSlotLength = kCallSequenceLength;
522 static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset;
523
524 // Length to patch between the start of the JS return sequence
525 // from SetDebugBreakAtReturn and the address from
526 // break_address_from_return_address.
527 //
528 // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in
529 // JS return sequence, so the length to patch will not include BKPT
530 // instruction length.
531 // static const int kPatchReturnSequenceAddressOffset =
532 // kCallSequenceLength - kPatchDebugBreakSlotReturnOffset;
533
534 // Length to patch between the start of the FIXED call sequence from
535 // SetDebugBreakAtSlot() and the the address from
536 // break_address_from_return_address.
537 static const int kPatchDebugBreakSlotAddressOffset =
538 kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset;
539
540 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
541 return ((cr.code() * CRWIDTH) + crbit);
542 }
543
544 // ---------------------------------------------------------------------------
545 // Code generation
546
547 // Helper for unconditional branch to Label with update to save register
548 void b(Register r, Label* l) {
549 positions_recorder()->WriteRecordedPositions();
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
583 void b(Condition cond, Register r) { bcr(cond, r); }
584 void beq(Register r) { b(eq, r); }
585 void bne(Register r) { b(ne, r); }
586 void blt(Register r) { b(lt, r); }
587 void ble(Register r) { b(le, r); }
588 void bgt(Register r) { b(gt, r); }
589 void bge(Register r) { b(ge, r); }
590 void b(Register r) { b(al, r); }
591 void jmp(Register r) { b(al, r); }
592 void bunordered(Register r) { b(unordered, 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
608 void breakpoint(bool do_print) {
609 if (do_print) {
610 printf("DebugBreak is inserted to %p\n", 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 RRE_FORM(cefbr);
769 RXE_FORM(ddb);
770 RRE_FORM(ddbr);
771 SS1_FORM(ed);
772 RRE_FORM(epair);
773 RX_FORM(ex);
774 RRF2_FORM(fidbr);
775 RRE_FORM(flogr);
776 RX_FORM(ic_z);
777 RXY_FORM(icy);
778 RIL1_FORM(iihf);
779 RI1_FORM(iihh);
780 RI1_FORM(iihl);
781 RIL1_FORM(iilf);
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 RXY_FORM(lrvh);
795 RXE_FORM(mdb);
796 RRE_FORM(mdbr);
797 SS4_FORM(mvck);
798 SSF_FORM(mvcos);
799 SS4_FORM(mvcs);
800 SS1_FORM(mvn);
801 SS1_FORM(nc);
802 SI_FORM(ni);
803 RIL1_FORM(nihf);
804 RIL1_FORM(nilf);
805 RI1_FORM(nilh);
806 RI1_FORM(nill);
807 RIL1_FORM(oihf);
808 RIL1_FORM(oilf);
809 RI1_FORM(oill);
810 RRE_FORM(popcnt);
811 RXE_FORM(sdb);
812 RRE_FORM(sdbr);
813 RIL1_FORM(slfi);
814 RXY_FORM(slgf);
815 RIL1_FORM(slgfi);
816 RS1_FORM(srdl);
817 RX_FORM(ste);
818 RXY_FORM(stey);
819 RXY_FORM(strv);
820 RI1_FORM(tmll);
821 SS1_FORM(tr);
822 S_FORM(ts);
823 RIL1_FORM(xihf);
824 RIL1_FORM(xilf);
825
826 // Load Address Instructions
827 void la(Register r, const MemOperand& opnd);
828 void lay(Register r, const MemOperand& opnd);
829 void larl(Register r1, const Operand& opnd);
830 void larl(Register r, Label* l);
831
832 // Load Instructions
833 void lb(Register r, const MemOperand& src);
834 void lbr(Register r1, Register r2);
835 void lgb(Register r, const MemOperand& src);
836 void lgbr(Register r1, Register r2);
837 void lh(Register r, const MemOperand& src);
838 void lhy(Register r, const MemOperand& src);
839 void lhr(Register r1, Register r2);
840 void lgh(Register r, const MemOperand& src);
841 void lghr(Register r1, Register r2);
842 void l(Register r, const MemOperand& src);
843 void ly(Register r, const MemOperand& src);
844 void lr(Register r1, Register r2);
845 void lg(Register r, const MemOperand& src);
846 void lgr(Register r1, Register r2);
847 void lgf(Register r, const MemOperand& src);
848 void lgfr(Register r1, Register r2);
849 void lhi(Register r, const Operand& imm);
850 void lghi(Register r, const Operand& imm);
851
852 // Load And Test Instructions
853 void lt_z(Register r, const MemOperand& src);
854 void ltg(Register r, const MemOperand& src);
855 void ltr(Register r1, Register r2);
856 void ltgr(Register r1, Register r2);
857 void ltgfr(Register r1, Register r2);
858
859 // Load Logical Instructions
860 void llc(Register r, const MemOperand& src);
861 void llgc(Register r, const MemOperand& src);
862 void llgf(Register r, const MemOperand& src);
863 void llgfr(Register r1, Register r2);
864 void llh(Register r, const MemOperand& src);
865 void llgh(Register r, const MemOperand& src);
866 void llhr(Register r1, Register r2);
867 void llghr(Register r1, Register r2);
868
869 // Load Multiple Instructions
870 void lm(Register r1, Register r2, const MemOperand& src);
871 void lmy(Register r1, Register r2, const MemOperand& src);
872 void lmg(Register r1, Register r2, const MemOperand& src);
873
874 // Store Instructions
875 void st(Register r, const MemOperand& src);
876 void stc(Register r, const MemOperand& src);
877 void stcy(Register r, const MemOperand& src);
878 void stg(Register r, const MemOperand& src);
879 void sth(Register r, const MemOperand& src);
880 void sthy(Register r, const MemOperand& src);
881 void sty(Register r, const MemOperand& src);
882
883 // Store Multiple Instructions
884 void stm(Register r1, Register r2, const MemOperand& src);
885 void stmy(Register r1, Register r2, const MemOperand& src);
886 void stmg(Register r1, Register r2, const MemOperand& src);
887
888 // Compare Instructions
889 void c(Register r, const MemOperand& opnd);
890 void cy(Register r, const MemOperand& opnd);
891 void cr_z(Register r1, Register r2);
892 void cg(Register r, const MemOperand& opnd);
893 void cgr(Register r1, Register r2);
894 void ch(Register r, const MemOperand& opnd);
895 void chy(Register r, const MemOperand& opnd);
896 void chi(Register r, const Operand& opnd);
897 void cghi(Register r, const Operand& opnd);
898 void cfi(Register r, const Operand& opnd);
899 void cgfi(Register r, const Operand& opnd);
900
901 // Compare Logical Instructions
902 void cl(Register r, const MemOperand& opnd);
903 void cly(Register r, const MemOperand& opnd);
904 void clr(Register r1, Register r2);
905 void clg(Register r, const MemOperand& opnd);
906 void clgr(Register r1, Register r2);
907 void clfi(Register r, const Operand& opnd);
908 void clgfi(Register r, const Operand& opnd);
909 void cli(const MemOperand& mem, const Operand& imm);
910 void cliy(const MemOperand& mem, const Operand& imm);
911 void clc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
912
913 // Test Under Mask Instructions
914 void tm(const MemOperand& mem, const Operand& imm);
915 void tmy(const MemOperand& mem, const Operand& imm);
916
917 // Rotate Instructions
918 void rll(Register r1, Register r3, Register opnd);
919 void rll(Register r1, Register r3, const Operand& opnd);
920 void rll(Register r1, Register r3, Register r2, const Operand& opnd);
921 void rllg(Register r1, Register r3, const Operand& opnd);
922 void rllg(Register r1, Register r3, const Register opnd);
923 void rllg(Register r1, Register r3, Register r2, const Operand& opnd);
924
925 // Shift Instructions (32)
926 void sll(Register r1, Register opnd);
927 void sll(Register r1, const Operand& opnd);
928 void sllk(Register r1, Register r3, Register opnd);
929 void sllk(Register r1, Register r3, const Operand& opnd);
930 void srl(Register r1, Register opnd);
931 void srl(Register r1, const Operand& opnd);
932 void srlk(Register r1, Register r3, Register opnd);
933 void srlk(Register r1, Register r3, const Operand& opnd);
934 void sra(Register r1, Register opnd);
935 void sra(Register r1, const Operand& opnd);
936 void srak(Register r1, Register r3, Register opnd);
937 void srak(Register r1, Register r3, const Operand& opnd);
938 void sla(Register r1, Register opnd);
939 void sla(Register r1, const Operand& opnd);
940 void slak(Register r1, Register r3, Register opnd);
941 void slak(Register r1, Register r3, const Operand& opnd);
942
943 // Shift Instructions (64)
944 void sllg(Register r1, Register r3, const Operand& opnd);
945 void sllg(Register r1, Register r3, const Register opnd);
946 void srlg(Register r1, Register r3, const Operand& opnd);
947 void srlg(Register r1, Register r3, const Register opnd);
948 void srag(Register r1, Register r3, const Operand& opnd);
949 void srag(Register r1, Register r3, const Register opnd);
950 void srda(Register r1, const Operand& opnd);
951 void srdl(Register r1, const Operand& opnd);
952 void slag(Register r1, Register r3, const Operand& opnd);
953 void slag(Register r1, Register r3, const Register opnd);
954 void sldl(Register r1, Register b2, const Operand& opnd);
955 void srdl(Register r1, Register b2, const Operand& opnd);
956 void srda(Register r1, Register b2, const Operand& opnd);
957
958 // Rotate and Insert Selected Bits
959 void risbg(Register dst, Register src, const Operand& startBit,
960 const Operand& endBit, const Operand& shiftAmt,
961 bool zeroBits = true);
962 void risbgn(Register dst, Register src, const Operand& startBit,
963 const Operand& endBit, const Operand& shiftAmt,
964 bool zeroBits = true);
965
966 // Move Character (Mem to Mem)
967 void mvc(const MemOperand& opnd1, const MemOperand& opnd2, uint32_t length);
968
969 // Branch Instructions
970 void basr(Register r1, Register r2);
971 void bcr(Condition m, Register target);
972 void bct(Register r, const MemOperand& opnd);
973 void bctg(Register r, const MemOperand& opnd);
974 void bras(Register r, const Operand& opnd);
975 void brasl(Register r, const Operand& opnd);
976 void brc(Condition c, const Operand& opnd);
977 void brcl(Condition m, const Operand& opnd, bool isCodeTarget = false);
978 void brct(Register r1, const Operand& opnd);
979 void brctg(Register r1, const Operand& opnd);
980
981 // 32-bit Add Instructions
982 void a(Register r1, const MemOperand& opnd);
983 void ay(Register r1, const MemOperand& opnd);
984 void afi(Register r1, const Operand& opnd);
985 void ah(Register r1, const MemOperand& opnd);
986 void ahy(Register r1, const MemOperand& opnd);
987 void ahi(Register r1, const Operand& opnd);
988 void ahik(Register r1, Register r3, const Operand& opnd);
989 void ar(Register r1, Register r2);
990 void ark(Register r1, Register r2, Register r3);
991 void asi(const MemOperand&, const Operand&);
992
993 // 64-bit Add Instructions
994 void ag(Register r1, const MemOperand& opnd);
995 void agf(Register r1, const MemOperand& opnd);
996 void agfi(Register r1, const Operand& opnd);
997 void agfr(Register r1, Register r2);
998 void aghi(Register r1, const Operand& opnd);
999 void aghik(Register r1, Register r3, const Operand& opnd);
1000 void agr(Register r1, Register r2);
1001 void agrk(Register r1, Register r2, Register r3);
1002 void agsi(const MemOperand&, const Operand&);
1003
1004 // 32-bit Add Logical Instructions
1005 void al_z(Register r1, const MemOperand& opnd);
1006 void aly(Register r1, const MemOperand& opnd);
1007 void alfi(Register r1, const Operand& opnd);
1008 void alr(Register r1, Register r2);
1009 void alcr(Register r1, Register r2);
1010 void alrk(Register r1, Register r2, Register r3);
1011
1012 // 64-bit Add Logical Instructions
1013 void alg(Register r1, const MemOperand& opnd);
1014 void algfi(Register r1, const Operand& opnd);
1015 void algr(Register r1, Register r2);
1016 void algrk(Register r1, Register r2, Register r3);
1017
1018 // 32-bit Subtract Instructions
1019 void s(Register r1, const MemOperand& opnd);
1020 void sy(Register r1, const MemOperand& opnd);
1021 void sh(Register r1, const MemOperand& opnd);
1022 void shy(Register r1, const MemOperand& opnd);
1023 void sr(Register r1, Register r2);
1024 void srk(Register r1, Register r2, Register r3);
1025
1026 // 64-bit Subtract Instructions
1027 void sg(Register r1, const MemOperand& opnd);
1028 void sgf(Register r1, const MemOperand& opnd);
1029 void sgr(Register r1, Register r2);
1030 void sgfr(Register r1, Register r2);
1031 void sgrk(Register r1, Register r2, Register r3);
1032
1033 // 32-bit Subtract Logical Instructions
1034 void sl(Register r1, const MemOperand& opnd);
1035 void sly(Register r1, const MemOperand& opnd);
1036 void slr(Register r1, Register r2);
1037 void slrk(Register r1, Register r2, Register r3);
1038 void slbr(Register r1, Register r2);
1039
1040 // 64-bit Subtract Logical Instructions
1041 void slg(Register r1, const MemOperand& opnd);
1042 void slgr(Register r1, Register r2);
1043 void slgrk(Register r1, Register r2, Register r3);
1044
1045 // 32-bit Multiply Instructions
1046 void m(Register r1, const MemOperand& opnd);
1047 void mr_z(Register r1, Register r2);
1048 void ml(Register r1, const MemOperand& opnd);
1049 void mlr(Register r1, Register r2);
1050 void ms(Register r1, const MemOperand& opnd);
1051 void msy(Register r1, const MemOperand& opnd);
1052 void msfi(Register r1, const Operand& opnd);
1053 void msr(Register r1, Register r2);
1054 void mh(Register r1, const MemOperand& opnd);
1055 void mhy(Register r1, const MemOperand& opnd);
1056 void mhi(Register r1, const Operand& opnd);
1057
1058 // 64-bit Multiply Instructions
1059 void mlg(Register r1, const MemOperand& opnd);
1060 void mlgr(Register r1, Register r2);
1061 void mghi(Register r1, const Operand& opnd);
1062 void msgfi(Register r1, const Operand& opnd);
1063 void msg(Register r1, const MemOperand& opnd);
1064 void msgr(Register r1, Register r2);
1065
1066 // 32-bit Divide Instructions
1067 void d(Register r1, const MemOperand& opnd);
1068 void dr(Register r1, Register r2);
1069 void dl(Register r1, const MemOperand& opnd);
1070 void dlr(Register r1, Register r2);
1071
1072 // 64-bit Divide Instructions
1073 void dlgr(Register r1, Register r2);
1074 void dsgr(Register r1, Register r2);
1075
1076 // Bitwise Instructions (AND / OR / XOR)
1077 void n(Register r1, const MemOperand& opnd);
1078 void ny(Register r1, const MemOperand& opnd);
1079 void nr(Register r1, Register r2);
1080 void nrk(Register r1, Register r2, Register r3);
1081 void ng(Register r1, const MemOperand& opnd);
1082 void ngr(Register r1, Register r2);
1083 void ngrk(Register r1, Register r2, Register r3);
1084 void o(Register r1, const MemOperand& opnd);
1085 void oy(Register r1, const MemOperand& opnd);
1086 void or_z(Register r1, Register r2);
1087 void ork(Register r1, Register r2, Register r3);
1088 void og(Register r1, const MemOperand& opnd);
1089 void ogr(Register r1, Register r2);
1090 void ogrk(Register r1, Register r2, Register r3);
1091 void x(Register r1, const MemOperand& opnd);
1092 void xy(Register r1, const MemOperand& opnd);
1093 void xr(Register r1, Register r2);
1094 void xrk(Register r1, Register r2, Register r3);
1095 void xg(Register r1, const MemOperand& opnd);
1096 void xgr(Register r1, Register r2);
1097 void xgrk(Register r1, Register r2, Register r3);
1098 void xc(const MemOperand& opnd1, const MemOperand& opnd2, Length length);
1099
1100 // Bitwise GPR <-> FPR Conversion Instructions
1101 void lgdr(Register r1, DoubleRegister f2);
1102 void ldgr(DoubleRegister f1, Register r2);
1103
1104 // Floating Point Load / Store Instructions
1105 void ld(DoubleRegister r1, const MemOperand& opnd);
1106 void ldy(DoubleRegister r1, const MemOperand& opnd);
1107 void le_z(DoubleRegister r1, const MemOperand& opnd);
1108 void ley(DoubleRegister r1, const MemOperand& opnd);
1109 void ldr(DoubleRegister r1, DoubleRegister r2);
1110 void ltdbr(DoubleRegister r1, DoubleRegister r2);
1111 void ltebr(DoubleRegister r1, DoubleRegister r2);
1112 void std(DoubleRegister r1, const MemOperand& opnd);
1113 void stdy(DoubleRegister r1, const MemOperand& opnd);
1114 void ste(DoubleRegister r1, const MemOperand& opnd);
1115 void stey(DoubleRegister r1, const MemOperand& opnd);
1116
1117 // Floating Point Load Rounded/Positive Instructions
1118 void ledbr(DoubleRegister r1, DoubleRegister r2);
1119 void ldebr(DoubleRegister r1, DoubleRegister r2);
1120 void lpebr(DoubleRegister r1, DoubleRegister r2);
1121 void lpdbr(DoubleRegister r1, DoubleRegister r2);
1122
1123 // Floating <-> Fixed Point Conversion Instructions
1124 void cdlfbr(Condition m3, Condition m4, DoubleRegister fltReg,
1125 Register fixReg);
1126 void cdlgbr(Condition m3, Condition m4, DoubleRegister fltReg,
1127 Register fixReg);
1128 void celgbr(Condition m3, Condition m4, DoubleRegister fltReg,
1129 Register fixReg);
1130 void celfbr(Condition m3, Condition m4, DoubleRegister fltReg,
1131 Register fixReg);
1132 void clfdbr(Condition m3, Condition m4, Register fixReg,
1133 DoubleRegister fltReg);
1134 void clfebr(Condition m3, Condition m4, Register fixReg,
1135 DoubleRegister fltReg);
1136 void clgdbr(Condition m3, Condition m4, Register fixReg,
1137 DoubleRegister fltReg);
1138 void clgebr(Condition m3, Condition m4, Register fixReg,
1139 DoubleRegister fltReg);
1140 void cfdbr(Condition m, Register fixReg, DoubleRegister fltReg);
1141 void cdfbr(DoubleRegister fltReg, Register fixReg);
1142 void cgebr(Condition m, Register fixReg, DoubleRegister fltReg);
1143 void cgdbr(Condition m, Register fixReg, DoubleRegister fltReg);
1144 void cegbr(DoubleRegister fltReg, Register fixReg);
1145 void cdgbr(DoubleRegister fltReg, Register fixReg);
1146 void cfebr(Condition m3, Register fixReg, DoubleRegister fltReg);
1147 void cefbr(DoubleRegister fltReg, Register fixReg);
1148
1149 // Floating Point Compare Instructions
1150 void cebr(DoubleRegister r1, DoubleRegister r2);
1151 void cdb(DoubleRegister r1, const MemOperand& opnd);
1152 void cdbr(DoubleRegister r1, DoubleRegister r2);
1153
1154 // Floating Point Arithmetic Instructions
1155 void aebr(DoubleRegister r1, DoubleRegister r2);
1156 void adb(DoubleRegister r1, const MemOperand& opnd);
1157 void adbr(DoubleRegister r1, DoubleRegister r2);
1158 void lzdr(DoubleRegister r1);
1159 void sebr(DoubleRegister r1, DoubleRegister r2);
1160 void sdb(DoubleRegister r1, const MemOperand& opnd);
1161 void sdbr(DoubleRegister r1, DoubleRegister r2);
1162 void meebr(DoubleRegister r1, DoubleRegister r2);
1163 void mdb(DoubleRegister r1, const MemOperand& opnd);
1164 void mdbr(DoubleRegister r1, DoubleRegister r2);
1165 void debr(DoubleRegister r1, DoubleRegister r2);
1166 void ddb(DoubleRegister r1, const MemOperand& opnd);
1167 void ddbr(DoubleRegister r1, DoubleRegister r2);
1168 void madbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3);
1169 void msdbr(DoubleRegister r1, DoubleRegister r2, DoubleRegister r3);
1170 void sqebr(DoubleRegister r1, DoubleRegister r2);
1171 void sqdb(DoubleRegister r1, const MemOperand& opnd);
1172 void sqdbr(DoubleRegister r1, DoubleRegister r2);
1173 void lcdbr(DoubleRegister r1, DoubleRegister r2);
1174 void ldeb(DoubleRegister r1, const MemOperand& opnd);
1175
1176 enum FIDBRA_MASK3 {
1177 FIDBRA_CURRENT_ROUNDING_MODE = 0,
1178 FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0 = 1,
1179 // ...
1180 FIDBRA_ROUND_TOWARD_0 = 5,
1181 FIDBRA_ROUND_TOWARD_POS_INF = 6,
1182 FIDBRA_ROUND_TOWARD_NEG_INF = 7
1183 };
1184 void fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3);
1185 void fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3);
1186
1187 // Move integer
1188 void mvhi(const MemOperand& opnd1, const Operand& i2);
1189 void mvghi(const MemOperand& opnd1, const Operand& i2);
1190
1191 // Exception-generating instructions and debugging support
1192 void stop(const char* msg, Condition cond = al,
1193 int32_t code = kDefaultStopCode, CRegister cr = cr7);
1194
1195 void bkpt(uint32_t imm16); // v5 and above
1196
1197 // Different nop operations are used by the code generator to detect certain
1198 // states of the generated code.
1199 enum NopMarkerTypes {
1200 NON_MARKING_NOP = 0,
1201 GROUP_ENDING_NOP,
1202 DEBUG_BREAK_NOP,
1203 // IC markers.
1204 PROPERTY_ACCESS_INLINED,
1205 PROPERTY_ACCESS_INLINED_CONTEXT,
1206 PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
1207 // Helper values.
1208 LAST_CODE_MARKER,
1209 FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
1210 };
1211
1212 void nop(int type = 0); // 0 is the default non-marking type.
1213
1214 // Check the code size generated from label to here.
1215 int SizeOfCodeGeneratedSince(Label* label) {
1216 return pc_offset() - label->pos();
1217 }
1218
1219 // Debugging
1220
1221 // Mark generator continuation.
1222 void RecordGeneratorContinuation();
1223
1224 // Mark address of a debug break slot.
1225 void RecordDebugBreakSlot(RelocInfo::Mode mode);
1226
1227 // Record the AST id of the CallIC being compiled, so that it can be placed
1228 // in the relocation information.
1229 void SetRecordedAstId(TypeFeedbackId ast_id) { recorded_ast_id_ = ast_id; }
1230
1231 TypeFeedbackId RecordedAstId() {
1232 // roohack - another issue??? DCHECK(!recorded_ast_id_.IsNone());
1233 return recorded_ast_id_;
1234 }
1235
1236 void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
1237
1238 // Record a comment relocation entry that can be used by a disassembler.
1239 // Use --code-comments to enable.
1240 void RecordComment(const char* msg);
1241
1242 // Record a deoptimization reason that can be used by a log or cpu profiler.
1243 // Use --trace-deopt to enable.
1244 void RecordDeoptReason(const int reason, int raw_position);
1245
1246 // Writes a single byte or word of data in the code stream. Used
1247 // for inline tables, e.g., jump-tables.
1248 void db(uint8_t data);
1249 void dd(uint32_t data);
1250 void dq(uint64_t data);
1251 void dp(uintptr_t data);
1252
1253 AssemblerPositionsRecorder* positions_recorder() {
1254 return &positions_recorder_;
1255 }
1256
1257 void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1258 ConstantPoolEntry::Access access,
1259 ConstantPoolEntry::Type type) {
1260 // No embedded constant pool support.
1261 UNREACHABLE();
1262 }
1263
1264 // Read/patch instructions
1265 SixByteInstr instr_at(int pos) {
1266 return Instruction::InstructionBits(buffer_ + pos);
1267 }
1268 template <typename T>
1269 void instr_at_put(int pos, T instr) {
1270 Instruction::SetInstructionBits<T>(buffer_ + pos, instr);
1271 }
1272
1273 // Decodes instruction at pos, and returns its length
1274 int32_t instr_length_at(int pos) {
1275 return Instruction::InstructionLength(buffer_ + pos);
1276 }
1277
1278 static SixByteInstr instr_at(byte* pc) {
1279 return Instruction::InstructionBits(pc);
1280 }
1281
1282 static Condition GetCondition(Instr instr);
1283
1284 static bool IsBranch(Instr instr);
1285#if V8_TARGET_ARCH_S390X
1286 static bool Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2);
1287#else
1288 static bool Is32BitLoadIntoIP(SixByteInstr instr);
1289#endif
1290
1291 static bool IsCmpRegister(Instr instr);
1292 static bool IsCmpImmediate(Instr instr);
1293 static bool IsNop(SixByteInstr instr, int type = NON_MARKING_NOP);
1294
1295 // The code currently calls CheckBuffer() too often. This has the side
1296 // effect of randomly growing the buffer in the middle of multi-instruction
1297 // sequences.
1298 //
1299 // This function allows outside callers to check and grow the buffer
1300 void EnsureSpaceFor(int space_needed);
1301
1302 void EmitRelocations();
1303 void emit_label_addr(Label* label);
1304
1305 public:
1306 byte* buffer_pos() const { return buffer_; }
1307
1308 protected:
1309 // Relocation for a type-recording IC has the AST id added to it. This
1310 // member variable is a way to pass the information from the call site to
1311 // the relocation info.
1312 TypeFeedbackId recorded_ast_id_;
1313
1314 int buffer_space() const { return reloc_info_writer.pos() - pc_; }
1315
1316 // Decode instruction(s) at pos and return backchain to previous
1317 // label reference or kEndOfChain.
1318 int target_at(int pos);
1319
1320 // Patch instruction(s) at pos to target target_pos (e.g. branch)
1321 void target_at_put(int pos, int target_pos, bool* is_branch = nullptr);
1322
1323 // Record reloc info for current pc_
1324 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1325
1326 private:
1327 // Code generation
1328 // The relocation writer's position is at least kGap bytes below the end of
1329 // the generated instructions. This is so that multi-instruction sequences do
1330 // not have to check for overflow. The same is true for writes of large
1331 // relocation info entries.
1332 static const int kGap = 32;
1333
1334 // Relocation info generation
1335 // Each relocation is encoded as a variable size value
1336 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1337 RelocInfoWriter reloc_info_writer;
1338 std::vector<DeferredRelocInfo> relocations_;
1339
1340 // The bound position, before this we cannot do instruction elimination.
1341 int last_bound_pos_;
1342
1343 // Code emission
1344 inline void CheckBuffer();
1345 void GrowBuffer(int needed = 0);
1346 inline void TrackBranch();
1347 inline void UntrackBranch();
1348
1349 inline int32_t emit_code_target(
1350 Handle<Code> target, RelocInfo::Mode rmode,
1351 TypeFeedbackId ast_id = TypeFeedbackId::None());
1352
1353 // Helpers to emit binary encoding of 2/4/6 byte instructions.
1354 inline void emit2bytes(uint16_t x);
1355 inline void emit4bytes(uint32_t x);
1356 inline void emit6bytes(uint64_t x);
1357
1358 // Helpers to emit binary encoding for various instruction formats.
1359
1360 inline void rr_form(Opcode op, Register r1, Register r2);
1361 inline void rr_form(Opcode op, DoubleRegister r1, DoubleRegister r2);
1362 inline void rr_form(Opcode op, Condition m1, Register r2);
1363 inline void rr2_form(uint8_t op, Condition m1, Register r2);
1364
1365 inline void rx_form(Opcode op, Register r1, Register x2, Register b2,
1366 Disp d2);
1367 inline void rx_form(Opcode op, DoubleRegister r1, Register x2, Register b2,
1368 Disp d2);
1369
1370 inline void ri_form(Opcode op, Register r1, const Operand& i2);
1371 inline void ri_form(Opcode op, Condition m1, const Operand& i2);
1372
1373 inline void rie_form(Opcode op, Register r1, Register r3, const Operand& i2);
1374 inline void rie_f_form(Opcode op, Register r1, Register r2, const Operand& i3,
1375 const Operand& i4, const Operand& i5);
1376
1377 inline void ril_form(Opcode op, Register r1, const Operand& i2);
1378 inline void ril_form(Opcode op, Condition m1, const Operand& i2);
1379
1380 inline void ris_form(Opcode op, Register r1, Condition m3, Register b4,
1381 Disp d4, const Operand& i2);
1382
1383 inline void rrd_form(Opcode op, Register r1, Register r3, Register r2);
1384
1385 inline void rre_form(Opcode op, Register r1, Register r2);
1386 inline void rre_form(Opcode op, DoubleRegister r1, DoubleRegister r2);
1387
1388 inline void rrf1_form(Opcode op, Register r1, Register r2, Register r3);
1389 inline void rrf1_form(uint32_t x);
1390 inline void rrf2_form(uint32_t x);
1391 inline void rrf3_form(uint32_t x);
1392 inline void rrfe_form(Opcode op, Condition m3, Condition m4, Register r1,
1393 Register r2);
1394
1395 inline void rrs_form(Opcode op, Register r1, Register r2, Register b4,
1396 Disp d4, Condition m3);
1397
1398 inline void rs_form(Opcode op, Register r1, Condition m3, Register b2,
1399 const Disp d2);
1400 inline void rs_form(Opcode op, Register r1, Register r3, Register b2,
1401 const Disp d2);
1402
1403 inline void rsi_form(Opcode op, Register r1, Register r3, const Operand& i2);
1404 inline void rsl_form(Opcode op, Length l1, Register b2, Disp d2);
1405
1406 inline void rsy_form(Opcode op, Register r1, Register r3, Register b2,
1407 const Disp d2);
1408 inline void rsy_form(Opcode op, Register r1, Condition m3, Register b2,
1409 const Disp d2);
1410
1411 inline void rxe_form(Opcode op, Register r1, Register x2, Register b2,
1412 Disp d2);
1413
1414 inline void rxf_form(Opcode op, Register r1, Register r3, Register b2,
1415 Register x2, Disp d2);
1416
1417 inline void rxy_form(Opcode op, Register r1, Register x2, Register b2,
1418 Disp d2);
1419 inline void rxy_form(Opcode op, DoubleRegister r1, Register x2, Register b2,
1420 Disp d2);
1421
1422 inline void s_form(Opcode op, Register b1, Disp d2);
1423
1424 inline void si_form(Opcode op, const Operand& i2, Register b1, Disp d1);
1425 inline void siy_form(Opcode op, const Operand& i2, Register b1, Disp d1);
1426
1427 inline void sil_form(Opcode op, Register b1, Disp d1, const Operand& i2);
1428
1429 inline void ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2,
1430 Disp d2);
1431 inline void ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1,
1432 Register b2, Disp d2);
1433 inline void ss_form(Opcode op, Length l1, const Operand& i3, Register b1,
1434 Disp d1, Register b2, Disp d2);
1435 inline void ss_form(Opcode op, Register r1, Register r2, Register b1, Disp d1,
1436 Register b2, Disp d2);
1437 inline void sse_form(Opcode op, Register b1, Disp d1, Register b2, Disp d2);
1438 inline void ssf_form(Opcode op, Register r3, Register b1, Disp d1,
1439 Register b2, Disp d2);
1440
1441 // Labels
1442 void print(Label* L);
1443 int max_reach_from(int pos);
1444 void bind_to(Label* L, int pos);
1445 void next(Label* L);
1446
1447 friend class RegExpMacroAssemblerS390;
1448 friend class RelocInfo;
1449 friend class CodePatcher;
1450
1451 List<Handle<Code> > code_targets_;
1452
1453 AssemblerPositionsRecorder positions_recorder_;
1454 friend class AssemblerPositionsRecorder;
1455 friend class EnsureSpace;
1456};
1457
1458class EnsureSpace BASE_EMBEDDED {
1459 public:
1460 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1461};
1462
1463} // namespace internal
1464} // namespace v8
1465
1466#endif // V8_S390_ASSEMBLER_S390_H_