1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions
6 // are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the
14 // distribution.
15 //
16 // - Neither the name of Sun Microsystems or the names of contributors may
17 // be used to endorse or promote products derived from this software without
18 // specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 // The original source code covered by the above license above has been
34 // modified significantly by Google Inc.
35 // Copyright 2014 the V8 project authors. All rights reserved.
36
37 #include "src/s390/assembler-s390.h"
38
39 #if V8_TARGET_ARCH_S390
40
41 #if V8_HOST_ARCH_S390
42 #include <elf.h> // Required for auxv checks for STFLE support
43 #endif
44
45 #include "src/base/bits.h"
46 #include "src/base/cpu.h"
47 #include "src/s390/assembler-s390-inl.h"
48
49 #include "src/macro-assembler.h"
50
51 namespace v8 {
52 namespace internal {
53
54 // Get the CPU features enabled by the build.
CpuFeaturesImpliedByCompiler()55 static unsigned CpuFeaturesImpliedByCompiler() {
56 unsigned answer = 0;
57 return answer;
58 }
59
60 // Check whether Store Facility STFLE instruction is available on the platform.
61 // Instruction returns a bit vector of the enabled hardware facilities.
supportsSTFLE()62 static bool supportsSTFLE() {
63 #if V8_HOST_ARCH_S390
64 static bool read_tried = false;
65 static uint32_t auxv_hwcap = 0;
66
67 if (!read_tried) {
68 // Open the AUXV (auxilliary vector) psuedo-file
69 int fd = open("/proc/self/auxv", O_RDONLY);
70
71 read_tried = true;
72 if (fd != -1) {
73 #if V8_TARGET_ARCH_S390X
74 static Elf64_auxv_t buffer[16];
75 Elf64_auxv_t* auxv_element;
76 #else
77 static Elf32_auxv_t buffer[16];
78 Elf32_auxv_t* auxv_element;
79 #endif
80 int bytes_read = 0;
81 while (bytes_read >= 0) {
82 // Read a chunk of the AUXV
83 bytes_read = read(fd, buffer, sizeof(buffer));
84 // Locate and read the platform field of AUXV if it is in the chunk
85 for (auxv_element = buffer;
86 auxv_element + sizeof(auxv_element) <= buffer + bytes_read &&
87 auxv_element->a_type != AT_NULL;
88 auxv_element++) {
89 // We are looking for HWCAP entry in AUXV to search for STFLE support
90 if (auxv_element->a_type == AT_HWCAP) {
91 /* Note: Both auxv_hwcap and buffer are static */
92 auxv_hwcap = auxv_element->a_un.a_val;
93 goto done_reading;
94 }
95 }
96 }
97 done_reading:
98 close(fd);
99 }
100 }
101
102 // Did not find result
103 if (0 == auxv_hwcap) {
104 return false;
105 }
106
107 // HWCAP_S390_STFLE is defined to be 4 in include/asm/elf.h. Currently
108 // hardcoded in case that include file does not exist.
109 const uint32_t HWCAP_S390_STFLE = 4;
110 return (auxv_hwcap & HWCAP_S390_STFLE);
111 #else
112 // STFLE is not available on non-s390 hosts
113 return false;
114 #endif
115 }
116
ProbeImpl(bool cross_compile)117 void CpuFeatures::ProbeImpl(bool cross_compile) {
118 supported_ |= CpuFeaturesImpliedByCompiler();
119 icache_line_size_ = 256;
120
121 // Only use statically determined features for cross compile (snapshot).
122 if (cross_compile) return;
123
124 #ifdef DEBUG
125 initialized_ = true;
126 #endif
127
128 static bool performSTFLE = supportsSTFLE();
129
130 // Need to define host, as we are generating inlined S390 assembly to test
131 // for facilities.
132 #if V8_HOST_ARCH_S390
133 if (performSTFLE) {
134 // STFLE D(B) requires:
135 // GPR0 to specify # of double words to update minus 1.
136 // i.e. GPR0 = 0 for 1 doubleword
137 // D(B) to specify to memory location to store the facilities bits
138 // The facilities we are checking for are:
139 // Bit 45 - Distinct Operands for instructions like ARK, SRK, etc.
140 // As such, we require only 1 double word
141 int64_t facilities[3] = {0L};
142 // LHI sets up GPR0
143 // STFLE is specified as .insn, as opcode is not recognized.
144 // We register the instructions kill r0 (LHI) and the CC (STFLE).
145 asm volatile(
146 "lhi 0,2\n"
147 ".insn s,0xb2b00000,%0\n"
148 : "=Q"(facilities)
149 :
150 : "cc", "r0");
151
152 uint64_t one = static_cast<uint64_t>(1);
153 // Test for Distinct Operands Facility - Bit 45
154 if (facilities[0] & (one << (63 - 45))) {
155 supported_ |= (1u << DISTINCT_OPS);
156 }
157 // Test for General Instruction Extension Facility - Bit 34
158 if (facilities[0] & (one << (63 - 34))) {
159 supported_ |= (1u << GENERAL_INSTR_EXT);
160 }
161 // Test for Floating Point Extension Facility - Bit 37
162 if (facilities[0] & (one << (63 - 37))) {
163 supported_ |= (1u << FLOATING_POINT_EXT);
164 }
165 // Test for Vector Facility - Bit 129
166 if (facilities[2] & (one << (63 - (129 - 128)))) {
167 supported_ |= (1u << VECTOR_FACILITY);
168 }
169 // Test for Miscellaneous Instruction Extension Facility - Bit 58
170 if (facilities[0] & (1lu << (63 - 58))) {
171 supported_ |= (1u << MISC_INSTR_EXT2);
172 }
173 }
174 #else
175 // All distinct ops instructions can be simulated
176 supported_ |= (1u << DISTINCT_OPS);
177 // RISBG can be simulated
178 supported_ |= (1u << GENERAL_INSTR_EXT);
179 supported_ |= (1u << FLOATING_POINT_EXT);
180 supported_ |= (1u << MISC_INSTR_EXT2);
181 USE(performSTFLE); // To avoid assert
182 supported_ |= (1u << VECTOR_FACILITY);
183 #endif
184 supported_ |= (1u << FPU);
185 }
186
PrintTarget()187 void CpuFeatures::PrintTarget() {
188 const char* s390_arch = NULL;
189
190 #if V8_TARGET_ARCH_S390X
191 s390_arch = "s390x";
192 #else
193 s390_arch = "s390";
194 #endif
195
196 printf("target %s\n", s390_arch);
197 }
198
PrintFeatures()199 void CpuFeatures::PrintFeatures() {
200 printf("FPU=%d\n", CpuFeatures::IsSupported(FPU));
201 printf("FPU_EXT=%d\n", CpuFeatures::IsSupported(FLOATING_POINT_EXT));
202 printf("GENERAL_INSTR=%d\n", CpuFeatures::IsSupported(GENERAL_INSTR_EXT));
203 printf("DISTINCT_OPS=%d\n", CpuFeatures::IsSupported(DISTINCT_OPS));
204 printf("VECTOR_FACILITY=%d\n", CpuFeatures::IsSupported(VECTOR_FACILITY));
205 printf("MISC_INSTR_EXT2=%d\n", CpuFeatures::IsSupported(MISC_INSTR_EXT2));
206 }
207
ToRegister(int num)208 Register ToRegister(int num) {
209 DCHECK(num >= 0 && num < kNumRegisters);
210 const Register kRegisters[] = {r0, r1, r2, r3, r4, r5, r6, r7,
211 r8, r9, r10, fp, ip, r13, r14, sp};
212 return kRegisters[num];
213 }
214
215 // -----------------------------------------------------------------------------
216 // Implementation of RelocInfo
217
218 const int RelocInfo::kApplyMask =
219 RelocInfo::kCodeTargetMask | 1 << RelocInfo::INTERNAL_REFERENCE;
220
IsCodedSpecially()221 bool RelocInfo::IsCodedSpecially() {
222 // The deserializer needs to know whether a pointer is specially
223 // coded. Being specially coded on S390 means that it is an iihf/iilf
224 // instruction sequence, and that is always the case inside code
225 // objects.
226 return true;
227 }
228
IsInConstantPool()229 bool RelocInfo::IsInConstantPool() { return false; }
230
wasm_memory_reference()231 Address RelocInfo::wasm_memory_reference() {
232 DCHECK(IsWasmMemoryReference(rmode_));
233 return Assembler::target_address_at(pc_, host_);
234 }
235
wasm_memory_size_reference()236 uint32_t RelocInfo::wasm_memory_size_reference() {
237 DCHECK(IsWasmMemorySizeReference(rmode_));
238 return static_cast<uint32_t>(
239 reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_)));
240 }
241
wasm_global_reference()242 Address RelocInfo::wasm_global_reference() {
243 DCHECK(IsWasmGlobalReference(rmode_));
244 return Assembler::target_address_at(pc_, host_);
245 }
246
wasm_function_table_size_reference()247 uint32_t RelocInfo::wasm_function_table_size_reference() {
248 DCHECK(IsWasmFunctionTableSizeReference(rmode_));
249 return static_cast<uint32_t>(
250 reinterpret_cast<intptr_t>(Assembler::target_address_at(pc_, host_)));
251 }
252
unchecked_update_wasm_memory_reference(Address address,ICacheFlushMode flush_mode)253 void RelocInfo::unchecked_update_wasm_memory_reference(
254 Address address, ICacheFlushMode flush_mode) {
255 Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode);
256 }
257
unchecked_update_wasm_size(uint32_t size,ICacheFlushMode flush_mode)258 void RelocInfo::unchecked_update_wasm_size(uint32_t size,
259 ICacheFlushMode flush_mode) {
260 Assembler::set_target_address_at(isolate_, pc_, host_,
261 reinterpret_cast<Address>(size), flush_mode);
262 }
263
264 // -----------------------------------------------------------------------------
265 // Implementation of Operand and MemOperand
266 // See assembler-s390-inl.h for inlined constructors
267
Operand(Handle<Object> handle)268 Operand::Operand(Handle<Object> handle) {
269 AllowDeferredHandleDereference using_raw_address;
270 rm_ = no_reg;
271 // Verify all Objects referred by code are NOT in new space.
272 Object* obj = *handle;
273 if (obj->IsHeapObject()) {
274 imm_ = reinterpret_cast<intptr_t>(handle.location());
275 rmode_ = RelocInfo::EMBEDDED_OBJECT;
276 } else {
277 // no relocation needed
278 imm_ = reinterpret_cast<intptr_t>(obj);
279 rmode_ = kRelocInfo_NONEPTR;
280 }
281 }
282
MemOperand(Register rn,int32_t offset)283 MemOperand::MemOperand(Register rn, int32_t offset) {
284 baseRegister = rn;
285 indexRegister = r0;
286 offset_ = offset;
287 }
288
MemOperand(Register rx,Register rb,int32_t offset)289 MemOperand::MemOperand(Register rx, Register rb, int32_t offset) {
290 baseRegister = rb;
291 indexRegister = rx;
292 offset_ = offset;
293 }
294
295 // -----------------------------------------------------------------------------
296 // Specific instructions, constants, and masks.
297
Assembler(Isolate * isolate,void * buffer,int buffer_size)298 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
299 : AssemblerBase(isolate, buffer, buffer_size),
300 recorded_ast_id_(TypeFeedbackId::None()),
301 code_targets_(100) {
302 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
303
304 last_bound_pos_ = 0;
305 ClearRecordedAstId();
306 relocations_.reserve(128);
307 }
308
GetCode(CodeDesc * desc)309 void Assembler::GetCode(CodeDesc* desc) {
310 EmitRelocations();
311
312 // Set up code descriptor.
313 desc->buffer = buffer_;
314 desc->buffer_size = buffer_size_;
315 desc->instr_size = pc_offset();
316 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
317 desc->origin = this;
318 desc->unwinding_info_size = 0;
319 desc->unwinding_info = nullptr;
320 }
321
Align(int m)322 void Assembler::Align(int m) {
323 DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
324 while ((pc_offset() & (m - 1)) != 0) {
325 nop(0);
326 }
327 }
328
CodeTargetAlign()329 void Assembler::CodeTargetAlign() { Align(8); }
330
GetCondition(Instr instr)331 Condition Assembler::GetCondition(Instr instr) {
332 switch (instr & kCondMask) {
333 case BT:
334 return eq;
335 case BF:
336 return ne;
337 default:
338 UNIMPLEMENTED();
339 }
340 return al;
341 }
342
343 #if V8_TARGET_ARCH_S390X
344 // This code assumes a FIXED_SEQUENCE for 64bit loads (iihf/iilf)
Is64BitLoadIntoIP(SixByteInstr instr1,SixByteInstr instr2)345 bool Assembler::Is64BitLoadIntoIP(SixByteInstr instr1, SixByteInstr instr2) {
346 // Check the instructions are the iihf/iilf load into ip
347 return (((instr1 >> 32) == 0xC0C8) && ((instr2 >> 32) == 0xC0C9));
348 }
349 #else
350 // This code assumes a FIXED_SEQUENCE for 32bit loads (iilf)
Is32BitLoadIntoIP(SixByteInstr instr)351 bool Assembler::Is32BitLoadIntoIP(SixByteInstr instr) {
352 // Check the instruction is an iilf load into ip/r12.
353 return ((instr >> 32) == 0xC0C9);
354 }
355 #endif
356
357 // Labels refer to positions in the (to be) generated code.
358 // There are bound, linked, and unused labels.
359 //
360 // Bound labels refer to known positions in the already
361 // generated code. pos() is the position the label refers to.
362 //
363 // Linked labels refer to unknown positions in the code
364 // to be generated; pos() is the position of the last
365 // instruction using the label.
366
367 // The link chain is terminated by a negative code position (must be aligned)
368 const int kEndOfChain = -4;
369
370 // Returns the target address of the relative instructions, typically
371 // of the form: pos + imm (where immediate is in # of halfwords for
372 // BR* and LARL).
target_at(int pos)373 int Assembler::target_at(int pos) {
374 SixByteInstr instr = instr_at(pos);
375 // check which type of branch this is 16 or 26 bit offset
376 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos);
377
378 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
379 int16_t imm16 = SIGN_EXT_IMM16((instr & kImm16Mask));
380 imm16 <<= 1; // BRC immediate is in # of halfwords
381 if (imm16 == 0) return kEndOfChain;
382 return pos + imm16;
383 } else if (LLILF == opcode || BRCL == opcode || LARL == opcode ||
384 BRASL == opcode) {
385 int32_t imm32 =
386 static_cast<int32_t>(instr & (static_cast<uint64_t>(0xffffffff)));
387 if (LLILF != opcode)
388 imm32 <<= 1; // BR* + LARL treat immediate in # of halfwords
389 if (imm32 == 0) return kEndOfChain;
390 return pos + imm32;
391 }
392
393 // Unknown condition
394 DCHECK(false);
395 return -1;
396 }
397
398 // Update the target address of the current relative instruction.
target_at_put(int pos,int target_pos,bool * is_branch)399 void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
400 SixByteInstr instr = instr_at(pos);
401 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos);
402
403 if (is_branch != nullptr) {
404 *is_branch = (opcode == BRC || opcode == BRCT || opcode == BRCTG ||
405 opcode == BRCL || opcode == BRASL);
406 }
407
408 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
409 int16_t imm16 = target_pos - pos;
410 instr &= (~0xffff);
411 DCHECK(is_int16(imm16));
412 instr_at_put<FourByteInstr>(pos, instr | (imm16 >> 1));
413 return;
414 } else if (BRCL == opcode || LARL == opcode || BRASL == opcode) {
415 // Immediate is in # of halfwords
416 int32_t imm32 = target_pos - pos;
417 instr &= (~static_cast<uint64_t>(0xffffffff));
418 instr_at_put<SixByteInstr>(pos, instr | (imm32 >> 1));
419 return;
420 } else if (LLILF == opcode) {
421 DCHECK(target_pos == kEndOfChain || target_pos >= 0);
422 // Emitted label constant, not part of a branch.
423 // Make label relative to Code* of generated Code object.
424 int32_t imm32 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
425 instr &= (~static_cast<uint64_t>(0xffffffff));
426 instr_at_put<SixByteInstr>(pos, instr | imm32);
427 return;
428 }
429 DCHECK(false);
430 }
431
432 // Returns the maximum number of bits given instruction can address.
max_reach_from(int pos)433 int Assembler::max_reach_from(int pos) {
434 Opcode opcode = Instruction::S390OpcodeValue(buffer_ + pos);
435
436 // Check which type of instr. In theory, we can return
437 // the values below + 1, given offset is # of halfwords
438 if (BRC == opcode || BRCT == opcode || BRCTG == opcode) {
439 return 16;
440 } else if (LLILF == opcode || BRCL == opcode || LARL == opcode ||
441 BRASL == opcode) {
442 return 31; // Using 31 as workaround instead of 32 as
443 // is_intn(x,32) doesn't work on 32-bit platforms.
444 // llilf: Emitted label constant, not part of
445 // a branch (regexp PushBacktrack).
446 }
447 DCHECK(false);
448 return 16;
449 }
450
bind_to(Label * L,int pos)451 void Assembler::bind_to(Label* L, int pos) {
452 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
453 bool is_branch = false;
454 while (L->is_linked()) {
455 int fixup_pos = L->pos();
456 #ifdef DEBUG
457 int32_t offset = pos - fixup_pos;
458 int maxReach = max_reach_from(fixup_pos);
459 #endif
460 next(L); // call next before overwriting link with target at fixup_pos
461 DCHECK(is_intn(offset, maxReach));
462 target_at_put(fixup_pos, pos, &is_branch);
463 }
464 L->bind_to(pos);
465
466 // Keep track of the last bound label so we don't eliminate any instructions
467 // before a bound label.
468 if (pos > last_bound_pos_) last_bound_pos_ = pos;
469 }
470
bind(Label * L)471 void Assembler::bind(Label* L) {
472 DCHECK(!L->is_bound()); // label can only be bound once
473 bind_to(L, pc_offset());
474 }
475
next(Label * L)476 void Assembler::next(Label* L) {
477 DCHECK(L->is_linked());
478 int link = target_at(L->pos());
479 if (link == kEndOfChain) {
480 L->Unuse();
481 } else {
482 DCHECK(link >= 0);
483 L->link_to(link);
484 }
485 }
486
is_near(Label * L,Condition cond)487 bool Assembler::is_near(Label* L, Condition cond) {
488 DCHECK(L->is_bound());
489 if (L->is_bound() == false) return false;
490
491 int maxReach = ((cond == al) ? 26 : 16);
492 int offset = L->pos() - pc_offset();
493
494 return is_intn(offset, maxReach);
495 }
496
link(Label * L)497 int Assembler::link(Label* L) {
498 int position;
499 if (L->is_bound()) {
500 position = L->pos();
501 } else {
502 if (L->is_linked()) {
503 position = L->pos(); // L's link
504 } else {
505 // was: target_pos = kEndOfChain;
506 // However, using self to mark the first reference
507 // should avoid most instances of branch offset overflow. See
508 // target_at() for where this is converted back to kEndOfChain.
509 position = pc_offset();
510 }
511 L->link_to(pc_offset());
512 }
513
514 return position;
515 }
516
load_label_offset(Register r1,Label * L)517 void Assembler::load_label_offset(Register r1, Label* L) {
518 int target_pos;
519 int constant;
520 if (L->is_bound()) {
521 target_pos = L->pos();
522 constant = target_pos + (Code::kHeaderSize - kHeapObjectTag);
523 } else {
524 if (L->is_linked()) {
525 target_pos = L->pos(); // L's link
526 } else {
527 // was: target_pos = kEndOfChain;
528 // However, using branch to self to mark the first reference
529 // should avoid most instances of branch offset overflow. See
530 // target_at() for where this is converted back to kEndOfChain.
531 target_pos = pc_offset();
532 }
533 L->link_to(pc_offset());
534
535 constant = target_pos - pc_offset();
536 }
537 llilf(r1, Operand(constant));
538 }
539
540 // Pseudo op - branch on condition
branchOnCond(Condition c,int branch_offset,bool is_bound)541 void Assembler::branchOnCond(Condition c, int branch_offset, bool is_bound) {
542 int offset_in_halfwords = branch_offset / 2;
543 if (is_bound && is_int16(offset_in_halfwords)) {
544 brc(c, Operand(offset_in_halfwords)); // short jump
545 } else {
546 brcl(c, Operand(offset_in_halfwords)); // long jump
547 }
548 }
549
550 // 32-bit Store Multiple - short displacement (12-bits unsigned)
stm(Register r1,Register r2,const MemOperand & src)551 void Assembler::stm(Register r1, Register r2, const MemOperand& src) {
552 rs_form(STM, r1, r2, src.rb(), src.offset());
553 }
554
555 // 32-bit Store Multiple - long displacement (20-bits signed)
stmy(Register r1,Register r2,const MemOperand & src)556 void Assembler::stmy(Register r1, Register r2, const MemOperand& src) {
557 rsy_form(STMY, r1, r2, src.rb(), src.offset());
558 }
559
560 // 64-bit Store Multiple - long displacement (20-bits signed)
stmg(Register r1,Register r2,const MemOperand & src)561 void Assembler::stmg(Register r1, Register r2, const MemOperand& src) {
562 rsy_form(STMG, r1, r2, src.rb(), src.offset());
563 }
564
565 // Exception-generating instructions and debugging support.
566 // Stops with a non-negative code less than kNumOfWatchedStops support
567 // enabling/disabling and a counter feature. See simulator-s390.h .
stop(const char * msg,Condition cond,int32_t code,CRegister cr)568 void Assembler::stop(const char* msg, Condition cond, int32_t code,
569 CRegister cr) {
570 if (cond != al) {
571 Label skip;
572 b(NegateCondition(cond), &skip, Label::kNear);
573 bkpt(0);
574 bind(&skip);
575 } else {
576 bkpt(0);
577 }
578 }
579
bkpt(uint32_t imm16)580 void Assembler::bkpt(uint32_t imm16) {
581 // GDB software breakpoint instruction
582 emit2bytes(0x0001);
583 }
584
585 // Pseudo instructions.
nop(int type)586 void Assembler::nop(int type) {
587 switch (type) {
588 case 0:
589 lr(r0, r0);
590 break;
591 case DEBUG_BREAK_NOP:
592 // TODO(john.yan): Use a better NOP break
593 oill(r3, Operand::Zero());
594 break;
595 default:
596 UNIMPLEMENTED();
597 }
598 }
599
600
601
602 // RI1 format: <insn> R1,I2
603 // +--------+----+----+------------------+
604 // | OpCode | R1 |OpCd| I2 |
605 // +--------+----+----+------------------+
606 // 0 8 12 16 31
607 #define RI1_FORM_EMIT(name, op) \
608 void Assembler::name(Register r, const Operand& i2) { ri_form(op, r, i2); }
609
ri_form(Opcode op,Register r1,const Operand & i2)610 void Assembler::ri_form(Opcode op, Register r1, const Operand& i2) {
611 DCHECK(is_uint12(op));
612 DCHECK(is_uint16(i2.imm_) || is_int16(i2.imm_));
613 emit4bytes((op & 0xFF0) * B20 | r1.code() * B20 | (op & 0xF) * B16 |
614 (i2.imm_ & 0xFFFF));
615 }
616
617 // RI2 format: <insn> M1,I2
618 // +--------+----+----+------------------+
619 // | OpCode | M1 |OpCd| I2 |
620 // +--------+----+----+------------------+
621 // 0 8 12 16 31
622 #define RI2_FORM_EMIT(name, op) \
623 void Assembler::name(Condition m, const Operand& i2) { ri_form(op, m, i2); }
624
ri_form(Opcode op,Condition m1,const Operand & i2)625 void Assembler::ri_form(Opcode op, Condition m1, const Operand& i2) {
626 DCHECK(is_uint12(op));
627 DCHECK(is_uint4(m1));
628 DCHECK(op == BRC ? is_int16(i2.imm_) : is_uint16(i2.imm_));
629 emit4bytes((op & 0xFF0) * B20 | m1 * B20 | (op & 0xF) * B16 |
630 (i2.imm_ & 0xFFFF));
631 }
632
633 // RIE-f format: <insn> R1,R2,I3,I4,I5
634 // +--------+----+----+------------------+--------+--------+
635 // | OpCode | R1 | R2 | I3 | I4 | I5 | OpCode |
636 // +--------+----+----+------------------+--------+--------+
637 // 0 8 12 16 24 32 40 47
rie_f_form(Opcode op,Register r1,Register r2,const Operand & i3,const Operand & i4,const Operand & i5)638 void Assembler::rie_f_form(Opcode op, Register r1, Register r2,
639 const Operand& i3, const Operand& i4,
640 const Operand& i5) {
641 DCHECK(is_uint16(op));
642 DCHECK(is_uint8(i3.imm_));
643 DCHECK(is_uint8(i4.imm_));
644 DCHECK(is_uint8(i5.imm_));
645 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
646 (static_cast<uint64_t>(r1.code())) * B36 |
647 (static_cast<uint64_t>(r2.code())) * B32 |
648 (static_cast<uint64_t>(i3.imm_)) * B24 |
649 (static_cast<uint64_t>(i4.imm_)) * B16 |
650 (static_cast<uint64_t>(i5.imm_)) * B8 |
651 (static_cast<uint64_t>(op & 0x00FF));
652 emit6bytes(code);
653 }
654
655 // RIE format: <insn> R1,R3,I2
656 // +--------+----+----+------------------+--------+--------+
657 // | OpCode | R1 | R3 | I2 |////////| OpCode |
658 // +--------+----+----+------------------+--------+--------+
659 // 0 8 12 16 32 40 47
660 #define RIE_FORM_EMIT(name, op) \
661 void Assembler::name(Register r1, Register r3, const Operand& i2) { \
662 rie_form(op, r1, r3, i2); \
663 }
664
rie_form(Opcode op,Register r1,Register r3,const Operand & i2)665 void Assembler::rie_form(Opcode op, Register r1, Register r3,
666 const Operand& i2) {
667 DCHECK(is_uint16(op));
668 DCHECK(is_int16(i2.imm_));
669 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
670 (static_cast<uint64_t>(r1.code())) * B36 |
671 (static_cast<uint64_t>(r3.code())) * B32 |
672 (static_cast<uint64_t>(i2.imm_ & 0xFFFF)) * B16 |
673 (static_cast<uint64_t>(op & 0x00FF));
674 emit6bytes(code);
675 }
676
677 // RS1 format: <insn> R1,R3,D2(B2)
678 // +--------+----+----+----+-------------+
679 // | OpCode | R1 | R3 | B2 | D2 |
680 // +--------+----+----+----+-------------+
681 // 0 8 12 16 20 31
682 #define RS1_FORM_EMIT(name, op) \
683 void Assembler::name(Register r1, Register r3, Register b2, Disp d2) { \
684 rs_form(op, r1, r3, b2, d2); \
685 } \
686 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \
687 name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \
688 }
689
rs_form(Opcode op,Register r1,Register r3,Register b2,const Disp d2)690 void Assembler::rs_form(Opcode op, Register r1, Register r3, Register b2,
691 const Disp d2) {
692 DCHECK(is_uint12(d2));
693 emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | b2.code() * B12 |
694 d2);
695 }
696
697 // RS2 format: <insn> R1,M3,D2(B2)
698 // +--------+----+----+----+-------------+
699 // | OpCode | R1 | M3 | B2 | D2 |
700 // +--------+----+----+----+-------------+
701 // 0 8 12 16 20 31
702 #define RS2_FORM_EMIT(name, op) \
703 void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) { \
704 rs_form(op, r1, m3, b2, d2); \
705 } \
706 void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \
707 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \
708 }
709
rs_form(Opcode op,Register r1,Condition m3,Register b2,const Disp d2)710 void Assembler::rs_form(Opcode op, Register r1, Condition m3, Register b2,
711 const Disp d2) {
712 DCHECK(is_uint12(d2));
713 emit4bytes(op * B24 | r1.code() * B20 | m3 * B16 | b2.code() * B12 | d2);
714 }
715
716 // RSI format: <insn> R1,R3,I2
717 // +--------+----+----+------------------+
718 // | OpCode | R1 | R3 | RI2 |
719 // +--------+----+----+------------------+
720 // 0 8 12 16 31
721 #define RSI_FORM_EMIT(name, op) \
722 void Assembler::name(Register r1, Register r3, const Operand& i2) { \
723 rsi_form(op, r1, r3, i2); \
724 }
725
rsi_form(Opcode op,Register r1,Register r3,const Operand & i2)726 void Assembler::rsi_form(Opcode op, Register r1, Register r3,
727 const Operand& i2) {
728 DCHECK(is_uint8(op));
729 DCHECK(is_uint16(i2.imm_));
730 emit4bytes(op * B24 | r1.code() * B20 | r3.code() * B16 | (i2.imm_ & 0xFFFF));
731 }
732
733 // RSL format: <insn> R1,R3,D2(B2)
734 // +--------+----+----+----+-------------+--------+--------+
735 // | OpCode | L1 | | B2 | D2 | | OpCode |
736 // +--------+----+----+----+-------------+--------+--------+
737 // 0 8 12 16 20 32 40 47
738 #define RSL_FORM_EMIT(name, op) \
739 void Assembler::name(Length l1, Register b2, Disp d2) { \
740 rsl_form(op, l1, b2, d2); \
741 }
742
rsl_form(Opcode op,Length l1,Register b2,Disp d2)743 void Assembler::rsl_form(Opcode op, Length l1, Register b2, Disp d2) {
744 DCHECK(is_uint16(op));
745 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
746 (static_cast<uint64_t>(l1)) * B36 |
747 (static_cast<uint64_t>(b2.code())) * B28 |
748 (static_cast<uint64_t>(d2)) * B16 |
749 (static_cast<uint64_t>(op & 0x00FF));
750 emit6bytes(code);
751 }
752
753 // RSY1 format: <insn> R1,R3,D2(B2)
754 // +--------+----+----+----+-------------+--------+--------+
755 // | OpCode | R1 | R3 | B2 | DL2 | DH2 | OpCode |
756 // +--------+----+----+----+-------------+--------+--------+
757 // 0 8 12 16 20 32 40 47
758 #define RSY1_FORM_EMIT(name, op) \
759 void Assembler::name(Register r1, Register r3, Register b2, Disp d2) { \
760 rsy_form(op, r1, r3, b2, d2); \
761 } \
762 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \
763 name(r1, r3, opnd.getBaseRegister(), opnd.getDisplacement()); \
764 }
765
rsy_form(Opcode op,Register r1,Register r3,Register b2,const Disp d2)766 void Assembler::rsy_form(Opcode op, Register r1, Register r3, Register b2,
767 const Disp d2) {
768 DCHECK(is_int20(d2));
769 DCHECK(is_uint16(op));
770 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
771 (static_cast<uint64_t>(r1.code())) * B36 |
772 (static_cast<uint64_t>(r3.code())) * B32 |
773 (static_cast<uint64_t>(b2.code())) * B28 |
774 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
775 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 |
776 (static_cast<uint64_t>(op & 0x00FF));
777 emit6bytes(code);
778 }
779
780 // RSY2 format: <insn> R1,M3,D2(B2)
781 // +--------+----+----+----+-------------+--------+--------+
782 // | OpCode | R1 | M3 | B2 | DL2 | DH2 | OpCode |
783 // +--------+----+----+----+-------------+--------+--------+
784 // 0 8 12 16 20 32 40 47
785 #define RSY2_FORM_EMIT(name, op) \
786 void Assembler::name(Register r1, Condition m3, Register b2, Disp d2) { \
787 rsy_form(op, r1, m3, b2, d2); \
788 } \
789 void Assembler::name(Register r1, Condition m3, const MemOperand& opnd) { \
790 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement()); \
791 }
792
rsy_form(Opcode op,Register r1,Condition m3,Register b2,const Disp d2)793 void Assembler::rsy_form(Opcode op, Register r1, Condition m3, Register b2,
794 const Disp d2) {
795 DCHECK(is_int20(d2));
796 DCHECK(is_uint16(op));
797 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
798 (static_cast<uint64_t>(r1.code())) * B36 |
799 (static_cast<uint64_t>(m3)) * B32 |
800 (static_cast<uint64_t>(b2.code())) * B28 |
801 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
802 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 |
803 (static_cast<uint64_t>(op & 0x00FF));
804 emit6bytes(code);
805 }
806
807 // RXE format: <insn> R1,D2(X2,B2)
808 // +--------+----+----+----+-------------+--------+--------+
809 // | OpCode | R1 | X2 | B2 | D2 |////////| OpCode |
810 // +--------+----+----+----+-------------+--------+--------+
811 // 0 8 12 16 20 32 40 47
812 #define RXE_FORM_EMIT(name, op) \
813 void Assembler::name(Register r1, Register x2, Register b2, Disp d2) { \
814 rxe_form(op, r1, x2, b2, d2); \
815 } \
816 void Assembler::name(Register r1, const MemOperand& opnd) { \
817 name(r1, opnd.getIndexRegister(), opnd.getBaseRegister(), \
818 opnd.getDisplacement()); \
819 }
820
rxe_form(Opcode op,Register r1,Register x2,Register b2,Disp d2)821 void Assembler::rxe_form(Opcode op, Register r1, Register x2, Register b2,
822 Disp d2) {
823 DCHECK(is_uint12(d2));
824 DCHECK(is_uint16(op));
825 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
826 (static_cast<uint64_t>(r1.code())) * B36 |
827 (static_cast<uint64_t>(x2.code())) * B32 |
828 (static_cast<uint64_t>(b2.code())) * B28 |
829 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
830 (static_cast<uint64_t>(op & 0x00FF));
831 emit6bytes(code);
832 }
833
834 // RRS format: <insn> R1,R2,M3,D4(B4)
835 // +--------+----+----+----+-------------+----+---+--------+
836 // | OpCode | R1 | R2 | B4 | D4 | M3 |///| OpCode |
837 // +--------+----+----+----+-------------+----+---+--------+
838 // 0 8 12 16 20 32 36 40 47
839 #define RRS_FORM_EMIT(name, op) \
840 void Assembler::name(Register r1, Register r2, Register b4, Disp d4, \
841 Condition m3) { \
842 rrs_form(op, r1, r2, b4, d4, m3); \
843 } \
844 void Assembler::name(Register r1, Register r2, Condition m3, \
845 const MemOperand& opnd) { \
846 name(r1, r2, opnd.getBaseRegister(), opnd.getDisplacement(), m3); \
847 }
848
rrs_form(Opcode op,Register r1,Register r2,Register b4,Disp d4,Condition m3)849 void Assembler::rrs_form(Opcode op, Register r1, Register r2, Register b4,
850 Disp d4, Condition m3) {
851 DCHECK(is_uint12(d4));
852 DCHECK(is_uint16(op));
853 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
854 (static_cast<uint64_t>(r1.code())) * B36 |
855 (static_cast<uint64_t>(r2.code())) * B32 |
856 (static_cast<uint64_t>(b4.code())) * B28 |
857 (static_cast<uint64_t>(d4)) * B16 |
858 (static_cast<uint64_t>(m3)) << 12 |
859 (static_cast<uint64_t>(op & 0x00FF));
860 emit6bytes(code);
861 }
862
863 // RIS format: <insn> R1,I2,M3,D4(B4)
864 // +--------+----+----+----+-------------+--------+--------+
865 // | OpCode | R1 | M3 | B4 | D4 | I2 | OpCode |
866 // +--------+----+----+----+-------------+--------+--------+
867 // 0 8 12 16 20 32 40 47
868 #define RIS_FORM_EMIT(name, op) \
869 void Assembler::name(Register r1, Condition m3, Register b4, Disp d4, \
870 const Operand& i2) { \
871 ris_form(op, r1, m3, b4, d4, i2); \
872 } \
873 void Assembler::name(Register r1, const Operand& i2, Condition m3, \
874 const MemOperand& opnd) { \
875 name(r1, m3, opnd.getBaseRegister(), opnd.getDisplacement(), i2); \
876 }
877
ris_form(Opcode op,Register r1,Condition m3,Register b4,Disp d4,const Operand & i2)878 void Assembler::ris_form(Opcode op, Register r1, Condition m3, Register b4,
879 Disp d4, const Operand& i2) {
880 DCHECK(is_uint12(d4));
881 DCHECK(is_uint16(op));
882 DCHECK(is_uint8(i2.imm_));
883 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
884 (static_cast<uint64_t>(r1.code())) * B36 |
885 (static_cast<uint64_t>(m3)) * B32 |
886 (static_cast<uint64_t>(b4.code())) * B28 |
887 (static_cast<uint64_t>(d4)) * B16 |
888 (static_cast<uint64_t>(i2.imm_)) << 8 |
889 (static_cast<uint64_t>(op & 0x00FF));
890 emit6bytes(code);
891 }
892
893 // S format: <insn> D2(B2)
894 // +------------------+----+-------------+
895 // | OpCode | B2 | D2 |
896 // +------------------+----+-------------+
897 // 0 16 20 31
898 #define S_FORM_EMIT(name, op) \
899 void Assembler::name(Register b1, Disp d2) { s_form(op, b1, d2); } \
900 void Assembler::name(const MemOperand& opnd) { \
901 name(opnd.getBaseRegister(), opnd.getDisplacement()); \
902 }
903
s_form(Opcode op,Register b1,Disp d2)904 void Assembler::s_form(Opcode op, Register b1, Disp d2) {
905 DCHECK(is_uint12(d2));
906 emit4bytes(op << 16 | b1.code() * B12 | d2);
907 }
908
909 // SI format: <insn> D1(B1),I2
910 // +--------+---------+----+-------------+
911 // | OpCode | I2 | B1 | D1 |
912 // +--------+---------+----+-------------+
913 // 0 8 16 20 31
914 #define SI_FORM_EMIT(name, op) \
915 void Assembler::name(const Operand& i2, Register b1, Disp d1) { \
916 si_form(op, i2, b1, d1); \
917 } \
918 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \
919 name(i2, opnd.getBaseRegister(), opnd.getDisplacement()); \
920 }
921
si_form(Opcode op,const Operand & i2,Register b1,Disp d1)922 void Assembler::si_form(Opcode op, const Operand& i2, Register b1, Disp d1) {
923 emit4bytes((op & 0x00FF) << 24 | i2.imm_ * B16 | b1.code() * B12 | d1);
924 }
925
926 // SIY format: <insn> D1(B1),I2
927 // +--------+---------+----+-------------+--------+--------+
928 // | OpCode | I2 | B1 | DL1 | DH1 | OpCode |
929 // +--------+---------+----+-------------+--------+--------+
930 // 0 8 16 20 32 36 40 47
931 #define SIY_FORM_EMIT(name, op) \
932 void Assembler::name(const Operand& i2, Register b1, Disp d1) { \
933 siy_form(op, i2, b1, d1); \
934 } \
935 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \
936 name(i2, opnd.getBaseRegister(), opnd.getDisplacement()); \
937 }
938
siy_form(Opcode op,const Operand & i2,Register b1,Disp d1)939 void Assembler::siy_form(Opcode op, const Operand& i2, Register b1, Disp d1) {
940 DCHECK(is_uint20(d1) || is_int20(d1));
941 DCHECK(is_uint16(op));
942 DCHECK(is_uint8(i2.imm_));
943 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
944 (static_cast<uint64_t>(i2.imm_)) * B32 |
945 (static_cast<uint64_t>(b1.code())) * B28 |
946 (static_cast<uint64_t>(d1 & 0x0FFF)) * B16 |
947 (static_cast<uint64_t>(d1 & 0x0FF000)) >> 4 |
948 (static_cast<uint64_t>(op & 0x00FF));
949 emit6bytes(code);
950 }
951
952 // SIL format: <insn> D1(B1),I2
953 // +------------------+----+-------------+-----------------+
954 // | OpCode | B1 | D1 | I2 |
955 // +------------------+----+-------------+-----------------+
956 // 0 16 20 32 47
957 #define SIL_FORM_EMIT(name, op) \
958 void Assembler::name(Register b1, Disp d1, const Operand& i2) { \
959 sil_form(op, b1, d1, i2); \
960 } \
961 void Assembler::name(const MemOperand& opnd, const Operand& i2) { \
962 name(opnd.getBaseRegister(), opnd.getDisplacement(), i2); \
963 }
964
sil_form(Opcode op,Register b1,Disp d1,const Operand & i2)965 void Assembler::sil_form(Opcode op, Register b1, Disp d1, const Operand& i2) {
966 DCHECK(is_uint12(d1));
967 DCHECK(is_uint16(op));
968 DCHECK(is_uint16(i2.imm_));
969 uint64_t code = (static_cast<uint64_t>(op)) * B32 |
970 (static_cast<uint64_t>(b1.code())) * B28 |
971 (static_cast<uint64_t>(d1)) * B16 |
972 (static_cast<uint64_t>(i2.imm_));
973 emit6bytes(code);
974 }
975
976 // RXF format: <insn> R1,R3,D2(X2,B2)
977 // +--------+----+----+----+-------------+----+---+--------+
978 // | OpCode | R3 | X2 | B2 | D2 | R1 |///| OpCode |
979 // +--------+----+----+----+-------------+----+---+--------+
980 // 0 8 12 16 20 32 36 40 47
981 #define RXF_FORM_EMIT(name, op) \
982 void Assembler::name(Register r1, Register r3, Register b2, Register x2, \
983 Disp d2) { \
984 rxf_form(op, r1, r3, b2, x2, d2); \
985 } \
986 void Assembler::name(Register r1, Register r3, const MemOperand& opnd) { \
987 name(r1, r3, opnd.getBaseRegister(), opnd.getIndexRegister(), \
988 opnd.getDisplacement()); \
989 }
990
rxf_form(Opcode op,Register r1,Register r3,Register b2,Register x2,Disp d2)991 void Assembler::rxf_form(Opcode op, Register r1, Register r3, Register b2,
992 Register x2, Disp d2) {
993 DCHECK(is_uint12(d2));
994 DCHECK(is_uint16(op));
995 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
996 (static_cast<uint64_t>(r3.code())) * B36 |
997 (static_cast<uint64_t>(x2.code())) * B32 |
998 (static_cast<uint64_t>(b2.code())) * B28 |
999 (static_cast<uint64_t>(d2)) * B16 |
1000 (static_cast<uint64_t>(r1.code())) * B12 |
1001 (static_cast<uint64_t>(op & 0x00FF));
1002 emit6bytes(code);
1003 }
1004
1005 // SS1 format: <insn> D1(L,B1),D2(B3)
1006 // +--------+----+----+----+-------------+----+------------+
1007 // | OpCode | L | B1 | D1 | B2 | D2 |
1008 // +--------+----+----+----+-------------+----+------------+
1009 // 0 8 12 16 20 32 36 47
1010 #define SS1_FORM_EMIT(name, op) \
1011 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l) { \
1012 ss_form(op, l, b1, d1, b2, d2); \
1013 } \
1014 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \
1015 Length length) { \
1016 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \
1017 opnd2.getBaseRegister(), opnd2.getDisplacement(), length); \
1018 }
1019
ss_form(Opcode op,Length l,Register b1,Disp d1,Register b2,Disp d2)1020 void Assembler::ss_form(Opcode op, Length l, Register b1, Disp d1, Register b2,
1021 Disp d2) {
1022 DCHECK(is_uint12(d2));
1023 DCHECK(is_uint12(d1));
1024 DCHECK(is_uint8(op));
1025 DCHECK(is_uint8(l));
1026 uint64_t code =
1027 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l)) * B32 |
1028 (static_cast<uint64_t>(b1.code())) * B28 |
1029 (static_cast<uint64_t>(d1)) * B16 |
1030 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2));
1031 emit6bytes(code);
1032 }
1033
1034 // SS2 format: <insn> D1(L1,B1), D2(L3,B3)
1035 // +--------+----+----+----+-------------+----+------------+
1036 // | OpCode | L1 | L2 | B1 | D1 | B2 | D2 |
1037 // +--------+----+----+----+-------------+----+------------+
1038 // 0 8 12 16 20 32 36 47
1039 #define SS2_FORM_EMIT(name, op) \
1040 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2, Length l1, \
1041 Length l2) { \
1042 ss_form(op, l1, l2, b1, d1, b2, d2); \
1043 } \
1044 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \
1045 Length length1, Length length2) { \
1046 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \
1047 opnd2.getBaseRegister(), opnd2.getDisplacement(), length1, length2); \
1048 }
1049
ss_form(Opcode op,Length l1,Length l2,Register b1,Disp d1,Register b2,Disp d2)1050 void Assembler::ss_form(Opcode op, Length l1, Length l2, Register b1, Disp d1,
1051 Register b2, Disp d2) {
1052 DCHECK(is_uint12(d2));
1053 DCHECK(is_uint12(d1));
1054 DCHECK(is_uint8(op));
1055 DCHECK(is_uint4(l2));
1056 DCHECK(is_uint4(l1));
1057 uint64_t code =
1058 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 |
1059 (static_cast<uint64_t>(l2)) * B32 |
1060 (static_cast<uint64_t>(b1.code())) * B28 |
1061 (static_cast<uint64_t>(d1)) * B16 |
1062 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2));
1063 emit6bytes(code);
1064 }
1065
1066 // SS3 format: <insn> D1(L1,B1), D2(I3,B2)
1067 // +--------+----+----+----+-------------+----+------------+
1068 // | OpCode | L1 | I3 | B1 | D1 | B2 | D2 |
1069 // +--------+----+----+----+-------------+----+------------+
1070 // 0 8 12 16 20 32 36 47
1071 #define SS3_FORM_EMIT(name, op) \
1072 void Assembler::name(const Operand& i3, Register b1, Disp d1, Register b2, \
1073 Disp d2, Length l1) { \
1074 ss_form(op, l1, i3, b1, d1, b2, d2); \
1075 } \
1076 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2, \
1077 Length length) { \
1078 DCHECK(false); \
1079 }
ss_form(Opcode op,Length l1,const Operand & i3,Register b1,Disp d1,Register b2,Disp d2)1080 void Assembler::ss_form(Opcode op, Length l1, const Operand& i3, Register b1,
1081 Disp d1, Register b2, Disp d2) {
1082 DCHECK(is_uint12(d2));
1083 DCHECK(is_uint12(d1));
1084 DCHECK(is_uint8(op));
1085 DCHECK(is_uint4(l1));
1086 DCHECK(is_uint4(i3.imm_));
1087 uint64_t code =
1088 (static_cast<uint64_t>(op)) * B40 | (static_cast<uint64_t>(l1)) * B36 |
1089 (static_cast<uint64_t>(i3.imm_)) * B32 |
1090 (static_cast<uint64_t>(b1.code())) * B28 |
1091 (static_cast<uint64_t>(d1)) * B16 |
1092 (static_cast<uint64_t>(b2.code())) * B12 | (static_cast<uint64_t>(d2));
1093 emit6bytes(code);
1094 }
1095
1096 // SS4 format: <insn> D1(R1,B1), D2(R3,B2)
1097 // +--------+----+----+----+-------------+----+------------+
1098 // | OpCode | R1 | R3 | B1 | D1 | B2 | D2 |
1099 // +--------+----+----+----+-------------+----+------------+
1100 // 0 8 12 16 20 32 36 47
1101 #define SS4_FORM_EMIT(name, op) \
1102 void Assembler::name(Register r1, Register r3, Register b1, Disp d1, \
1103 Register b2, Disp d2) { \
1104 ss_form(op, r1, r3, b1, d1, b2, d2); \
1105 } \
1106 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \
1107 DCHECK(false); \
1108 }
ss_form(Opcode op,Register r1,Register r3,Register b1,Disp d1,Register b2,Disp d2)1109 void Assembler::ss_form(Opcode op, Register r1, Register r3, Register b1,
1110 Disp d1, Register b2, Disp d2) {
1111 DCHECK(is_uint12(d2));
1112 DCHECK(is_uint12(d1));
1113 DCHECK(is_uint8(op));
1114 uint64_t code = (static_cast<uint64_t>(op)) * B40 |
1115 (static_cast<uint64_t>(r1.code())) * B36 |
1116 (static_cast<uint64_t>(r3.code())) * B32 |
1117 (static_cast<uint64_t>(b1.code())) * B28 |
1118 (static_cast<uint64_t>(d1)) * B16 |
1119 (static_cast<uint64_t>(b2.code())) * B12 |
1120 (static_cast<uint64_t>(d2));
1121 emit6bytes(code);
1122 }
1123
1124 // SS5 format: <insn> D1(R1,B1), D2(R3,B2)
1125 // +--------+----+----+----+-------------+----+------------+
1126 // | OpCode | R1 | R3 | B2 | D2 | B4 | D4 |
1127 // +--------+----+----+----+-------------+----+------------+
1128 // 0 8 12 16 20 32 36 47
1129 #define SS5_FORM_EMIT(name, op) \
1130 void Assembler::name(Register r1, Register r3, Register b2, Disp d2, \
1131 Register b4, Disp d4) { \
1132 ss_form(op, r1, r3, b2, d2, b4, d4); /*SS5 use the same form as SS4*/ \
1133 } \
1134 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \
1135 DCHECK(false); \
1136 }
1137
1138 #define SS6_FORM_EMIT(name, op) SS1_FORM_EMIT(name, op)
1139
1140 // SSE format: <insn> D1(B1),D2(B2)
1141 // +------------------+----+-------------+----+------------+
1142 // | OpCode | B1 | D1 | B2 | D2 |
1143 // +------------------+----+-------------+----+------------+
1144 // 0 8 12 16 20 32 36 47
1145 #define SSE_FORM_EMIT(name, op) \
1146 void Assembler::name(Register b1, Disp d1, Register b2, Disp d2) { \
1147 sse_form(op, b1, d1, b2, d2); \
1148 } \
1149 void Assembler::name(const MemOperand& opnd1, const MemOperand& opnd2) { \
1150 name(opnd1.getBaseRegister(), opnd1.getDisplacement(), \
1151 opnd2.getBaseRegister(), opnd2.getDisplacement()); \
1152 }
sse_form(Opcode op,Register b1,Disp d1,Register b2,Disp d2)1153 void Assembler::sse_form(Opcode op, Register b1, Disp d1, Register b2,
1154 Disp d2) {
1155 DCHECK(is_uint12(d2));
1156 DCHECK(is_uint12(d1));
1157 DCHECK(is_uint16(op));
1158 uint64_t code = (static_cast<uint64_t>(op)) * B32 |
1159 (static_cast<uint64_t>(b1.code())) * B28 |
1160 (static_cast<uint64_t>(d1)) * B16 |
1161 (static_cast<uint64_t>(b2.code())) * B12 |
1162 (static_cast<uint64_t>(d2));
1163 emit6bytes(code);
1164 }
1165
1166 // SSF format: <insn> R3, D1(B1),D2(B2),R3
1167 // +--------+----+----+----+-------------+----+------------+
1168 // | OpCode | R3 |OpCd| B1 | D1 | B2 | D2 |
1169 // +--------+----+----+----+-------------+----+------------+
1170 // 0 8 12 16 20 32 36 47
1171 #define SSF_FORM_EMIT(name, op) \
1172 void Assembler::name(Register r3, Register b1, Disp d1, Register b2, \
1173 Disp d2) { \
1174 ssf_form(op, r3, b1, d1, b2, d2); \
1175 } \
1176 void Assembler::name(Register r3, const MemOperand& opnd1, \
1177 const MemOperand& opnd2) { \
1178 name(r3, opnd1.getBaseRegister(), opnd1.getDisplacement(), \
1179 opnd2.getBaseRegister(), opnd2.getDisplacement()); \
1180 }
1181
ssf_form(Opcode op,Register r3,Register b1,Disp d1,Register b2,Disp d2)1182 void Assembler::ssf_form(Opcode op, Register r3, Register b1, Disp d1,
1183 Register b2, Disp d2) {
1184 DCHECK(is_uint12(d2));
1185 DCHECK(is_uint12(d1));
1186 DCHECK(is_uint12(op));
1187 uint64_t code = (static_cast<uint64_t>(op & 0xFF0)) * B36 |
1188 (static_cast<uint64_t>(r3.code())) * B36 |
1189 (static_cast<uint64_t>(op & 0x00F)) * B32 |
1190 (static_cast<uint64_t>(b1.code())) * B28 |
1191 (static_cast<uint64_t>(d1)) * B16 |
1192 (static_cast<uint64_t>(b2.code())) * B12 |
1193 (static_cast<uint64_t>(d2));
1194 emit6bytes(code);
1195 }
1196
1197 // RRF1 format: <insn> R1,R2,R3
1198 // +------------------+----+----+----+----+
1199 // | OpCode | R3 | | R1 | R2 |
1200 // +------------------+----+----+----+----+
1201 // 0 16 20 24 28 31
1202 #define RRF1_FORM_EMIT(name, op) \
1203 void Assembler::name(Register r1, Register r2, Register r3) { \
1204 rrf1_form(op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code()); \
1205 }
1206
rrf1_form(Opcode op,Register r1,Register r2,Register r3)1207 void Assembler::rrf1_form(Opcode op, Register r1, Register r2, Register r3) {
1208 uint32_t code = op << 16 | r3.code() * B12 | r1.code() * B4 | r2.code();
1209 emit4bytes(code);
1210 }
1211
rrf1_form(uint32_t code)1212 void Assembler::rrf1_form(uint32_t code) { emit4bytes(code); }
1213
1214 // RRF2 format: <insn> R1,R2,M3
1215 // +------------------+----+----+----+----+
1216 // | OpCode | M3 | | R1 | R2 |
1217 // +------------------+----+----+----+----+
1218 // 0 16 20 24 28 31
1219 #define RRF2_FORM_EMIT(name, op) \
1220 void Assembler::name(Condition m3, Register r1, Register r2) { \
1221 rrf2_form(op << 16 | m3 * B12 | r1.code() * B4 | r2.code()); \
1222 }
1223
rrf2_form(uint32_t code)1224 void Assembler::rrf2_form(uint32_t code) { emit4bytes(code); }
1225
1226 // RRF3 format: <insn> R1,R2,R3,M4
1227 // +------------------+----+----+----+----+
1228 // | OpCode | R3 | M4 | R1 | R2 |
1229 // +------------------+----+----+----+----+
1230 // 0 16 20 24 28 31
1231 #define RRF3_FORM_EMIT(name, op) \
1232 void Assembler::name(Register r3, Conition m4, Register r1, Register r2) { \
1233 rrf3_form(op << 16 | r3.code() * B12 | m4 * B8 | r1.code() * B4 | \
1234 r2.code()); \
1235 }
1236
rrf3_form(uint32_t code)1237 void Assembler::rrf3_form(uint32_t code) { emit4bytes(code); }
1238
1239 // RRF-e format: <insn> R1,M3,R2,M4
1240 // +------------------+----+----+----+----+
1241 // | OpCode | M3 | M4 | R1 | R2 |
1242 // +------------------+----+----+----+----+
1243 // 0 16 20 24 28 31
rrfe_form(Opcode op,Condition m3,Condition m4,Register r1,Register r2)1244 void Assembler::rrfe_form(Opcode op, Condition m3, Condition m4, Register r1,
1245 Register r2) {
1246 uint32_t code = op << 16 | m3 * B12 | m4 * B8 | r1.code() * B4 | r2.code();
1247 emit4bytes(code);
1248 }
1249
1250 // end of S390 Instruction generation
1251
1252 // start of S390 instruction
SS1_FORM_EMIT(ed,ED)1253 SS1_FORM_EMIT(ed, ED)
1254 SS1_FORM_EMIT(mvn, MVN)
1255 SS1_FORM_EMIT(nc, NC)
1256 SI_FORM_EMIT(ni, NI)
1257 RI1_FORM_EMIT(nilh, NILH)
1258 RI1_FORM_EMIT(nill, NILL)
1259 RI1_FORM_EMIT(oill, OILL)
1260 RI1_FORM_EMIT(tmll, TMLL)
1261 SS1_FORM_EMIT(tr, TR)
1262 S_FORM_EMIT(ts, TS)
1263
1264 // -------------------------
1265 // Load Address Instructions
1266 // -------------------------
1267 // Load Address Relative Long
1268 void Assembler::larl(Register r1, Label* l) {
1269 larl(r1, Operand(branch_offset(l)));
1270 }
1271
1272 // -----------------
1273 // Load Instructions
1274 // -----------------
1275 // Load Halfword Immediate (32)
lhi(Register r,const Operand & imm)1276 void Assembler::lhi(Register r, const Operand& imm) { ri_form(LHI, r, imm); }
1277
1278 // Load Halfword Immediate (64)
lghi(Register r,const Operand & imm)1279 void Assembler::lghi(Register r, const Operand& imm) { ri_form(LGHI, r, imm); }
1280
1281 // -------------------------
1282 // Load Logical Instructions
1283 // -------------------------
1284 // Load On Condition R-R (32)
locr(Condition m3,Register r1,Register r2)1285 void Assembler::locr(Condition m3, Register r1, Register r2) {
1286 rrf2_form(LOCR << 16 | m3 * B12 | r1.code() * B4 | r2.code());
1287 }
1288
1289 // Load On Condition R-R (64)
locgr(Condition m3,Register r1,Register r2)1290 void Assembler::locgr(Condition m3, Register r1, Register r2) {
1291 rrf2_form(LOCGR << 16 | m3 * B12 | r1.code() * B4 | r2.code());
1292 }
1293
1294 // Load On Condition R-M (32)
loc(Condition m3,Register r1,const MemOperand & src)1295 void Assembler::loc(Condition m3, Register r1, const MemOperand& src) {
1296 rsy_form(LOC, r1, m3, src.rb(), src.offset());
1297 }
1298
1299 // Load On Condition R-M (64)
locg(Condition m3,Register r1,const MemOperand & src)1300 void Assembler::locg(Condition m3, Register r1, const MemOperand& src) {
1301 rsy_form(LOCG, r1, m3, src.rb(), src.offset());
1302 }
1303
1304 // -------------------
1305 // Branch Instructions
1306 // -------------------
1307 // Branch on Count (64)
1308 // Branch Relative and Save (32)
bras(Register r,const Operand & opnd)1309 void Assembler::bras(Register r, const Operand& opnd) {
1310 ri_form(BRAS, r, opnd);
1311 }
1312
1313 // Branch relative on Condition (32)
brc(Condition c,const Operand & opnd)1314 void Assembler::brc(Condition c, const Operand& opnd) { ri_form(BRC, c, opnd); }
1315
1316 // Branch On Count (32)
brct(Register r1,const Operand & imm)1317 void Assembler::brct(Register r1, const Operand& imm) {
1318 // BRCT encodes # of halfwords, so divide by 2.
1319 int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2;
1320 Operand halfwordOp = Operand(numHalfwords);
1321 halfwordOp.setBits(16);
1322 ri_form(BRCT, r1, halfwordOp);
1323 }
1324
1325 // Branch On Count (32)
brctg(Register r1,const Operand & imm)1326 void Assembler::brctg(Register r1, const Operand& imm) {
1327 // BRCTG encodes # of halfwords, so divide by 2.
1328 int16_t numHalfwords = static_cast<int16_t>(imm.immediate()) / 2;
1329 Operand halfwordOp = Operand(numHalfwords);
1330 halfwordOp.setBits(16);
1331 ri_form(BRCTG, r1, halfwordOp);
1332 }
1333
1334 // --------------------
1335 // Compare Instructions
1336 // --------------------
1337 // Compare Halfword Immediate (32)
chi(Register r,const Operand & opnd)1338 void Assembler::chi(Register r, const Operand& opnd) { ri_form(CHI, r, opnd); }
1339
1340 // Compare Halfword Immediate (64)
cghi(Register r,const Operand & opnd)1341 void Assembler::cghi(Register r, const Operand& opnd) {
1342 ri_form(CGHI, r, opnd);
1343 }
1344
1345 // ----------------------------
1346 // Compare Logical Instructions
1347 // ----------------------------
1348 // Compare Immediate (Mem - Imm) (8)
cli(const MemOperand & opnd,const Operand & imm)1349 void Assembler::cli(const MemOperand& opnd, const Operand& imm) {
1350 si_form(CLI, imm, opnd.rb(), opnd.offset());
1351 }
1352
1353 // Compare Immediate (Mem - Imm) (8)
cliy(const MemOperand & opnd,const Operand & imm)1354 void Assembler::cliy(const MemOperand& opnd, const Operand& imm) {
1355 siy_form(CLIY, imm, opnd.rb(), opnd.offset());
1356 }
1357
1358 // Compare logical - mem to mem operation
clc(const MemOperand & opnd1,const MemOperand & opnd2,Length length)1359 void Assembler::clc(const MemOperand& opnd1, const MemOperand& opnd2,
1360 Length length) {
1361 ss_form(CLC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(),
1362 opnd2.getBaseRegister(), opnd2.getDisplacement());
1363 }
1364
1365 // ----------------------------
1366 // Test Under Mask Instructions
1367 // ----------------------------
1368 // Test Under Mask (Mem - Imm) (8)
tm(const MemOperand & opnd,const Operand & imm)1369 void Assembler::tm(const MemOperand& opnd, const Operand& imm) {
1370 si_form(TM, imm, opnd.rb(), opnd.offset());
1371 }
1372
1373 // Test Under Mask (Mem - Imm) (8)
tmy(const MemOperand & opnd,const Operand & imm)1374 void Assembler::tmy(const MemOperand& opnd, const Operand& imm) {
1375 siy_form(TMY, imm, opnd.rb(), opnd.offset());
1376 }
1377
1378 // -------------------------------
1379 // Rotate and Insert Selected Bits
1380 // -------------------------------
1381 // Rotate-And-Insert-Selected-Bits
risbg(Register dst,Register src,const Operand & startBit,const Operand & endBit,const Operand & shiftAmt,bool zeroBits)1382 void Assembler::risbg(Register dst, Register src, const Operand& startBit,
1383 const Operand& endBit, const Operand& shiftAmt,
1384 bool zeroBits) {
1385 // High tag the top bit of I4/EndBit to zero out any unselected bits
1386 if (zeroBits)
1387 rie_f_form(RISBG, dst, src, startBit, Operand(endBit.imm_ | 0x80),
1388 shiftAmt);
1389 else
1390 rie_f_form(RISBG, dst, src, startBit, endBit, shiftAmt);
1391 }
1392
1393 // Rotate-And-Insert-Selected-Bits
risbgn(Register dst,Register src,const Operand & startBit,const Operand & endBit,const Operand & shiftAmt,bool zeroBits)1394 void Assembler::risbgn(Register dst, Register src, const Operand& startBit,
1395 const Operand& endBit, const Operand& shiftAmt,
1396 bool zeroBits) {
1397 // High tag the top bit of I4/EndBit to zero out any unselected bits
1398 if (zeroBits)
1399 rie_f_form(RISBGN, dst, src, startBit, Operand(endBit.imm_ | 0x80),
1400 shiftAmt);
1401 else
1402 rie_f_form(RISBGN, dst, src, startBit, endBit, shiftAmt);
1403 }
1404
1405 // ---------------------------
1406 // Move Character Instructions
1407 // ---------------------------
1408 // Move charactor - mem to mem operation
mvc(const MemOperand & opnd1,const MemOperand & opnd2,uint32_t length)1409 void Assembler::mvc(const MemOperand& opnd1, const MemOperand& opnd2,
1410 uint32_t length) {
1411 ss_form(MVC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(),
1412 opnd2.getBaseRegister(), opnd2.getDisplacement());
1413 }
1414
1415 // -----------------------
1416 // 32-bit Add Instructions
1417 // -----------------------
1418 // Add Halfword Immediate (32)
ahi(Register r1,const Operand & i2)1419 void Assembler::ahi(Register r1, const Operand& i2) { ri_form(AHI, r1, i2); }
1420
1421 // Add Halfword Immediate (32)
ahik(Register r1,Register r3,const Operand & i2)1422 void Assembler::ahik(Register r1, Register r3, const Operand& i2) {
1423 rie_form(AHIK, r1, r3, i2);
1424 }
1425
1426 // Add Register-Register-Register (32)
ark(Register r1,Register r2,Register r3)1427 void Assembler::ark(Register r1, Register r2, Register r3) {
1428 rrf1_form(ARK, r1, r2, r3);
1429 }
1430
1431 // Add Storage-Imm (32)
asi(const MemOperand & opnd,const Operand & imm)1432 void Assembler::asi(const MemOperand& opnd, const Operand& imm) {
1433 DCHECK(is_int8(imm.imm_));
1434 DCHECK(is_int20(opnd.offset()));
1435 siy_form(ASI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset());
1436 }
1437
1438 // -----------------------
1439 // 64-bit Add Instructions
1440 // -----------------------
1441 // Add Halfword Immediate (64)
aghi(Register r1,const Operand & i2)1442 void Assembler::aghi(Register r1, const Operand& i2) { ri_form(AGHI, r1, i2); }
1443
1444 // Add Halfword Immediate (64)
aghik(Register r1,Register r3,const Operand & i2)1445 void Assembler::aghik(Register r1, Register r3, const Operand& i2) {
1446 rie_form(AGHIK, r1, r3, i2);
1447 }
1448
1449 // Add Register-Register-Register (64)
agrk(Register r1,Register r2,Register r3)1450 void Assembler::agrk(Register r1, Register r2, Register r3) {
1451 rrf1_form(AGRK, r1, r2, r3);
1452 }
1453
1454 // Add Storage-Imm (64)
agsi(const MemOperand & opnd,const Operand & imm)1455 void Assembler::agsi(const MemOperand& opnd, const Operand& imm) {
1456 DCHECK(is_int8(imm.imm_));
1457 DCHECK(is_int20(opnd.offset()));
1458 siy_form(AGSI, Operand(0xff & imm.imm_), opnd.rb(), 0xfffff & opnd.offset());
1459 }
1460
1461 // -------------------------------
1462 // 32-bit Add Logical Instructions
1463 // -------------------------------
1464 // Add Logical Register-Register-Register (32)
alrk(Register r1,Register r2,Register r3)1465 void Assembler::alrk(Register r1, Register r2, Register r3) {
1466 rrf1_form(ALRK, r1, r2, r3);
1467 }
1468
1469 // -------------------------------
1470 // 64-bit Add Logical Instructions
1471 // -------------------------------
1472 // Add Logical Register-Register-Register (64)
algrk(Register r1,Register r2,Register r3)1473 void Assembler::algrk(Register r1, Register r2, Register r3) {
1474 rrf1_form(ALGRK, r1, r2, r3);
1475 }
1476
1477 // ----------------------------
1478 // 32-bit Subtract Instructions
1479 // ----------------------------
1480 // Subtract Register-Register-Register (32)
srk(Register r1,Register r2,Register r3)1481 void Assembler::srk(Register r1, Register r2, Register r3) {
1482 rrf1_form(SRK, r1, r2, r3);
1483 }
1484
1485 // ----------------------------
1486 // 64-bit Subtract Instructions
1487 // ----------------------------
1488 // Subtract Register-Register-Register (64)
sgrk(Register r1,Register r2,Register r3)1489 void Assembler::sgrk(Register r1, Register r2, Register r3) {
1490 rrf1_form(SGRK, r1, r2, r3);
1491 }
1492
1493 // ------------------------------------
1494 // 32-bit Subtract Logical Instructions
1495 // ------------------------------------
1496 // Subtract Logical Register-Register-Register (32)
slrk(Register r1,Register r2,Register r3)1497 void Assembler::slrk(Register r1, Register r2, Register r3) {
1498 rrf1_form(SLRK, r1, r2, r3);
1499 }
1500
1501 // ------------------------------------
1502 // 64-bit Subtract Logical Instructions
1503 // ------------------------------------
1504 // Subtract Logical Register-Register-Register (64)
slgrk(Register r1,Register r2,Register r3)1505 void Assembler::slgrk(Register r1, Register r2, Register r3) {
1506 rrf1_form(SLGRK, r1, r2, r3);
1507 }
1508
1509 // ----------------------------
1510 // 32-bit Multiply Instructions
1511 // ----------------------------
1512 // Multiply Halfword Immediate (32)
mhi(Register r1,const Operand & opnd)1513 void Assembler::mhi(Register r1, const Operand& opnd) {
1514 ri_form(MHI, r1, opnd);
1515 }
1516
1517 // Multiply Single Register (32)
msrkc(Register r1,Register r2,Register r3)1518 void Assembler::msrkc(Register r1, Register r2, Register r3) {
1519 rrf1_form(MSRKC, r1, r2, r3);
1520 }
1521
1522 // Multiply Single Register (64)
msgrkc(Register r1,Register r2,Register r3)1523 void Assembler::msgrkc(Register r1, Register r2, Register r3) {
1524 rrf1_form(MSGRKC, r1, r2, r3);
1525 }
1526
1527 // ----------------------------
1528 // 64-bit Multiply Instructions
1529 // ----------------------------
1530 // Multiply Halfword Immediate (64)
mghi(Register r1,const Operand & opnd)1531 void Assembler::mghi(Register r1, const Operand& opnd) {
1532 ri_form(MGHI, r1, opnd);
1533 }
1534
1535 // --------------------
1536 // Bitwise Instructions
1537 // --------------------
1538 // AND Register-Register-Register (32)
nrk(Register r1,Register r2,Register r3)1539 void Assembler::nrk(Register r1, Register r2, Register r3) {
1540 rrf1_form(NRK, r1, r2, r3);
1541 }
1542
1543 // AND Register-Register-Register (64)
ngrk(Register r1,Register r2,Register r3)1544 void Assembler::ngrk(Register r1, Register r2, Register r3) {
1545 rrf1_form(NGRK, r1, r2, r3);
1546 }
1547
1548 // OR Register-Register-Register (32)
ork(Register r1,Register r2,Register r3)1549 void Assembler::ork(Register r1, Register r2, Register r3) {
1550 rrf1_form(ORK, r1, r2, r3);
1551 }
1552
1553 // OR Register-Register-Register (64)
ogrk(Register r1,Register r2,Register r3)1554 void Assembler::ogrk(Register r1, Register r2, Register r3) {
1555 rrf1_form(OGRK, r1, r2, r3);
1556 }
1557
1558 // XOR Register-Register-Register (32)
xrk(Register r1,Register r2,Register r3)1559 void Assembler::xrk(Register r1, Register r2, Register r3) {
1560 rrf1_form(XRK, r1, r2, r3);
1561 }
1562
1563 // XOR Register-Register-Register (64)
xgrk(Register r1,Register r2,Register r3)1564 void Assembler::xgrk(Register r1, Register r2, Register r3) {
1565 rrf1_form(XGRK, r1, r2, r3);
1566 }
1567
1568 // XOR Storage-Storage
xc(const MemOperand & opnd1,const MemOperand & opnd2,Length length)1569 void Assembler::xc(const MemOperand& opnd1, const MemOperand& opnd2,
1570 Length length) {
1571 ss_form(XC, length - 1, opnd1.getBaseRegister(), opnd1.getDisplacement(),
1572 opnd2.getBaseRegister(), opnd2.getDisplacement());
1573 }
1574
EnsureSpaceFor(int space_needed)1575 void Assembler::EnsureSpaceFor(int space_needed) {
1576 if (buffer_space() <= (kGap + space_needed)) {
1577 GrowBuffer(space_needed);
1578 }
1579 }
1580
1581 // Rotate Left Single Logical (32)
rll(Register r1,Register r3,Register opnd)1582 void Assembler::rll(Register r1, Register r3, Register opnd) {
1583 DCHECK(!opnd.is(r0));
1584 rsy_form(RLL, r1, r3, opnd, 0);
1585 }
1586
1587 // Rotate Left Single Logical (32)
rll(Register r1,Register r3,const Operand & opnd)1588 void Assembler::rll(Register r1, Register r3, const Operand& opnd) {
1589 rsy_form(RLL, r1, r3, r0, opnd.immediate());
1590 }
1591
1592 // Rotate Left Single Logical (32)
rll(Register r1,Register r3,Register r2,const Operand & opnd)1593 void Assembler::rll(Register r1, Register r3, Register r2,
1594 const Operand& opnd) {
1595 rsy_form(RLL, r1, r3, r2, opnd.immediate());
1596 }
1597
1598 // Rotate Left Single Logical (64)
rllg(Register r1,Register r3,Register opnd)1599 void Assembler::rllg(Register r1, Register r3, Register opnd) {
1600 DCHECK(!opnd.is(r0));
1601 rsy_form(RLLG, r1, r3, opnd, 0);
1602 }
1603
1604 // Rotate Left Single Logical (64)
rllg(Register r1,Register r3,const Operand & opnd)1605 void Assembler::rllg(Register r1, Register r3, const Operand& opnd) {
1606 rsy_form(RLLG, r1, r3, r0, opnd.immediate());
1607 }
1608
1609 // Rotate Left Single Logical (64)
rllg(Register r1,Register r3,Register r2,const Operand & opnd)1610 void Assembler::rllg(Register r1, Register r3, Register r2,
1611 const Operand& opnd) {
1612 rsy_form(RLLG, r1, r3, r2, opnd.immediate());
1613 }
1614
1615 // Shift Left Single Logical (32)
sll(Register r1,Register opnd)1616 void Assembler::sll(Register r1, Register opnd) {
1617 DCHECK(!opnd.is(r0));
1618 rs_form(SLL, r1, r0, opnd, 0);
1619 }
1620
1621 // Shift Left Single Logical (32)
sll(Register r1,const Operand & opnd)1622 void Assembler::sll(Register r1, const Operand& opnd) {
1623 rs_form(SLL, r1, r0, r0, opnd.immediate());
1624 }
1625
1626 // Shift Left Single Logical (32)
sllk(Register r1,Register r3,Register opnd)1627 void Assembler::sllk(Register r1, Register r3, Register opnd) {
1628 DCHECK(!opnd.is(r0));
1629 rsy_form(SLLK, r1, r3, opnd, 0);
1630 }
1631
1632 // Shift Left Single Logical (32)
sllk(Register r1,Register r3,const Operand & opnd)1633 void Assembler::sllk(Register r1, Register r3, const Operand& opnd) {
1634 rsy_form(SLLK, r1, r3, r0, opnd.immediate());
1635 }
1636
1637 // Shift Left Single Logical (64)
sllg(Register r1,Register r3,Register opnd)1638 void Assembler::sllg(Register r1, Register r3, Register opnd) {
1639 DCHECK(!opnd.is(r0));
1640 rsy_form(SLLG, r1, r3, opnd, 0);
1641 }
1642
1643 // Shift Left Single Logical (64)
sllg(Register r1,Register r3,const Operand & opnd)1644 void Assembler::sllg(Register r1, Register r3, const Operand& opnd) {
1645 rsy_form(SLLG, r1, r3, r0, opnd.immediate());
1646 }
1647
1648 // Shift Left Double Logical (64)
sldl(Register r1,Register b2,const Operand & opnd)1649 void Assembler::sldl(Register r1, Register b2, const Operand& opnd) {
1650 DCHECK(r1.code() % 2 == 0);
1651 rs_form(SLDL, r1, r0, b2, opnd.immediate());
1652 }
1653
1654 // Shift Right Single Logical (32)
srl(Register r1,Register opnd)1655 void Assembler::srl(Register r1, Register opnd) {
1656 DCHECK(!opnd.is(r0));
1657 rs_form(SRL, r1, r0, opnd, 0);
1658 }
1659
1660 // Shift Right Double Arith (64)
srda(Register r1,Register b2,const Operand & opnd)1661 void Assembler::srda(Register r1, Register b2, const Operand& opnd) {
1662 DCHECK(r1.code() % 2 == 0);
1663 rs_form(SRDA, r1, r0, b2, opnd.immediate());
1664 }
1665
1666 // Shift Right Double Logical (64)
srdl(Register r1,Register b2,const Operand & opnd)1667 void Assembler::srdl(Register r1, Register b2, const Operand& opnd) {
1668 DCHECK(r1.code() % 2 == 0);
1669 rs_form(SRDL, r1, r0, b2, opnd.immediate());
1670 }
1671
1672 // Shift Right Single Logical (32)
srl(Register r1,const Operand & opnd)1673 void Assembler::srl(Register r1, const Operand& opnd) {
1674 rs_form(SRL, r1, r0, r0, opnd.immediate());
1675 }
1676
1677 // Shift Right Single Logical (32)
srlk(Register r1,Register r3,Register opnd)1678 void Assembler::srlk(Register r1, Register r3, Register opnd) {
1679 DCHECK(!opnd.is(r0));
1680 rsy_form(SRLK, r1, r3, opnd, 0);
1681 }
1682
1683 // Shift Right Single Logical (32)
srlk(Register r1,Register r3,const Operand & opnd)1684 void Assembler::srlk(Register r1, Register r3, const Operand& opnd) {
1685 rsy_form(SRLK, r1, r3, r0, opnd.immediate());
1686 }
1687
1688 // Shift Right Single Logical (64)
srlg(Register r1,Register r3,Register opnd)1689 void Assembler::srlg(Register r1, Register r3, Register opnd) {
1690 DCHECK(!opnd.is(r0));
1691 rsy_form(SRLG, r1, r3, opnd, 0);
1692 }
1693
1694 // Shift Right Single Logical (64)
srlg(Register r1,Register r3,const Operand & opnd)1695 void Assembler::srlg(Register r1, Register r3, const Operand& opnd) {
1696 rsy_form(SRLG, r1, r3, r0, opnd.immediate());
1697 }
1698
1699 // Shift Left Single (32)
sla(Register r1,Register opnd)1700 void Assembler::sla(Register r1, Register opnd) {
1701 DCHECK(!opnd.is(r0));
1702 rs_form(SLA, r1, r0, opnd, 0);
1703 }
1704
1705 // Shift Left Single (32)
sla(Register r1,const Operand & opnd)1706 void Assembler::sla(Register r1, const Operand& opnd) {
1707 rs_form(SLA, r1, r0, r0, opnd.immediate());
1708 }
1709
1710 // Shift Left Single (32)
slak(Register r1,Register r3,Register opnd)1711 void Assembler::slak(Register r1, Register r3, Register opnd) {
1712 DCHECK(!opnd.is(r0));
1713 rsy_form(SLAK, r1, r3, opnd, 0);
1714 }
1715
1716 // Shift Left Single (32)
slak(Register r1,Register r3,const Operand & opnd)1717 void Assembler::slak(Register r1, Register r3, const Operand& opnd) {
1718 rsy_form(SLAK, r1, r3, r0, opnd.immediate());
1719 }
1720
1721 // Shift Left Single (64)
slag(Register r1,Register r3,Register opnd)1722 void Assembler::slag(Register r1, Register r3, Register opnd) {
1723 DCHECK(!opnd.is(r0));
1724 rsy_form(SLAG, r1, r3, opnd, 0);
1725 }
1726
1727 // Shift Left Single (64)
slag(Register r1,Register r3,const Operand & opnd)1728 void Assembler::slag(Register r1, Register r3, const Operand& opnd) {
1729 rsy_form(SLAG, r1, r3, r0, opnd.immediate());
1730 }
1731
1732 // Shift Right Single (32)
sra(Register r1,Register opnd)1733 void Assembler::sra(Register r1, Register opnd) {
1734 DCHECK(!opnd.is(r0));
1735 rs_form(SRA, r1, r0, opnd, 0);
1736 }
1737
1738 // Shift Right Single (32)
sra(Register r1,const Operand & opnd)1739 void Assembler::sra(Register r1, const Operand& opnd) {
1740 rs_form(SRA, r1, r0, r0, opnd.immediate());
1741 }
1742
1743 // Shift Right Single (32)
srak(Register r1,Register r3,Register opnd)1744 void Assembler::srak(Register r1, Register r3, Register opnd) {
1745 DCHECK(!opnd.is(r0));
1746 rsy_form(SRAK, r1, r3, opnd, 0);
1747 }
1748
1749 // Shift Right Single (32)
srak(Register r1,Register r3,const Operand & opnd)1750 void Assembler::srak(Register r1, Register r3, const Operand& opnd) {
1751 rsy_form(SRAK, r1, r3, r0, opnd.immediate());
1752 }
1753
1754 // Shift Right Single (64)
srag(Register r1,Register r3,Register opnd)1755 void Assembler::srag(Register r1, Register r3, Register opnd) {
1756 DCHECK(!opnd.is(r0));
1757 rsy_form(SRAG, r1, r3, opnd, 0);
1758 }
1759
srag(Register r1,Register r3,const Operand & opnd)1760 void Assembler::srag(Register r1, Register r3, const Operand& opnd) {
1761 rsy_form(SRAG, r1, r3, r0, opnd.immediate());
1762 }
1763
1764 // Shift Right Double
srda(Register r1,const Operand & opnd)1765 void Assembler::srda(Register r1, const Operand& opnd) {
1766 DCHECK(r1.code() % 2 == 0);
1767 rs_form(SRDA, r1, r0, r0, opnd.immediate());
1768 }
1769
1770 // Shift Right Double Logical
srdl(Register r1,const Operand & opnd)1771 void Assembler::srdl(Register r1, const Operand& opnd) {
1772 DCHECK(r1.code() % 2 == 0);
1773 rs_form(SRDL, r1, r0, r0, opnd.immediate());
1774 }
1775
call(Handle<Code> target,RelocInfo::Mode rmode,TypeFeedbackId ast_id)1776 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode,
1777 TypeFeedbackId ast_id) {
1778 EnsureSpace ensure_space(this);
1779
1780 int32_t target_index = emit_code_target(target, rmode, ast_id);
1781 brasl(r14, Operand(target_index));
1782 }
1783
jump(Handle<Code> target,RelocInfo::Mode rmode,Condition cond)1784 void Assembler::jump(Handle<Code> target, RelocInfo::Mode rmode,
1785 Condition cond) {
1786 EnsureSpace ensure_space(this);
1787
1788 int32_t target_index = emit_code_target(target, rmode);
1789 brcl(cond, Operand(target_index));
1790 }
1791
1792 // 32-bit Load Multiple - short displacement (12-bits unsigned)
lm(Register r1,Register r2,const MemOperand & src)1793 void Assembler::lm(Register r1, Register r2, const MemOperand& src) {
1794 rs_form(LM, r1, r2, src.rb(), src.offset());
1795 }
1796
1797 // 32-bit Load Multiple - long displacement (20-bits signed)
lmy(Register r1,Register r2,const MemOperand & src)1798 void Assembler::lmy(Register r1, Register r2, const MemOperand& src) {
1799 rsy_form(LMY, r1, r2, src.rb(), src.offset());
1800 }
1801
1802 // 64-bit Load Multiple - long displacement (20-bits signed)
lmg(Register r1,Register r2,const MemOperand & src)1803 void Assembler::lmg(Register r1, Register r2, const MemOperand& src) {
1804 rsy_form(LMG, r1, r2, src.rb(), src.offset());
1805 }
1806
1807 // Move integer (32)
mvhi(const MemOperand & opnd1,const Operand & i2)1808 void Assembler::mvhi(const MemOperand& opnd1, const Operand& i2) {
1809 sil_form(MVHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2);
1810 }
1811
1812 // Move integer (64)
mvghi(const MemOperand & opnd1,const Operand & i2)1813 void Assembler::mvghi(const MemOperand& opnd1, const Operand& i2) {
1814 sil_form(MVGHI, opnd1.getBaseRegister(), opnd1.getDisplacement(), i2);
1815 }
1816
1817 // Insert Immediate (high high)
iihh(Register r1,const Operand & opnd)1818 void Assembler::iihh(Register r1, const Operand& opnd) {
1819 ri_form(IIHH, r1, opnd);
1820 }
1821
1822 // Insert Immediate (high low)
iihl(Register r1,const Operand & opnd)1823 void Assembler::iihl(Register r1, const Operand& opnd) {
1824 ri_form(IIHL, r1, opnd);
1825 }
1826
1827 // Insert Immediate (low high)
iilh(Register r1,const Operand & opnd)1828 void Assembler::iilh(Register r1, const Operand& opnd) {
1829 ri_form(IILH, r1, opnd);
1830 }
1831
1832 // Insert Immediate (low low)
iill(Register r1,const Operand & opnd)1833 void Assembler::iill(Register r1, const Operand& opnd) {
1834 ri_form(IILL, r1, opnd);
1835 }
1836
1837 // GPR <-> FPR Instructions
1838
1839 // Floating point instructions
1840 //
1841 // Add Register-Storage (LB)
adb(DoubleRegister r1,const MemOperand & opnd)1842 void Assembler::adb(DoubleRegister r1, const MemOperand& opnd) {
1843 rxe_form(ADB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1844 opnd.offset());
1845 }
1846
1847 // Divide Register-Storage (LB)
ddb(DoubleRegister r1,const MemOperand & opnd)1848 void Assembler::ddb(DoubleRegister r1, const MemOperand& opnd) {
1849 rxe_form(DDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1850 opnd.offset());
1851 }
1852
1853 // Multiply Register-Storage (LB)
mdb(DoubleRegister r1,const MemOperand & opnd)1854 void Assembler::mdb(DoubleRegister r1, const MemOperand& opnd) {
1855 rxe_form(MDB, Register::from_code(r1.code()), opnd.rb(), opnd.rx(),
1856 opnd.offset());
1857 }
1858
1859 // Subtract Register-Storage (LB)
sdb(DoubleRegister r1,const MemOperand & opnd)1860 void Assembler::sdb(DoubleRegister r1, const MemOperand& opnd) {
1861 rxe_form(SDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1862 opnd.offset());
1863 }
1864
ceb(DoubleRegister r1,const MemOperand & opnd)1865 void Assembler::ceb(DoubleRegister r1, const MemOperand& opnd) {
1866 rxe_form(CEB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1867 opnd.offset());
1868 }
1869
cdb(DoubleRegister r1,const MemOperand & opnd)1870 void Assembler::cdb(DoubleRegister r1, const MemOperand& opnd) {
1871 rxe_form(CDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1872 opnd.offset());
1873 }
1874
1875 // Square Root (LB)
sqdb(DoubleRegister r1,const MemOperand & opnd)1876 void Assembler::sqdb(DoubleRegister r1, const MemOperand& opnd) {
1877 rxe_form(SQDB, Register::from_code(r1.code()), opnd.rx(), opnd.rb(),
1878 opnd.offset());
1879 }
1880
1881 // Convert to Fixed point (64<-S)
cgebr(Condition m,Register r1,DoubleRegister r2)1882 void Assembler::cgebr(Condition m, Register r1, DoubleRegister r2) {
1883 rrfe_form(CGEBR, m, Condition(0), r1, Register::from_code(r2.code()));
1884 }
1885
1886 // Convert to Fixed point (64<-L)
cgdbr(Condition m,Register r1,DoubleRegister r2)1887 void Assembler::cgdbr(Condition m, Register r1, DoubleRegister r2) {
1888 rrfe_form(CGDBR, m, Condition(0), r1, Register::from_code(r2.code()));
1889 }
1890
1891 // Convert to Fixed point (32<-L)
cfdbr(Condition m,Register r1,DoubleRegister r2)1892 void Assembler::cfdbr(Condition m, Register r1, DoubleRegister r2) {
1893 rrfe_form(CFDBR, m, Condition(0), r1, Register::from_code(r2.code()));
1894 }
1895
1896 // Convert to Fixed Logical (64<-L)
clgdbr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1897 void Assembler::clgdbr(Condition m3, Condition m4, Register r1,
1898 DoubleRegister r2) {
1899 DCHECK_EQ(m4, Condition(0));
1900 rrfe_form(CLGDBR, m3, m4, r1, Register::from_code(r2.code()));
1901 }
1902
1903 // Convert to Fixed Logical (64<-F32)
clgebr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1904 void Assembler::clgebr(Condition m3, Condition m4, Register r1,
1905 DoubleRegister r2) {
1906 DCHECK_EQ(m4, Condition(0));
1907 rrfe_form(CLGEBR, m3, m4, r1, Register::from_code(r2.code()));
1908 }
1909
1910 // Convert to Fixed Logical (32<-F64)
clfdbr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1911 void Assembler::clfdbr(Condition m3, Condition m4, Register r1,
1912 DoubleRegister r2) {
1913 DCHECK_EQ(m3, Condition(0));
1914 DCHECK_EQ(m4, Condition(0));
1915 rrfe_form(CLFDBR, Condition(0), Condition(0), r1,
1916 Register::from_code(r2.code()));
1917 }
1918
1919 // Convert to Fixed Logical (32<-F32)
clfebr(Condition m3,Condition m4,Register r1,DoubleRegister r2)1920 void Assembler::clfebr(Condition m3, Condition m4, Register r1,
1921 DoubleRegister r2) {
1922 DCHECK_EQ(m4, Condition(0));
1923 rrfe_form(CLFEBR, m3, Condition(0), r1, Register::from_code(r2.code()));
1924 }
1925
1926 // Convert from Fixed Logical (L<-64)
celgbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1927 void Assembler::celgbr(Condition m3, Condition m4, DoubleRegister r1,
1928 Register r2) {
1929 DCHECK_EQ(m3, Condition(0));
1930 DCHECK_EQ(m4, Condition(0));
1931 rrfe_form(CELGBR, Condition(0), Condition(0), Register::from_code(r1.code()),
1932 r2);
1933 }
1934
1935 // Convert from Fixed Logical (F32<-32)
celfbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1936 void Assembler::celfbr(Condition m3, Condition m4, DoubleRegister r1,
1937 Register r2) {
1938 DCHECK_EQ(m4, Condition(0));
1939 rrfe_form(CELFBR, m3, Condition(0), Register::from_code(r1.code()), r2);
1940 }
1941
1942 // Convert from Fixed Logical (L<-64)
cdlgbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1943 void Assembler::cdlgbr(Condition m3, Condition m4, DoubleRegister r1,
1944 Register r2) {
1945 DCHECK_EQ(m3, Condition(0));
1946 DCHECK_EQ(m4, Condition(0));
1947 rrfe_form(CDLGBR, Condition(0), Condition(0), Register::from_code(r1.code()),
1948 r2);
1949 }
1950
1951 // Convert from Fixed Logical (L<-32)
cdlfbr(Condition m3,Condition m4,DoubleRegister r1,Register r2)1952 void Assembler::cdlfbr(Condition m3, Condition m4, DoubleRegister r1,
1953 Register r2) {
1954 DCHECK_EQ(m4, Condition(0));
1955 rrfe_form(CDLFBR, m3, Condition(0), Register::from_code(r1.code()), r2);
1956 }
1957
1958 // Convert from Fixed point (S<-32)
cefbr(Condition m3,DoubleRegister r1,Register r2)1959 void Assembler::cefbr(Condition m3, DoubleRegister r1, Register r2) {
1960 rrfe_form(CEFBR, m3, Condition(0), Register::from_code(r1.code()), r2);
1961 }
1962
1963 // Convert to Fixed point (32<-S)
cfebr(Condition m3,Register r1,DoubleRegister r2)1964 void Assembler::cfebr(Condition m3, Register r1, DoubleRegister r2) {
1965 rrfe_form(CFEBR, m3, Condition(0), r1, Register::from_code(r2.code()));
1966 }
1967
1968 // Load (L <- S)
ldeb(DoubleRegister d1,const MemOperand & opnd)1969 void Assembler::ldeb(DoubleRegister d1, const MemOperand& opnd) {
1970 rxe_form(LDEB, Register::from_code(d1.code()), opnd.rx(), opnd.rb(),
1971 opnd.offset());
1972 }
1973
1974 // Load FP Integer
fiebra(DoubleRegister d1,DoubleRegister d2,FIDBRA_MASK3 m3)1975 void Assembler::fiebra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) {
1976 rrf2_form(FIEBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code());
1977 }
1978
1979 // Load FP Integer
fidbra(DoubleRegister d1,DoubleRegister d2,FIDBRA_MASK3 m3)1980 void Assembler::fidbra(DoubleRegister d1, DoubleRegister d2, FIDBRA_MASK3 m3) {
1981 rrf2_form(FIDBRA << 16 | m3 * B12 | d1.code() * B4 | d2.code());
1982 }
1983
1984 // end of S390instructions
1985
IsNop(SixByteInstr instr,int type)1986 bool Assembler::IsNop(SixByteInstr instr, int type) {
1987 DCHECK((0 == type) || (DEBUG_BREAK_NOP == type));
1988 if (DEBUG_BREAK_NOP == type) {
1989 return ((instr & 0xffffffff) == 0xa53b0000); // oill r3, 0
1990 }
1991 return ((instr & 0xffff) == 0x1800); // lr r0,r0
1992 }
1993
1994 // dummy instruction reserved for special use.
dumy(int r1,int x2,int b2,int d2)1995 void Assembler::dumy(int r1, int x2, int b2, int d2) {
1996 #if defined(USE_SIMULATOR)
1997 int op = 0xE353;
1998 uint64_t code = (static_cast<uint64_t>(op & 0xFF00)) * B32 |
1999 (static_cast<uint64_t>(r1) & 0xF) * B36 |
2000 (static_cast<uint64_t>(x2) & 0xF) * B32 |
2001 (static_cast<uint64_t>(b2) & 0xF) * B28 |
2002 (static_cast<uint64_t>(d2 & 0x0FFF)) * B16 |
2003 (static_cast<uint64_t>(d2 & 0x0FF000)) >> 4 |
2004 (static_cast<uint64_t>(op & 0x00FF));
2005 emit6bytes(code);
2006 #endif
2007 }
2008
GrowBuffer(int needed)2009 void Assembler::GrowBuffer(int needed) {
2010 if (!own_buffer_) FATAL("external code buffer is too small");
2011
2012 // Compute new buffer size.
2013 CodeDesc desc; // the new buffer
2014 if (buffer_size_ < 4 * KB) {
2015 desc.buffer_size = 4 * KB;
2016 } else if (buffer_size_ < 1 * MB) {
2017 desc.buffer_size = 2 * buffer_size_;
2018 } else {
2019 desc.buffer_size = buffer_size_ + 1 * MB;
2020 }
2021 int space = buffer_space() + (desc.buffer_size - buffer_size_);
2022 if (space < needed) {
2023 desc.buffer_size += needed - space;
2024 }
2025 CHECK_GT(desc.buffer_size, 0); // no overflow
2026
2027 // Set up new buffer.
2028 desc.buffer = NewArray<byte>(desc.buffer_size);
2029 desc.origin = this;
2030
2031 desc.instr_size = pc_offset();
2032 desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2033
2034 // Copy the data.
2035 intptr_t pc_delta = desc.buffer - buffer_;
2036 intptr_t rc_delta =
2037 (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2038 memmove(desc.buffer, buffer_, desc.instr_size);
2039 memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
2040 desc.reloc_size);
2041
2042 // Switch buffers.
2043 DeleteArray(buffer_);
2044 buffer_ = desc.buffer;
2045 buffer_size_ = desc.buffer_size;
2046 pc_ += pc_delta;
2047 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2048 reloc_info_writer.last_pc() + pc_delta);
2049
2050 // None of our relocation types are pc relative pointing outside the code
2051 // buffer nor pc absolute pointing inside the code buffer, so there is no need
2052 // to relocate any emitted relocation entries.
2053 }
2054
db(uint8_t data)2055 void Assembler::db(uint8_t data) {
2056 CheckBuffer();
2057 *reinterpret_cast<uint8_t*>(pc_) = data;
2058 pc_ += sizeof(uint8_t);
2059 }
2060
dd(uint32_t data)2061 void Assembler::dd(uint32_t data) {
2062 CheckBuffer();
2063 *reinterpret_cast<uint32_t*>(pc_) = data;
2064 pc_ += sizeof(uint32_t);
2065 }
2066
dq(uint64_t value)2067 void Assembler::dq(uint64_t value) {
2068 CheckBuffer();
2069 *reinterpret_cast<uint64_t*>(pc_) = value;
2070 pc_ += sizeof(uint64_t);
2071 }
2072
dp(uintptr_t data)2073 void Assembler::dp(uintptr_t data) {
2074 CheckBuffer();
2075 *reinterpret_cast<uintptr_t*>(pc_) = data;
2076 pc_ += sizeof(uintptr_t);
2077 }
2078
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2079 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2080 if (RelocInfo::IsNone(rmode) ||
2081 // Don't record external references unless the heap will be serialized.
2082 (rmode == RelocInfo::EXTERNAL_REFERENCE && !serializer_enabled() &&
2083 !emit_debug_code())) {
2084 return;
2085 }
2086 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2087 data = RecordedAstId().ToInt();
2088 ClearRecordedAstId();
2089 }
2090 DeferredRelocInfo rinfo(pc_offset(), rmode, data);
2091 relocations_.push_back(rinfo);
2092 }
2093
emit_label_addr(Label * label)2094 void Assembler::emit_label_addr(Label* label) {
2095 CheckBuffer();
2096 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2097 int position = link(label);
2098 DCHECK(label->is_bound());
2099 // Keep internal references relative until EmitRelocations.
2100 dp(position);
2101 }
2102
EmitRelocations()2103 void Assembler::EmitRelocations() {
2104 EnsureSpaceFor(relocations_.size() * kMaxRelocSize);
2105
2106 for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin();
2107 it != relocations_.end(); it++) {
2108 RelocInfo::Mode rmode = it->rmode();
2109 Address pc = buffer_ + it->position();
2110 Code* code = NULL;
2111 RelocInfo rinfo(isolate(), pc, rmode, it->data(), code);
2112
2113 // Fix up internal references now that they are guaranteed to be bound.
2114 if (RelocInfo::IsInternalReference(rmode)) {
2115 // Jump table entry
2116 intptr_t pos = reinterpret_cast<intptr_t>(Memory::Address_at(pc));
2117 Memory::Address_at(pc) = buffer_ + pos;
2118 } else if (RelocInfo::IsInternalReferenceEncoded(rmode)) {
2119 // mov sequence
2120 intptr_t pos = reinterpret_cast<intptr_t>(target_address_at(pc, code));
2121 set_target_address_at(isolate(), pc, code, buffer_ + pos,
2122 SKIP_ICACHE_FLUSH);
2123 }
2124
2125 reloc_info_writer.Write(&rinfo);
2126 }
2127 }
2128
2129 } // namespace internal
2130 } // namespace v8
2131 #endif // V8_TARGET_ARCH_S390
2132