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