Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: src/s390/assembler-s390.h

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

Powered by Google App Engine
This is Rietveld 408576698