Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/cpu/x86/assembler_x86.cpp
41145 views
1
/*
2
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "asm/assembler.hpp"
27
#include "asm/assembler.inline.hpp"
28
#include "gc/shared/cardTableBarrierSet.hpp"
29
#include "gc/shared/collectedHeap.inline.hpp"
30
#include "interpreter/interpreter.hpp"
31
#include "memory/resourceArea.hpp"
32
#include "prims/methodHandles.hpp"
33
#include "runtime/biasedLocking.hpp"
34
#include "runtime/objectMonitor.hpp"
35
#include "runtime/os.hpp"
36
#include "runtime/sharedRuntime.hpp"
37
#include "runtime/stubRoutines.hpp"
38
#include "runtime/vm_version.hpp"
39
#include "utilities/macros.hpp"
40
41
#ifdef PRODUCT
42
#define BLOCK_COMMENT(str) /* nothing */
43
#define STOP(error) stop(error)
44
#else
45
#define BLOCK_COMMENT(str) block_comment(str)
46
#define STOP(error) block_comment(error); stop(error)
47
#endif
48
49
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
50
// Implementation of AddressLiteral
51
52
// A 2-D table for managing compressed displacement(disp8) on EVEX enabled platforms.
53
unsigned char tuple_table[Assembler::EVEX_ETUP + 1][Assembler::AVX_512bit + 1] = {
54
// -----------------Table 4.5 -------------------- //
55
16, 32, 64, // EVEX_FV(0)
56
4, 4, 4, // EVEX_FV(1) - with Evex.b
57
16, 32, 64, // EVEX_FV(2) - with Evex.w
58
8, 8, 8, // EVEX_FV(3) - with Evex.w and Evex.b
59
8, 16, 32, // EVEX_HV(0)
60
4, 4, 4, // EVEX_HV(1) - with Evex.b
61
// -----------------Table 4.6 -------------------- //
62
16, 32, 64, // EVEX_FVM(0)
63
1, 1, 1, // EVEX_T1S(0)
64
2, 2, 2, // EVEX_T1S(1)
65
4, 4, 4, // EVEX_T1S(2)
66
8, 8, 8, // EVEX_T1S(3)
67
4, 4, 4, // EVEX_T1F(0)
68
8, 8, 8, // EVEX_T1F(1)
69
8, 8, 8, // EVEX_T2(0)
70
0, 16, 16, // EVEX_T2(1)
71
0, 16, 16, // EVEX_T4(0)
72
0, 0, 32, // EVEX_T4(1)
73
0, 0, 32, // EVEX_T8(0)
74
8, 16, 32, // EVEX_HVM(0)
75
4, 8, 16, // EVEX_QVM(0)
76
2, 4, 8, // EVEX_OVM(0)
77
16, 16, 16, // EVEX_M128(0)
78
8, 32, 64, // EVEX_DUP(0)
79
0, 0, 0 // EVEX_NTUP
80
};
81
82
AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) {
83
_is_lval = false;
84
_target = target;
85
switch (rtype) {
86
case relocInfo::oop_type:
87
case relocInfo::metadata_type:
88
// Oops are a special case. Normally they would be their own section
89
// but in cases like icBuffer they are literals in the code stream that
90
// we don't have a section for. We use none so that we get a literal address
91
// which is always patchable.
92
break;
93
case relocInfo::external_word_type:
94
_rspec = external_word_Relocation::spec(target);
95
break;
96
case relocInfo::internal_word_type:
97
_rspec = internal_word_Relocation::spec(target);
98
break;
99
case relocInfo::opt_virtual_call_type:
100
_rspec = opt_virtual_call_Relocation::spec();
101
break;
102
case relocInfo::static_call_type:
103
_rspec = static_call_Relocation::spec();
104
break;
105
case relocInfo::runtime_call_type:
106
_rspec = runtime_call_Relocation::spec();
107
break;
108
case relocInfo::poll_type:
109
case relocInfo::poll_return_type:
110
_rspec = Relocation::spec_simple(rtype);
111
break;
112
case relocInfo::none:
113
break;
114
default:
115
ShouldNotReachHere();
116
break;
117
}
118
}
119
120
// Implementation of Address
121
122
#ifdef _LP64
123
124
Address Address::make_array(ArrayAddress adr) {
125
// Not implementable on 64bit machines
126
// Should have been handled higher up the call chain.
127
ShouldNotReachHere();
128
return Address();
129
}
130
131
// exceedingly dangerous constructor
132
Address::Address(int disp, address loc, relocInfo::relocType rtype) {
133
_base = noreg;
134
_index = noreg;
135
_scale = no_scale;
136
_disp = disp;
137
_xmmindex = xnoreg;
138
_isxmmindex = false;
139
switch (rtype) {
140
case relocInfo::external_word_type:
141
_rspec = external_word_Relocation::spec(loc);
142
break;
143
case relocInfo::internal_word_type:
144
_rspec = internal_word_Relocation::spec(loc);
145
break;
146
case relocInfo::runtime_call_type:
147
// HMM
148
_rspec = runtime_call_Relocation::spec();
149
break;
150
case relocInfo::poll_type:
151
case relocInfo::poll_return_type:
152
_rspec = Relocation::spec_simple(rtype);
153
break;
154
case relocInfo::none:
155
break;
156
default:
157
ShouldNotReachHere();
158
}
159
}
160
#else // LP64
161
162
Address Address::make_array(ArrayAddress adr) {
163
AddressLiteral base = adr.base();
164
Address index = adr.index();
165
assert(index._disp == 0, "must not have disp"); // maybe it can?
166
Address array(index._base, index._index, index._scale, (intptr_t) base.target());
167
array._rspec = base._rspec;
168
return array;
169
}
170
171
// exceedingly dangerous constructor
172
Address::Address(address loc, RelocationHolder spec) {
173
_base = noreg;
174
_index = noreg;
175
_scale = no_scale;
176
_disp = (intptr_t) loc;
177
_rspec = spec;
178
_xmmindex = xnoreg;
179
_isxmmindex = false;
180
}
181
182
#endif // _LP64
183
184
185
186
// Convert the raw encoding form into the form expected by the constructor for
187
// Address. An index of 4 (rsp) corresponds to having no index, so convert
188
// that to noreg for the Address constructor.
189
Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) {
190
RelocationHolder rspec;
191
if (disp_reloc != relocInfo::none) {
192
rspec = Relocation::spec_simple(disp_reloc);
193
}
194
bool valid_index = index != rsp->encoding();
195
if (valid_index) {
196
Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp));
197
madr._rspec = rspec;
198
return madr;
199
} else {
200
Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp));
201
madr._rspec = rspec;
202
return madr;
203
}
204
}
205
206
// Implementation of Assembler
207
208
int AbstractAssembler::code_fill_byte() {
209
return (u_char)'\xF4'; // hlt
210
}
211
212
void Assembler::init_attributes(void) {
213
_legacy_mode_bw = (VM_Version::supports_avx512bw() == false);
214
_legacy_mode_dq = (VM_Version::supports_avx512dq() == false);
215
_legacy_mode_vl = (VM_Version::supports_avx512vl() == false);
216
_legacy_mode_vlbw = (VM_Version::supports_avx512vlbw() == false);
217
NOT_LP64(_is_managed = false;)
218
_attributes = NULL;
219
}
220
221
222
void Assembler::membar(Membar_mask_bits order_constraint) {
223
// We only have to handle StoreLoad
224
if (order_constraint & StoreLoad) {
225
// All usable chips support "locked" instructions which suffice
226
// as barriers, and are much faster than the alternative of
227
// using cpuid instruction. We use here a locked add [esp-C],0.
228
// This is conveniently otherwise a no-op except for blowing
229
// flags, and introducing a false dependency on target memory
230
// location. We can't do anything with flags, but we can avoid
231
// memory dependencies in the current method by locked-adding
232
// somewhere else on the stack. Doing [esp+C] will collide with
233
// something on stack in current method, hence we go for [esp-C].
234
// It is convenient since it is almost always in data cache, for
235
// any small C. We need to step back from SP to avoid data
236
// dependencies with other things on below SP (callee-saves, for
237
// example). Without a clear way to figure out the minimal safe
238
// distance from SP, it makes sense to step back the complete
239
// cache line, as this will also avoid possible second-order effects
240
// with locked ops against the cache line. Our choice of offset
241
// is bounded by x86 operand encoding, which should stay within
242
// [-128; +127] to have the 8-byte displacement encoding.
243
//
244
// Any change to this code may need to revisit other places in
245
// the code where this idiom is used, in particular the
246
// orderAccess code.
247
248
int offset = -VM_Version::L1_line_size();
249
if (offset < -128) {
250
offset = -128;
251
}
252
253
lock();
254
addl(Address(rsp, offset), 0);// Assert the lock# signal here
255
}
256
}
257
258
// make this go away someday
259
void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) {
260
if (rtype == relocInfo::none)
261
emit_int32(data);
262
else
263
emit_data(data, Relocation::spec_simple(rtype), format);
264
}
265
266
void Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) {
267
assert(imm_operand == 0, "default format must be immediate in this file");
268
assert(inst_mark() != NULL, "must be inside InstructionMark");
269
if (rspec.type() != relocInfo::none) {
270
#ifdef ASSERT
271
check_relocation(rspec, format);
272
#endif
273
// Do not use AbstractAssembler::relocate, which is not intended for
274
// embedded words. Instead, relocate to the enclosing instruction.
275
276
// hack. call32 is too wide for mask so use disp32
277
if (format == call32_operand)
278
code_section()->relocate(inst_mark(), rspec, disp32_operand);
279
else
280
code_section()->relocate(inst_mark(), rspec, format);
281
}
282
emit_int32(data);
283
}
284
285
static int encode(Register r) {
286
int enc = r->encoding();
287
if (enc >= 8) {
288
enc -= 8;
289
}
290
return enc;
291
}
292
293
void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
294
assert(dst->has_byte_register(), "must have byte register");
295
assert(isByte(op1) && isByte(op2), "wrong opcode");
296
assert(isByte(imm8), "not a byte");
297
assert((op1 & 0x01) == 0, "should be 8bit operation");
298
emit_int24(op1, (op2 | encode(dst)), imm8);
299
}
300
301
302
void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) {
303
assert(isByte(op1) && isByte(op2), "wrong opcode");
304
assert((op1 & 0x01) == 1, "should be 32bit operation");
305
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
306
if (is8bit(imm32)) {
307
emit_int24(op1 | 0x02, // set sign bit
308
op2 | encode(dst),
309
imm32 & 0xFF);
310
} else {
311
emit_int16(op1, (op2 | encode(dst)));
312
emit_int32(imm32);
313
}
314
}
315
316
// Force generation of a 4 byte immediate value even if it fits into 8bit
317
void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) {
318
assert(isByte(op1) && isByte(op2), "wrong opcode");
319
assert((op1 & 0x01) == 1, "should be 32bit operation");
320
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
321
emit_int16(op1, (op2 | encode(dst)));
322
emit_int32(imm32);
323
}
324
325
// immediate-to-memory forms
326
void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) {
327
assert((op1 & 0x01) == 1, "should be 32bit operation");
328
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
329
if (is8bit(imm32)) {
330
emit_int8(op1 | 0x02); // set sign bit
331
emit_operand(rm, adr, 1);
332
emit_int8(imm32 & 0xFF);
333
} else {
334
emit_int8(op1);
335
emit_operand(rm, adr, 4);
336
emit_int32(imm32);
337
}
338
}
339
340
341
void Assembler::emit_arith(int op1, int op2, Register dst, Register src) {
342
assert(isByte(op1) && isByte(op2), "wrong opcode");
343
emit_int16(op1, (op2 | encode(dst) << 3 | encode(src)));
344
}
345
346
347
bool Assembler::query_compressed_disp_byte(int disp, bool is_evex_inst, int vector_len,
348
int cur_tuple_type, int in_size_in_bits, int cur_encoding) {
349
int mod_idx = 0;
350
// We will test if the displacement fits the compressed format and if so
351
// apply the compression to the displacment iff the result is8bit.
352
if (VM_Version::supports_evex() && is_evex_inst) {
353
switch (cur_tuple_type) {
354
case EVEX_FV:
355
if ((cur_encoding & VEX_W) == VEX_W) {
356
mod_idx = ((cur_encoding & EVEX_Rb) == EVEX_Rb) ? 3 : 2;
357
} else {
358
mod_idx = ((cur_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
359
}
360
break;
361
362
case EVEX_HV:
363
mod_idx = ((cur_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
364
break;
365
366
case EVEX_FVM:
367
break;
368
369
case EVEX_T1S:
370
switch (in_size_in_bits) {
371
case EVEX_8bit:
372
break;
373
374
case EVEX_16bit:
375
mod_idx = 1;
376
break;
377
378
case EVEX_32bit:
379
mod_idx = 2;
380
break;
381
382
case EVEX_64bit:
383
mod_idx = 3;
384
break;
385
}
386
break;
387
388
case EVEX_T1F:
389
case EVEX_T2:
390
case EVEX_T4:
391
mod_idx = (in_size_in_bits == EVEX_64bit) ? 1 : 0;
392
break;
393
394
case EVEX_T8:
395
break;
396
397
case EVEX_HVM:
398
break;
399
400
case EVEX_QVM:
401
break;
402
403
case EVEX_OVM:
404
break;
405
406
case EVEX_M128:
407
break;
408
409
case EVEX_DUP:
410
break;
411
412
default:
413
assert(0, "no valid evex tuple_table entry");
414
break;
415
}
416
417
if (vector_len >= AVX_128bit && vector_len <= AVX_512bit) {
418
int disp_factor = tuple_table[cur_tuple_type + mod_idx][vector_len];
419
if ((disp % disp_factor) == 0) {
420
int new_disp = disp / disp_factor;
421
if ((-0x80 <= new_disp && new_disp < 0x80)) {
422
disp = new_disp;
423
}
424
} else {
425
return false;
426
}
427
}
428
}
429
return (-0x80 <= disp && disp < 0x80);
430
}
431
432
433
bool Assembler::emit_compressed_disp_byte(int &disp) {
434
int mod_idx = 0;
435
// We will test if the displacement fits the compressed format and if so
436
// apply the compression to the displacment iff the result is8bit.
437
if (VM_Version::supports_evex() && _attributes && _attributes->is_evex_instruction()) {
438
int evex_encoding = _attributes->get_evex_encoding();
439
int tuple_type = _attributes->get_tuple_type();
440
switch (tuple_type) {
441
case EVEX_FV:
442
if ((evex_encoding & VEX_W) == VEX_W) {
443
mod_idx = ((evex_encoding & EVEX_Rb) == EVEX_Rb) ? 3 : 2;
444
} else {
445
mod_idx = ((evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
446
}
447
break;
448
449
case EVEX_HV:
450
mod_idx = ((evex_encoding & EVEX_Rb) == EVEX_Rb) ? 1 : 0;
451
break;
452
453
case EVEX_FVM:
454
break;
455
456
case EVEX_T1S:
457
switch (_attributes->get_input_size()) {
458
case EVEX_8bit:
459
break;
460
461
case EVEX_16bit:
462
mod_idx = 1;
463
break;
464
465
case EVEX_32bit:
466
mod_idx = 2;
467
break;
468
469
case EVEX_64bit:
470
mod_idx = 3;
471
break;
472
}
473
break;
474
475
case EVEX_T1F:
476
case EVEX_T2:
477
case EVEX_T4:
478
mod_idx = (_attributes->get_input_size() == EVEX_64bit) ? 1 : 0;
479
break;
480
481
case EVEX_T8:
482
break;
483
484
case EVEX_HVM:
485
break;
486
487
case EVEX_QVM:
488
break;
489
490
case EVEX_OVM:
491
break;
492
493
case EVEX_M128:
494
break;
495
496
case EVEX_DUP:
497
break;
498
499
default:
500
assert(0, "no valid evex tuple_table entry");
501
break;
502
}
503
504
int vector_len = _attributes->get_vector_len();
505
if (vector_len >= AVX_128bit && vector_len <= AVX_512bit) {
506
int disp_factor = tuple_table[tuple_type + mod_idx][vector_len];
507
if ((disp % disp_factor) == 0) {
508
int new_disp = disp / disp_factor;
509
if (is8bit(new_disp)) {
510
disp = new_disp;
511
}
512
} else {
513
return false;
514
}
515
}
516
}
517
return is8bit(disp);
518
}
519
520
static bool is_valid_encoding(int reg_enc) {
521
return reg_enc >= 0;
522
}
523
524
static int raw_encode(Register reg) {
525
assert(reg == noreg || reg->is_valid(), "sanity");
526
int reg_enc = (intptr_t)reg;
527
assert(reg_enc == -1 || is_valid_encoding(reg_enc), "sanity");
528
return reg_enc;
529
}
530
531
static int raw_encode(XMMRegister xmmreg) {
532
assert(xmmreg == xnoreg || xmmreg->is_valid(), "sanity");
533
int xmmreg_enc = (intptr_t)xmmreg;
534
assert(xmmreg_enc == -1 || is_valid_encoding(xmmreg_enc), "sanity");
535
return xmmreg_enc;
536
}
537
538
static int modrm_encoding(int mod, int dst_enc, int src_enc) {
539
return (mod & 3) << 6 | (dst_enc & 7) << 3 | (src_enc & 7);
540
}
541
542
static int sib_encoding(Address::ScaleFactor scale, int index_enc, int base_enc) {
543
return (scale & 3) << 6 | (index_enc & 7) << 3 | (base_enc & 7);
544
}
545
546
inline void Assembler::emit_modrm(int mod, int dst_enc, int src_enc) {
547
assert((mod & 3) != 0b11, "forbidden");
548
int modrm = modrm_encoding(mod, dst_enc, src_enc);
549
emit_int8(modrm);
550
}
551
552
inline void Assembler::emit_modrm_disp8(int mod, int dst_enc, int src_enc,
553
int disp) {
554
int modrm = modrm_encoding(mod, dst_enc, src_enc);
555
emit_int16(modrm, disp & 0xFF);
556
}
557
558
inline void Assembler::emit_modrm_sib(int mod, int dst_enc, int src_enc,
559
Address::ScaleFactor scale, int index_enc, int base_enc) {
560
int modrm = modrm_encoding(mod, dst_enc, src_enc);
561
int sib = sib_encoding(scale, index_enc, base_enc);
562
emit_int16(modrm, sib);
563
}
564
565
inline void Assembler::emit_modrm_sib_disp8(int mod, int dst_enc, int src_enc,
566
Address::ScaleFactor scale, int index_enc, int base_enc,
567
int disp) {
568
int modrm = modrm_encoding(mod, dst_enc, src_enc);
569
int sib = sib_encoding(scale, index_enc, base_enc);
570
emit_int24(modrm, sib, disp & 0xFF);
571
}
572
573
void Assembler::emit_operand_helper(int reg_enc, int base_enc, int index_enc,
574
Address::ScaleFactor scale, int disp,
575
RelocationHolder const& rspec,
576
int rip_relative_correction) {
577
bool no_relocation = (rspec.type() == relocInfo::none);
578
579
if (is_valid_encoding(base_enc)) {
580
if (is_valid_encoding(index_enc)) {
581
assert(scale != Address::no_scale, "inconsistent address");
582
// [base + index*scale + disp]
583
if (disp == 0 && no_relocation &&
584
base_enc != rbp->encoding() LP64_ONLY(&& base_enc != r13->encoding())) {
585
// [base + index*scale]
586
// [00 reg 100][ss index base]
587
emit_modrm_sib(0b00, reg_enc, 0b100,
588
scale, index_enc, base_enc);
589
} else if (emit_compressed_disp_byte(disp) && no_relocation) {
590
// [base + index*scale + imm8]
591
// [01 reg 100][ss index base] imm8
592
emit_modrm_sib_disp8(0b01, reg_enc, 0b100,
593
scale, index_enc, base_enc,
594
disp);
595
} else {
596
// [base + index*scale + disp32]
597
// [10 reg 100][ss index base] disp32
598
emit_modrm_sib(0b10, reg_enc, 0b100,
599
scale, index_enc, base_enc);
600
emit_data(disp, rspec, disp32_operand);
601
}
602
} else if (base_enc == rsp->encoding() LP64_ONLY(|| base_enc == r12->encoding())) {
603
// [rsp + disp]
604
if (disp == 0 && no_relocation) {
605
// [rsp]
606
// [00 reg 100][00 100 100]
607
emit_modrm_sib(0b00, reg_enc, 0b100,
608
Address::times_1, 0b100, 0b100);
609
} else if (emit_compressed_disp_byte(disp) && no_relocation) {
610
// [rsp + imm8]
611
// [01 reg 100][00 100 100] disp8
612
emit_modrm_sib_disp8(0b01, reg_enc, 0b100,
613
Address::times_1, 0b100, 0b100,
614
disp);
615
} else {
616
// [rsp + imm32]
617
// [10 reg 100][00 100 100] disp32
618
emit_modrm_sib(0b10, reg_enc, 0b100,
619
Address::times_1, 0b100, 0b100);
620
emit_data(disp, rspec, disp32_operand);
621
}
622
} else {
623
// [base + disp]
624
assert(base_enc != rsp->encoding() LP64_ONLY(&& base_enc != r12->encoding()), "illegal addressing mode");
625
if (disp == 0 && no_relocation &&
626
base_enc != rbp->encoding() LP64_ONLY(&& base_enc != r13->encoding())) {
627
// [base]
628
// [00 reg base]
629
emit_modrm(0, reg_enc, base_enc);
630
} else if (emit_compressed_disp_byte(disp) && no_relocation) {
631
// [base + disp8]
632
// [01 reg base] disp8
633
emit_modrm_disp8(0b01, reg_enc, base_enc,
634
disp);
635
} else {
636
// [base + disp32]
637
// [10 reg base] disp32
638
emit_modrm(0b10, reg_enc, base_enc);
639
emit_data(disp, rspec, disp32_operand);
640
}
641
}
642
} else {
643
if (is_valid_encoding(index_enc)) {
644
assert(scale != Address::no_scale, "inconsistent address");
645
// base == noreg
646
// [index*scale + disp]
647
// [00 reg 100][ss index 101] disp32
648
emit_modrm_sib(0b00, reg_enc, 0b100,
649
scale, index_enc, 0b101 /* no base */);
650
emit_data(disp, rspec, disp32_operand);
651
} else if (!no_relocation) {
652
// base == noreg, index == noreg
653
// [disp] (64bit) RIP-RELATIVE (32bit) abs
654
// [00 reg 101] disp32
655
656
emit_modrm(0b00, reg_enc, 0b101 /* no base */);
657
// Note that the RIP-rel. correction applies to the generated
658
// disp field, but _not_ to the target address in the rspec.
659
660
// disp was created by converting the target address minus the pc
661
// at the start of the instruction. That needs more correction here.
662
// intptr_t disp = target - next_ip;
663
assert(inst_mark() != NULL, "must be inside InstructionMark");
664
address next_ip = pc() + sizeof(int32_t) + rip_relative_correction;
665
int64_t adjusted = disp;
666
// Do rip-rel adjustment for 64bit
667
LP64_ONLY(adjusted -= (next_ip - inst_mark()));
668
assert(is_simm32(adjusted),
669
"must be 32bit offset (RIP relative address)");
670
emit_data((int32_t) adjusted, rspec, disp32_operand);
671
672
} else {
673
// base == noreg, index == noreg, no_relocation == true
674
// 32bit never did this, did everything as the rip-rel/disp code above
675
// [disp] ABSOLUTE
676
// [00 reg 100][00 100 101] disp32
677
emit_modrm_sib(0b00, reg_enc, 0b100 /* no base */,
678
Address::times_1, 0b100, 0b101);
679
emit_data(disp, rspec, disp32_operand);
680
}
681
}
682
}
683
684
void Assembler::emit_operand(Register reg, Register base, Register index,
685
Address::ScaleFactor scale, int disp,
686
RelocationHolder const& rspec,
687
int rip_relative_correction) {
688
assert(!index->is_valid() || index != rsp, "illegal addressing mode");
689
emit_operand_helper(raw_encode(reg), raw_encode(base), raw_encode(index),
690
scale, disp, rspec, rip_relative_correction);
691
692
}
693
void Assembler::emit_operand(XMMRegister xmmreg, Register base, Register index,
694
Address::ScaleFactor scale, int disp,
695
RelocationHolder const& rspec) {
696
assert(!index->is_valid() || index != rsp, "illegal addressing mode");
697
assert(xmmreg->encoding() < 16 || UseAVX > 2, "not supported");
698
emit_operand_helper(raw_encode(xmmreg), raw_encode(base), raw_encode(index),
699
scale, disp, rspec);
700
}
701
702
void Assembler::emit_operand(XMMRegister xmmreg, Register base, XMMRegister xmmindex,
703
Address::ScaleFactor scale, int disp,
704
RelocationHolder const& rspec) {
705
assert(xmmreg->encoding() < 16 || UseAVX > 2, "not supported");
706
assert(xmmindex->encoding() < 16 || UseAVX > 2, "not supported");
707
emit_operand_helper(raw_encode(xmmreg), raw_encode(base), raw_encode(xmmindex),
708
scale, disp, rspec, /* rip_relative_correction */ 0);
709
}
710
711
// Secret local extension to Assembler::WhichOperand:
712
#define end_pc_operand (_WhichOperand_limit)
713
714
address Assembler::locate_operand(address inst, WhichOperand which) {
715
// Decode the given instruction, and return the address of
716
// an embedded 32-bit operand word.
717
718
// If "which" is disp32_operand, selects the displacement portion
719
// of an effective address specifier.
720
// If "which" is imm64_operand, selects the trailing immediate constant.
721
// If "which" is call32_operand, selects the displacement of a call or jump.
722
// Caller is responsible for ensuring that there is such an operand,
723
// and that it is 32/64 bits wide.
724
725
// If "which" is end_pc_operand, find the end of the instruction.
726
727
address ip = inst;
728
bool is_64bit = false;
729
730
debug_only(bool has_disp32 = false);
731
int tail_size = 0; // other random bytes (#32, #16, etc.) at end of insn
732
733
again_after_prefix:
734
switch (0xFF & *ip++) {
735
736
// These convenience macros generate groups of "case" labels for the switch.
737
#define REP4(x) (x)+0: case (x)+1: case (x)+2: case (x)+3
738
#define REP8(x) (x)+0: case (x)+1: case (x)+2: case (x)+3: \
739
case (x)+4: case (x)+5: case (x)+6: case (x)+7
740
#define REP16(x) REP8((x)+0): \
741
case REP8((x)+8)
742
743
case CS_segment:
744
case SS_segment:
745
case DS_segment:
746
case ES_segment:
747
case FS_segment:
748
case GS_segment:
749
// Seems dubious
750
LP64_ONLY(assert(false, "shouldn't have that prefix"));
751
assert(ip == inst+1, "only one prefix allowed");
752
goto again_after_prefix;
753
754
case 0x67:
755
case REX:
756
case REX_B:
757
case REX_X:
758
case REX_XB:
759
case REX_R:
760
case REX_RB:
761
case REX_RX:
762
case REX_RXB:
763
NOT_LP64(assert(false, "64bit prefixes"));
764
goto again_after_prefix;
765
766
case REX_W:
767
case REX_WB:
768
case REX_WX:
769
case REX_WXB:
770
case REX_WR:
771
case REX_WRB:
772
case REX_WRX:
773
case REX_WRXB:
774
NOT_LP64(assert(false, "64bit prefixes"));
775
is_64bit = true;
776
goto again_after_prefix;
777
778
case 0xFF: // pushq a; decl a; incl a; call a; jmp a
779
case 0x88: // movb a, r
780
case 0x89: // movl a, r
781
case 0x8A: // movb r, a
782
case 0x8B: // movl r, a
783
case 0x8F: // popl a
784
debug_only(has_disp32 = true);
785
break;
786
787
case 0x68: // pushq #32
788
if (which == end_pc_operand) {
789
return ip + 4;
790
}
791
assert(which == imm_operand && !is_64bit, "pushl has no disp32 or 64bit immediate");
792
return ip; // not produced by emit_operand
793
794
case 0x66: // movw ... (size prefix)
795
again_after_size_prefix2:
796
switch (0xFF & *ip++) {
797
case REX:
798
case REX_B:
799
case REX_X:
800
case REX_XB:
801
case REX_R:
802
case REX_RB:
803
case REX_RX:
804
case REX_RXB:
805
case REX_W:
806
case REX_WB:
807
case REX_WX:
808
case REX_WXB:
809
case REX_WR:
810
case REX_WRB:
811
case REX_WRX:
812
case REX_WRXB:
813
NOT_LP64(assert(false, "64bit prefix found"));
814
goto again_after_size_prefix2;
815
case 0x8B: // movw r, a
816
case 0x89: // movw a, r
817
debug_only(has_disp32 = true);
818
break;
819
case 0xC7: // movw a, #16
820
debug_only(has_disp32 = true);
821
tail_size = 2; // the imm16
822
break;
823
case 0x0F: // several SSE/SSE2 variants
824
ip--; // reparse the 0x0F
825
goto again_after_prefix;
826
default:
827
ShouldNotReachHere();
828
}
829
break;
830
831
case REP8(0xB8): // movl/q r, #32/#64(oop?)
832
if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4);
833
// these asserts are somewhat nonsensical
834
#ifndef _LP64
835
assert(which == imm_operand || which == disp32_operand,
836
"which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
837
#else
838
assert((which == call32_operand || which == imm_operand) && is_64bit ||
839
which == narrow_oop_operand && !is_64bit,
840
"which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
841
#endif // _LP64
842
return ip;
843
844
case 0x69: // imul r, a, #32
845
case 0xC7: // movl a, #32(oop?)
846
tail_size = 4;
847
debug_only(has_disp32 = true); // has both kinds of operands!
848
break;
849
850
case 0x0F: // movx..., etc.
851
switch (0xFF & *ip++) {
852
case 0x3A: // pcmpestri
853
tail_size = 1;
854
case 0x38: // ptest, pmovzxbw
855
ip++; // skip opcode
856
debug_only(has_disp32 = true); // has both kinds of operands!
857
break;
858
859
case 0x70: // pshufd r, r/a, #8
860
debug_only(has_disp32 = true); // has both kinds of operands!
861
case 0x73: // psrldq r, #8
862
tail_size = 1;
863
break;
864
865
case 0x12: // movlps
866
case 0x28: // movaps
867
case 0x2E: // ucomiss
868
case 0x2F: // comiss
869
case 0x54: // andps
870
case 0x55: // andnps
871
case 0x56: // orps
872
case 0x57: // xorps
873
case 0x58: // addpd
874
case 0x59: // mulpd
875
case 0x6E: // movd
876
case 0x7E: // movd
877
case 0x6F: // movdq
878
case 0x7F: // movdq
879
case 0xAE: // ldmxcsr, stmxcsr, fxrstor, fxsave, clflush
880
case 0xFE: // paddd
881
debug_only(has_disp32 = true);
882
break;
883
884
case 0xAD: // shrd r, a, %cl
885
case 0xAF: // imul r, a
886
case 0xBE: // movsbl r, a (movsxb)
887
case 0xBF: // movswl r, a (movsxw)
888
case 0xB6: // movzbl r, a (movzxb)
889
case 0xB7: // movzwl r, a (movzxw)
890
case REP16(0x40): // cmovl cc, r, a
891
case 0xB0: // cmpxchgb
892
case 0xB1: // cmpxchg
893
case 0xC1: // xaddl
894
case 0xC7: // cmpxchg8
895
case REP16(0x90): // setcc a
896
debug_only(has_disp32 = true);
897
// fall out of the switch to decode the address
898
break;
899
900
case 0xC4: // pinsrw r, a, #8
901
debug_only(has_disp32 = true);
902
case 0xC5: // pextrw r, r, #8
903
tail_size = 1; // the imm8
904
break;
905
906
case 0xAC: // shrd r, a, #8
907
debug_only(has_disp32 = true);
908
tail_size = 1; // the imm8
909
break;
910
911
case REP16(0x80): // jcc rdisp32
912
if (which == end_pc_operand) return ip + 4;
913
assert(which == call32_operand, "jcc has no disp32 or imm");
914
return ip;
915
default:
916
ShouldNotReachHere();
917
}
918
break;
919
920
case 0x81: // addl a, #32; addl r, #32
921
// also: orl, adcl, sbbl, andl, subl, xorl, cmpl
922
// on 32bit in the case of cmpl, the imm might be an oop
923
tail_size = 4;
924
debug_only(has_disp32 = true); // has both kinds of operands!
925
break;
926
927
case 0x83: // addl a, #8; addl r, #8
928
// also: orl, adcl, sbbl, andl, subl, xorl, cmpl
929
debug_only(has_disp32 = true); // has both kinds of operands!
930
tail_size = 1;
931
break;
932
933
case 0x9B:
934
switch (0xFF & *ip++) {
935
case 0xD9: // fnstcw a
936
debug_only(has_disp32 = true);
937
break;
938
default:
939
ShouldNotReachHere();
940
}
941
break;
942
943
case REP4(0x00): // addb a, r; addl a, r; addb r, a; addl r, a
944
case REP4(0x10): // adc...
945
case REP4(0x20): // and...
946
case REP4(0x30): // xor...
947
case REP4(0x08): // or...
948
case REP4(0x18): // sbb...
949
case REP4(0x28): // sub...
950
case 0xF7: // mull a
951
case 0x8D: // lea r, a
952
case 0x87: // xchg r, a
953
case REP4(0x38): // cmp...
954
case 0x85: // test r, a
955
debug_only(has_disp32 = true); // has both kinds of operands!
956
break;
957
958
case 0xC1: // sal a, #8; sar a, #8; shl a, #8; shr a, #8
959
case 0xC6: // movb a, #8
960
case 0x80: // cmpb a, #8
961
case 0x6B: // imul r, a, #8
962
debug_only(has_disp32 = true); // has both kinds of operands!
963
tail_size = 1; // the imm8
964
break;
965
966
case 0xC4: // VEX_3bytes
967
case 0xC5: // VEX_2bytes
968
assert((UseAVX > 0), "shouldn't have VEX prefix");
969
assert(ip == inst+1, "no prefixes allowed");
970
// C4 and C5 are also used as opcodes for PINSRW and PEXTRW instructions
971
// but they have prefix 0x0F and processed when 0x0F processed above.
972
//
973
// In 32-bit mode the VEX first byte C4 and C5 alias onto LDS and LES
974
// instructions (these instructions are not supported in 64-bit mode).
975
// To distinguish them bits [7:6] are set in the VEX second byte since
976
// ModRM byte can not be of the form 11xxxxxx in 32-bit mode. To set
977
// those VEX bits REX and vvvv bits are inverted.
978
//
979
// Fortunately C2 doesn't generate these instructions so we don't need
980
// to check for them in product version.
981
982
// Check second byte
983
NOT_LP64(assert((0xC0 & *ip) == 0xC0, "shouldn't have LDS and LES instructions"));
984
985
int vex_opcode;
986
// First byte
987
if ((0xFF & *inst) == VEX_3bytes) {
988
vex_opcode = VEX_OPCODE_MASK & *ip;
989
ip++; // third byte
990
is_64bit = ((VEX_W & *ip) == VEX_W);
991
} else {
992
vex_opcode = VEX_OPCODE_0F;
993
}
994
ip++; // opcode
995
// To find the end of instruction (which == end_pc_operand).
996
switch (vex_opcode) {
997
case VEX_OPCODE_0F:
998
switch (0xFF & *ip) {
999
case 0x70: // pshufd r, r/a, #8
1000
case 0x71: // ps[rl|ra|ll]w r, #8
1001
case 0x72: // ps[rl|ra|ll]d r, #8
1002
case 0x73: // ps[rl|ra|ll]q r, #8
1003
case 0xC2: // cmp[ps|pd|ss|sd] r, r, r/a, #8
1004
case 0xC4: // pinsrw r, r, r/a, #8
1005
case 0xC5: // pextrw r/a, r, #8
1006
case 0xC6: // shufp[s|d] r, r, r/a, #8
1007
tail_size = 1; // the imm8
1008
break;
1009
}
1010
break;
1011
case VEX_OPCODE_0F_3A:
1012
tail_size = 1;
1013
break;
1014
}
1015
ip++; // skip opcode
1016
debug_only(has_disp32 = true); // has both kinds of operands!
1017
break;
1018
1019
case 0x62: // EVEX_4bytes
1020
assert(VM_Version::supports_evex(), "shouldn't have EVEX prefix");
1021
assert(ip == inst+1, "no prefixes allowed");
1022
// no EVEX collisions, all instructions that have 0x62 opcodes
1023
// have EVEX versions and are subopcodes of 0x66
1024
ip++; // skip P0 and exmaine W in P1
1025
is_64bit = ((VEX_W & *ip) == VEX_W);
1026
ip++; // move to P2
1027
ip++; // skip P2, move to opcode
1028
// To find the end of instruction (which == end_pc_operand).
1029
switch (0xFF & *ip) {
1030
case 0x22: // pinsrd r, r/a, #8
1031
case 0x61: // pcmpestri r, r/a, #8
1032
case 0x70: // pshufd r, r/a, #8
1033
case 0x73: // psrldq r, #8
1034
case 0x1f: // evpcmpd/evpcmpq
1035
case 0x3f: // evpcmpb/evpcmpw
1036
tail_size = 1; // the imm8
1037
break;
1038
default:
1039
break;
1040
}
1041
ip++; // skip opcode
1042
debug_only(has_disp32 = true); // has both kinds of operands!
1043
break;
1044
1045
case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1
1046
case 0xD3: // sal a, %cl; sar a, %cl; shl a, %cl; shr a, %cl
1047
case 0xD9: // fld_s a; fst_s a; fstp_s a; fldcw a
1048
case 0xDD: // fld_d a; fst_d a; fstp_d a
1049
case 0xDB: // fild_s a; fistp_s a; fld_x a; fstp_x a
1050
case 0xDF: // fild_d a; fistp_d a
1051
case 0xD8: // fadd_s a; fsubr_s a; fmul_s a; fdivr_s a; fcomp_s a
1052
case 0xDC: // fadd_d a; fsubr_d a; fmul_d a; fdivr_d a; fcomp_d a
1053
case 0xDE: // faddp_d a; fsubrp_d a; fmulp_d a; fdivrp_d a; fcompp_d a
1054
debug_only(has_disp32 = true);
1055
break;
1056
1057
case 0xE8: // call rdisp32
1058
case 0xE9: // jmp rdisp32
1059
if (which == end_pc_operand) return ip + 4;
1060
assert(which == call32_operand, "call has no disp32 or imm");
1061
return ip;
1062
1063
case 0xF0: // Lock
1064
goto again_after_prefix;
1065
1066
case 0xF3: // For SSE
1067
case 0xF2: // For SSE2
1068
switch (0xFF & *ip++) {
1069
case REX:
1070
case REX_B:
1071
case REX_X:
1072
case REX_XB:
1073
case REX_R:
1074
case REX_RB:
1075
case REX_RX:
1076
case REX_RXB:
1077
case REX_W:
1078
case REX_WB:
1079
case REX_WX:
1080
case REX_WXB:
1081
case REX_WR:
1082
case REX_WRB:
1083
case REX_WRX:
1084
case REX_WRXB:
1085
NOT_LP64(assert(false, "found 64bit prefix"));
1086
ip++;
1087
default:
1088
ip++;
1089
}
1090
debug_only(has_disp32 = true); // has both kinds of operands!
1091
break;
1092
1093
default:
1094
ShouldNotReachHere();
1095
1096
#undef REP8
1097
#undef REP16
1098
}
1099
1100
assert(which != call32_operand, "instruction is not a call, jmp, or jcc");
1101
#ifdef _LP64
1102
assert(which != imm_operand, "instruction is not a movq reg, imm64");
1103
#else
1104
// assert(which != imm_operand || has_imm32, "instruction has no imm32 field");
1105
assert(which != imm_operand || has_disp32, "instruction has no imm32 field");
1106
#endif // LP64
1107
assert(which != disp32_operand || has_disp32, "instruction has no disp32 field");
1108
1109
// parse the output of emit_operand
1110
int op2 = 0xFF & *ip++;
1111
int base = op2 & 0x07;
1112
int op3 = -1;
1113
const int b100 = 4;
1114
const int b101 = 5;
1115
if (base == b100 && (op2 >> 6) != 3) {
1116
op3 = 0xFF & *ip++;
1117
base = op3 & 0x07; // refetch the base
1118
}
1119
// now ip points at the disp (if any)
1120
1121
switch (op2 >> 6) {
1122
case 0:
1123
// [00 reg 100][ss index base]
1124
// [00 reg 100][00 100 esp]
1125
// [00 reg base]
1126
// [00 reg 100][ss index 101][disp32]
1127
// [00 reg 101] [disp32]
1128
1129
if (base == b101) {
1130
if (which == disp32_operand)
1131
return ip; // caller wants the disp32
1132
ip += 4; // skip the disp32
1133
}
1134
break;
1135
1136
case 1:
1137
// [01 reg 100][ss index base][disp8]
1138
// [01 reg 100][00 100 esp][disp8]
1139
// [01 reg base] [disp8]
1140
ip += 1; // skip the disp8
1141
break;
1142
1143
case 2:
1144
// [10 reg 100][ss index base][disp32]
1145
// [10 reg 100][00 100 esp][disp32]
1146
// [10 reg base] [disp32]
1147
if (which == disp32_operand)
1148
return ip; // caller wants the disp32
1149
ip += 4; // skip the disp32
1150
break;
1151
1152
case 3:
1153
// [11 reg base] (not a memory addressing mode)
1154
break;
1155
}
1156
1157
if (which == end_pc_operand) {
1158
return ip + tail_size;
1159
}
1160
1161
#ifdef _LP64
1162
assert(which == narrow_oop_operand && !is_64bit, "instruction is not a movl adr, imm32");
1163
#else
1164
assert(which == imm_operand, "instruction has only an imm field");
1165
#endif // LP64
1166
return ip;
1167
}
1168
1169
address Assembler::locate_next_instruction(address inst) {
1170
// Secretly share code with locate_operand:
1171
return locate_operand(inst, end_pc_operand);
1172
}
1173
1174
1175
#ifdef ASSERT
1176
void Assembler::check_relocation(RelocationHolder const& rspec, int format) {
1177
address inst = inst_mark();
1178
assert(inst != NULL && inst < pc(), "must point to beginning of instruction");
1179
address opnd;
1180
1181
Relocation* r = rspec.reloc();
1182
if (r->type() == relocInfo::none) {
1183
return;
1184
} else if (r->is_call() || format == call32_operand) {
1185
// assert(format == imm32_operand, "cannot specify a nonzero format");
1186
opnd = locate_operand(inst, call32_operand);
1187
} else if (r->is_data()) {
1188
assert(format == imm_operand || format == disp32_operand
1189
LP64_ONLY(|| format == narrow_oop_operand), "format ok");
1190
opnd = locate_operand(inst, (WhichOperand)format);
1191
} else {
1192
assert(format == imm_operand, "cannot specify a format");
1193
return;
1194
}
1195
assert(opnd == pc(), "must put operand where relocs can find it");
1196
}
1197
#endif // ASSERT
1198
1199
void Assembler::emit_operand(Register reg, Address adr,
1200
int rip_relative_correction) {
1201
emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp,
1202
adr._rspec,
1203
rip_relative_correction);
1204
}
1205
1206
void Assembler::emit_operand(XMMRegister reg, Address adr) {
1207
if (adr.isxmmindex()) {
1208
emit_operand(reg, adr._base, adr._xmmindex, adr._scale, adr._disp, adr._rspec);
1209
} else {
1210
emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp,
1211
adr._rspec);
1212
}
1213
}
1214
1215
// Now the Assembler instructions (identical for 32/64 bits)
1216
1217
void Assembler::adcl(Address dst, int32_t imm32) {
1218
InstructionMark im(this);
1219
prefix(dst);
1220
emit_arith_operand(0x81, rdx, dst, imm32);
1221
}
1222
1223
void Assembler::adcl(Address dst, Register src) {
1224
InstructionMark im(this);
1225
prefix(dst, src);
1226
emit_int8(0x11);
1227
emit_operand(src, dst);
1228
}
1229
1230
void Assembler::adcl(Register dst, int32_t imm32) {
1231
prefix(dst);
1232
emit_arith(0x81, 0xD0, dst, imm32);
1233
}
1234
1235
void Assembler::adcl(Register dst, Address src) {
1236
InstructionMark im(this);
1237
prefix(src, dst);
1238
emit_int8(0x13);
1239
emit_operand(dst, src);
1240
}
1241
1242
void Assembler::adcl(Register dst, Register src) {
1243
(void) prefix_and_encode(dst->encoding(), src->encoding());
1244
emit_arith(0x13, 0xC0, dst, src);
1245
}
1246
1247
void Assembler::addl(Address dst, int32_t imm32) {
1248
InstructionMark im(this);
1249
prefix(dst);
1250
emit_arith_operand(0x81, rax, dst, imm32);
1251
}
1252
1253
void Assembler::addb(Address dst, int imm8) {
1254
InstructionMark im(this);
1255
prefix(dst);
1256
emit_int8((unsigned char)0x80);
1257
emit_operand(rax, dst, 1);
1258
emit_int8(imm8);
1259
}
1260
1261
void Assembler::addw(Register dst, Register src) {
1262
(void)prefix_and_encode(dst->encoding(), src->encoding());
1263
emit_arith(0x03, 0xC0, dst, src);
1264
}
1265
1266
void Assembler::addw(Address dst, int imm16) {
1267
InstructionMark im(this);
1268
emit_int8(0x66);
1269
prefix(dst);
1270
emit_int8((unsigned char)0x81);
1271
emit_operand(rax, dst, 2);
1272
emit_int16(imm16);
1273
}
1274
1275
void Assembler::addl(Address dst, Register src) {
1276
InstructionMark im(this);
1277
prefix(dst, src);
1278
emit_int8(0x01);
1279
emit_operand(src, dst);
1280
}
1281
1282
void Assembler::addl(Register dst, int32_t imm32) {
1283
prefix(dst);
1284
emit_arith(0x81, 0xC0, dst, imm32);
1285
}
1286
1287
void Assembler::addl(Register dst, Address src) {
1288
InstructionMark im(this);
1289
prefix(src, dst);
1290
emit_int8(0x03);
1291
emit_operand(dst, src);
1292
}
1293
1294
void Assembler::addl(Register dst, Register src) {
1295
(void) prefix_and_encode(dst->encoding(), src->encoding());
1296
emit_arith(0x03, 0xC0, dst, src);
1297
}
1298
1299
void Assembler::addr_nop_4() {
1300
assert(UseAddressNop, "no CPU support");
1301
// 4 bytes: NOP DWORD PTR [EAX+0]
1302
emit_int32(0x0F,
1303
0x1F,
1304
0x40, // emit_rm(cbuf, 0x1, EAX_enc, EAX_enc);
1305
0); // 8-bits offset (1 byte)
1306
}
1307
1308
void Assembler::addr_nop_5() {
1309
assert(UseAddressNop, "no CPU support");
1310
// 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset
1311
emit_int32(0x0F,
1312
0x1F,
1313
0x44, // emit_rm(cbuf, 0x1, EAX_enc, 0x4);
1314
0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc);
1315
emit_int8(0); // 8-bits offset (1 byte)
1316
}
1317
1318
void Assembler::addr_nop_7() {
1319
assert(UseAddressNop, "no CPU support");
1320
// 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset
1321
emit_int24(0x0F,
1322
0x1F,
1323
(unsigned char)0x80);
1324
// emit_rm(cbuf, 0x2, EAX_enc, EAX_enc);
1325
emit_int32(0); // 32-bits offset (4 bytes)
1326
}
1327
1328
void Assembler::addr_nop_8() {
1329
assert(UseAddressNop, "no CPU support");
1330
// 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset
1331
emit_int32(0x0F,
1332
0x1F,
1333
(unsigned char)0x84,
1334
// emit_rm(cbuf, 0x2, EAX_enc, 0x4);
1335
0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc);
1336
emit_int32(0); // 32-bits offset (4 bytes)
1337
}
1338
1339
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
1340
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1341
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1342
attributes.set_rex_vex_w_reverted();
1343
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1344
emit_int16(0x58, (0xC0 | encode));
1345
}
1346
1347
void Assembler::addsd(XMMRegister dst, Address src) {
1348
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1349
InstructionMark im(this);
1350
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1351
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
1352
attributes.set_rex_vex_w_reverted();
1353
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1354
emit_int8(0x58);
1355
emit_operand(dst, src);
1356
}
1357
1358
void Assembler::addss(XMMRegister dst, XMMRegister src) {
1359
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1360
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1361
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1362
emit_int16(0x58, (0xC0 | encode));
1363
}
1364
1365
void Assembler::addss(XMMRegister dst, Address src) {
1366
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1367
InstructionMark im(this);
1368
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1369
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
1370
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1371
emit_int8(0x58);
1372
emit_operand(dst, src);
1373
}
1374
1375
void Assembler::aesdec(XMMRegister dst, Address src) {
1376
assert(VM_Version::supports_aes(), "");
1377
InstructionMark im(this);
1378
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1379
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1380
emit_int8((unsigned char)0xDE);
1381
emit_operand(dst, src);
1382
}
1383
1384
void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
1385
assert(VM_Version::supports_aes(), "");
1386
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1387
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1388
emit_int16((unsigned char)0xDE, (0xC0 | encode));
1389
}
1390
1391
void Assembler::vaesdec(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
1392
assert(VM_Version::supports_avx512_vaes(), "");
1393
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1394
attributes.set_is_evex_instruction();
1395
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1396
emit_int16((unsigned char)0xDE, (0xC0 | encode));
1397
}
1398
1399
1400
void Assembler::aesdeclast(XMMRegister dst, Address src) {
1401
assert(VM_Version::supports_aes(), "");
1402
InstructionMark im(this);
1403
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1404
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1405
emit_int8((unsigned char)0xDF);
1406
emit_operand(dst, src);
1407
}
1408
1409
void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
1410
assert(VM_Version::supports_aes(), "");
1411
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1412
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1413
emit_int16((unsigned char)0xDF, (0xC0 | encode));
1414
}
1415
1416
void Assembler::vaesdeclast(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
1417
assert(VM_Version::supports_avx512_vaes(), "");
1418
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1419
attributes.set_is_evex_instruction();
1420
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1421
emit_int16((unsigned char)0xDF, (0xC0 | encode));
1422
}
1423
1424
void Assembler::aesenc(XMMRegister dst, Address src) {
1425
assert(VM_Version::supports_aes(), "");
1426
InstructionMark im(this);
1427
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1428
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1429
emit_int8((unsigned char)0xDC);
1430
emit_operand(dst, src);
1431
}
1432
1433
void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
1434
assert(VM_Version::supports_aes(), "");
1435
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1436
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1437
emit_int16((unsigned char)0xDC, 0xC0 | encode);
1438
}
1439
1440
void Assembler::vaesenc(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
1441
assert(VM_Version::supports_avx512_vaes(), "requires vaes support/enabling");
1442
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1443
attributes.set_is_evex_instruction();
1444
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1445
emit_int16((unsigned char)0xDC, (0xC0 | encode));
1446
}
1447
1448
void Assembler::aesenclast(XMMRegister dst, Address src) {
1449
assert(VM_Version::supports_aes(), "");
1450
InstructionMark im(this);
1451
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1452
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1453
emit_int8((unsigned char)0xDD);
1454
emit_operand(dst, src);
1455
}
1456
1457
void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
1458
assert(VM_Version::supports_aes(), "");
1459
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1460
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1461
emit_int16((unsigned char)0xDD, (0xC0 | encode));
1462
}
1463
1464
void Assembler::vaesenclast(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
1465
assert(VM_Version::supports_avx512_vaes(), "requires vaes support/enabling");
1466
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1467
attributes.set_is_evex_instruction();
1468
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1469
emit_int16((unsigned char)0xDD, (0xC0 | encode));
1470
}
1471
1472
void Assembler::andb(Address dst, Register src) {
1473
InstructionMark im(this);
1474
prefix(dst, src, true);
1475
emit_int8(0x20);
1476
emit_operand(src, dst);
1477
}
1478
1479
void Assembler::andw(Register dst, Register src) {
1480
(void)prefix_and_encode(dst->encoding(), src->encoding());
1481
emit_arith(0x23, 0xC0, dst, src);
1482
}
1483
1484
void Assembler::andl(Address dst, int32_t imm32) {
1485
InstructionMark im(this);
1486
prefix(dst);
1487
emit_arith_operand(0x81, as_Register(4), dst, imm32);
1488
}
1489
1490
void Assembler::andl(Register dst, int32_t imm32) {
1491
prefix(dst);
1492
emit_arith(0x81, 0xE0, dst, imm32);
1493
}
1494
1495
void Assembler::andl(Address dst, Register src) {
1496
InstructionMark im(this);
1497
prefix(dst, src);
1498
emit_int8(0x21);
1499
emit_operand(src, dst);
1500
}
1501
1502
void Assembler::andl(Register dst, Address src) {
1503
InstructionMark im(this);
1504
prefix(src, dst);
1505
emit_int8(0x23);
1506
emit_operand(dst, src);
1507
}
1508
1509
void Assembler::andl(Register dst, Register src) {
1510
(void) prefix_and_encode(dst->encoding(), src->encoding());
1511
emit_arith(0x23, 0xC0, dst, src);
1512
}
1513
1514
void Assembler::andnl(Register dst, Register src1, Register src2) {
1515
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1516
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1517
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1518
emit_int16((unsigned char)0xF2, (0xC0 | encode));
1519
}
1520
1521
void Assembler::andnl(Register dst, Register src1, Address src2) {
1522
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1523
InstructionMark im(this);
1524
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1525
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1526
emit_int8((unsigned char)0xF2);
1527
emit_operand(dst, src2);
1528
}
1529
1530
void Assembler::bsfl(Register dst, Register src) {
1531
int encode = prefix_and_encode(dst->encoding(), src->encoding());
1532
emit_int24(0x0F,
1533
(unsigned char)0xBC,
1534
0xC0 | encode);
1535
}
1536
1537
void Assembler::bsrl(Register dst, Register src) {
1538
int encode = prefix_and_encode(dst->encoding(), src->encoding());
1539
emit_int24(0x0F,
1540
(unsigned char)0xBD,
1541
0xC0 | encode);
1542
}
1543
1544
void Assembler::bswapl(Register reg) { // bswap
1545
int encode = prefix_and_encode(reg->encoding());
1546
emit_int16(0x0F, (0xC8 | encode));
1547
}
1548
1549
void Assembler::blsil(Register dst, Register src) {
1550
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1551
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1552
int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1553
emit_int16((unsigned char)0xF3, (0xC0 | encode));
1554
}
1555
1556
void Assembler::blsil(Register dst, Address src) {
1557
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1558
InstructionMark im(this);
1559
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1560
vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1561
emit_int8((unsigned char)0xF3);
1562
emit_operand(rbx, src);
1563
}
1564
1565
void Assembler::blsmskl(Register dst, Register src) {
1566
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1567
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1568
int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1569
emit_int16((unsigned char)0xF3,
1570
0xC0 | encode);
1571
}
1572
1573
void Assembler::blsmskl(Register dst, Address src) {
1574
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1575
InstructionMark im(this);
1576
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1577
vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1578
emit_int8((unsigned char)0xF3);
1579
emit_operand(rdx, src);
1580
}
1581
1582
void Assembler::blsrl(Register dst, Register src) {
1583
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1584
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1585
int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1586
emit_int16((unsigned char)0xF3, (0xC0 | encode));
1587
}
1588
1589
void Assembler::blsrl(Register dst, Address src) {
1590
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
1591
InstructionMark im(this);
1592
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
1593
vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
1594
emit_int8((unsigned char)0xF3);
1595
emit_operand(rcx, src);
1596
}
1597
1598
void Assembler::call(Label& L, relocInfo::relocType rtype) {
1599
// suspect disp32 is always good
1600
int operand = LP64_ONLY(disp32_operand) NOT_LP64(imm_operand);
1601
1602
if (L.is_bound()) {
1603
const int long_size = 5;
1604
int offs = (int)( target(L) - pc() );
1605
assert(offs <= 0, "assembler error");
1606
InstructionMark im(this);
1607
// 1110 1000 #32-bit disp
1608
emit_int8((unsigned char)0xE8);
1609
emit_data(offs - long_size, rtype, operand);
1610
} else {
1611
InstructionMark im(this);
1612
// 1110 1000 #32-bit disp
1613
L.add_patch_at(code(), locator());
1614
1615
emit_int8((unsigned char)0xE8);
1616
emit_data(int(0), rtype, operand);
1617
}
1618
}
1619
1620
void Assembler::call(Register dst) {
1621
int encode = prefix_and_encode(dst->encoding());
1622
emit_int16((unsigned char)0xFF, (0xD0 | encode));
1623
}
1624
1625
1626
void Assembler::call(Address adr) {
1627
InstructionMark im(this);
1628
prefix(adr);
1629
emit_int8((unsigned char)0xFF);
1630
emit_operand(rdx, adr);
1631
}
1632
1633
void Assembler::call_literal(address entry, RelocationHolder const& rspec) {
1634
InstructionMark im(this);
1635
emit_int8((unsigned char)0xE8);
1636
intptr_t disp = entry - (pc() + sizeof(int32_t));
1637
// Entry is NULL in case of a scratch emit.
1638
assert(entry == NULL || is_simm32(disp), "disp=" INTPTR_FORMAT " must be 32bit offset (call2)", disp);
1639
// Technically, should use call32_operand, but this format is
1640
// implied by the fact that we're emitting a call instruction.
1641
1642
int operand = LP64_ONLY(disp32_operand) NOT_LP64(call32_operand);
1643
emit_data((int) disp, rspec, operand);
1644
}
1645
1646
void Assembler::cdql() {
1647
emit_int8((unsigned char)0x99);
1648
}
1649
1650
void Assembler::cld() {
1651
emit_int8((unsigned char)0xFC);
1652
}
1653
1654
void Assembler::cmovl(Condition cc, Register dst, Register src) {
1655
NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction"));
1656
int encode = prefix_and_encode(dst->encoding(), src->encoding());
1657
emit_int24(0x0F,
1658
0x40 | cc,
1659
0xC0 | encode);
1660
}
1661
1662
1663
void Assembler::cmovl(Condition cc, Register dst, Address src) {
1664
InstructionMark im(this);
1665
NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction"));
1666
prefix(src, dst);
1667
emit_int16(0x0F, (0x40 | cc));
1668
emit_operand(dst, src);
1669
}
1670
1671
void Assembler::cmpb(Address dst, int imm8) {
1672
InstructionMark im(this);
1673
prefix(dst);
1674
emit_int8((unsigned char)0x80);
1675
emit_operand(rdi, dst, 1);
1676
emit_int8(imm8);
1677
}
1678
1679
void Assembler::cmpl(Address dst, int32_t imm32) {
1680
InstructionMark im(this);
1681
prefix(dst);
1682
emit_int8((unsigned char)0x81);
1683
emit_operand(rdi, dst, 4);
1684
emit_int32(imm32);
1685
}
1686
1687
void Assembler::cmp(Register dst, int32_t imm32) {
1688
prefix(dst);
1689
emit_int8((unsigned char)0x3D);
1690
emit_int32(imm32);
1691
}
1692
1693
void Assembler::cmpl(Register dst, int32_t imm32) {
1694
prefix(dst);
1695
emit_arith(0x81, 0xF8, dst, imm32);
1696
}
1697
1698
void Assembler::cmpl(Register dst, Register src) {
1699
(void) prefix_and_encode(dst->encoding(), src->encoding());
1700
emit_arith(0x3B, 0xC0, dst, src);
1701
}
1702
1703
void Assembler::cmpl(Register dst, Address src) {
1704
InstructionMark im(this);
1705
prefix(src, dst);
1706
emit_int8(0x3B);
1707
emit_operand(dst, src);
1708
}
1709
1710
void Assembler::cmpw(Address dst, int imm16) {
1711
InstructionMark im(this);
1712
assert(!dst.base_needs_rex() && !dst.index_needs_rex(), "no extended registers");
1713
emit_int16(0x66, (unsigned char)0x81);
1714
emit_operand(rdi, dst, 2);
1715
emit_int16(imm16);
1716
}
1717
1718
// The 32-bit cmpxchg compares the value at adr with the contents of rax,
1719
// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,.
1720
// The ZF is set if the compared values were equal, and cleared otherwise.
1721
void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg
1722
InstructionMark im(this);
1723
prefix(adr, reg);
1724
emit_int16(0x0F, (unsigned char)0xB1);
1725
emit_operand(reg, adr);
1726
}
1727
1728
void Assembler::cmpxchgw(Register reg, Address adr) { // cmpxchg
1729
InstructionMark im(this);
1730
size_prefix();
1731
prefix(adr, reg);
1732
emit_int16(0x0F, (unsigned char)0xB1);
1733
emit_operand(reg, adr);
1734
}
1735
1736
// The 8-bit cmpxchg compares the value at adr with the contents of rax,
1737
// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,.
1738
// The ZF is set if the compared values were equal, and cleared otherwise.
1739
void Assembler::cmpxchgb(Register reg, Address adr) { // cmpxchg
1740
InstructionMark im(this);
1741
prefix(adr, reg, true);
1742
emit_int16(0x0F, (unsigned char)0xB0);
1743
emit_operand(reg, adr);
1744
}
1745
1746
void Assembler::comisd(XMMRegister dst, Address src) {
1747
// NOTE: dbx seems to decode this as comiss even though the
1748
// 0x66 is there. Strangly ucomisd comes out correct
1749
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1750
InstructionMark im(this);
1751
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);;
1752
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
1753
attributes.set_rex_vex_w_reverted();
1754
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
1755
emit_int8(0x2F);
1756
emit_operand(dst, src);
1757
}
1758
1759
void Assembler::comisd(XMMRegister dst, XMMRegister src) {
1760
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1761
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1762
attributes.set_rex_vex_w_reverted();
1763
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
1764
emit_int16(0x2F, (0xC0 | encode));
1765
}
1766
1767
void Assembler::comiss(XMMRegister dst, Address src) {
1768
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1769
InstructionMark im(this);
1770
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1771
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
1772
simd_prefix(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
1773
emit_int8(0x2F);
1774
emit_operand(dst, src);
1775
}
1776
1777
void Assembler::comiss(XMMRegister dst, XMMRegister src) {
1778
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1779
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1780
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
1781
emit_int16(0x2F, (0xC0 | encode));
1782
}
1783
1784
void Assembler::cpuid() {
1785
emit_int16(0x0F, (unsigned char)0xA2);
1786
}
1787
1788
// Opcode / Instruction Op / En 64 - Bit Mode Compat / Leg Mode Description Implemented
1789
// F2 0F 38 F0 / r CRC32 r32, r / m8 RM Valid Valid Accumulate CRC32 on r / m8. v
1790
// F2 REX 0F 38 F0 / r CRC32 r32, r / m8* RM Valid N.E. Accumulate CRC32 on r / m8. -
1791
// F2 REX.W 0F 38 F0 / r CRC32 r64, r / m8 RM Valid N.E. Accumulate CRC32 on r / m8. -
1792
//
1793
// F2 0F 38 F1 / r CRC32 r32, r / m16 RM Valid Valid Accumulate CRC32 on r / m16. v
1794
//
1795
// F2 0F 38 F1 / r CRC32 r32, r / m32 RM Valid Valid Accumulate CRC32 on r / m32. v
1796
//
1797
// F2 REX.W 0F 38 F1 / r CRC32 r64, r / m64 RM Valid N.E. Accumulate CRC32 on r / m64. v
1798
void Assembler::crc32(Register crc, Register v, int8_t sizeInBytes) {
1799
assert(VM_Version::supports_sse4_2(), "");
1800
int8_t w = 0x01;
1801
Prefix p = Prefix_EMPTY;
1802
1803
emit_int8((unsigned char)0xF2);
1804
switch (sizeInBytes) {
1805
case 1:
1806
w = 0;
1807
break;
1808
case 2:
1809
case 4:
1810
break;
1811
LP64_ONLY(case 8:)
1812
// This instruction is not valid in 32 bits
1813
// Note:
1814
// http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
1815
//
1816
// Page B - 72 Vol. 2C says
1817
// qwreg2 to qwreg 1111 0010 : 0100 1R0B : 0000 1111 : 0011 1000 : 1111 0000 : 11 qwreg1 qwreg2
1818
// mem64 to qwreg 1111 0010 : 0100 1R0B : 0000 1111 : 0011 1000 : 1111 0000 : mod qwreg r / m
1819
// F0!!!
1820
// while 3 - 208 Vol. 2A
1821
// F2 REX.W 0F 38 F1 / r CRC32 r64, r / m64 RM Valid N.E.Accumulate CRC32 on r / m64.
1822
//
1823
// the 0 on a last bit is reserved for a different flavor of this instruction :
1824
// F2 REX.W 0F 38 F0 / r CRC32 r64, r / m8 RM Valid N.E.Accumulate CRC32 on r / m8.
1825
p = REX_W;
1826
break;
1827
default:
1828
assert(0, "Unsupported value for a sizeInBytes argument");
1829
break;
1830
}
1831
LP64_ONLY(prefix(crc, v, p);)
1832
emit_int32(0x0F,
1833
0x38,
1834
0xF0 | w,
1835
0xC0 | ((crc->encoding() & 0x7) << 3) | (v->encoding() & 7));
1836
}
1837
1838
void Assembler::crc32(Register crc, Address adr, int8_t sizeInBytes) {
1839
assert(VM_Version::supports_sse4_2(), "");
1840
InstructionMark im(this);
1841
int8_t w = 0x01;
1842
Prefix p = Prefix_EMPTY;
1843
1844
emit_int8((int8_t)0xF2);
1845
switch (sizeInBytes) {
1846
case 1:
1847
w = 0;
1848
break;
1849
case 2:
1850
case 4:
1851
break;
1852
LP64_ONLY(case 8:)
1853
// This instruction is not valid in 32 bits
1854
p = REX_W;
1855
break;
1856
default:
1857
assert(0, "Unsupported value for a sizeInBytes argument");
1858
break;
1859
}
1860
LP64_ONLY(prefix(crc, adr, p);)
1861
emit_int24(0x0F, 0x38, (0xF0 | w));
1862
emit_operand(crc, adr);
1863
}
1864
1865
void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
1866
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1867
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1868
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1869
emit_int16((unsigned char)0xE6, (0xC0 | encode));
1870
}
1871
1872
void Assembler::vcvtdq2pd(XMMRegister dst, XMMRegister src, int vector_len) {
1873
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
1874
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1875
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1876
emit_int16((unsigned char)0xE6, (0xC0 | encode));
1877
}
1878
1879
void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
1880
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1881
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1882
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
1883
emit_int16(0x5B, (0xC0 | encode));
1884
}
1885
1886
void Assembler::vcvtdq2ps(XMMRegister dst, XMMRegister src, int vector_len) {
1887
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
1888
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1889
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
1890
emit_int16(0x5B, (0xC0 | encode));
1891
}
1892
1893
void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
1894
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1895
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1896
attributes.set_rex_vex_w_reverted();
1897
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1898
emit_int16(0x5A, (0xC0 | encode));
1899
}
1900
1901
void Assembler::cvtsd2ss(XMMRegister dst, Address src) {
1902
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1903
InstructionMark im(this);
1904
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1905
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
1906
attributes.set_rex_vex_w_reverted();
1907
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1908
emit_int8(0x5A);
1909
emit_operand(dst, src);
1910
}
1911
1912
void Assembler::cvtsi2sdl(XMMRegister dst, Register src) {
1913
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1914
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1915
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1916
emit_int16(0x2A, (0xC0 | encode));
1917
}
1918
1919
void Assembler::cvtsi2sdl(XMMRegister dst, Address src) {
1920
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1921
InstructionMark im(this);
1922
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1923
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
1924
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1925
emit_int8(0x2A);
1926
emit_operand(dst, src);
1927
}
1928
1929
void Assembler::cvtsi2ssl(XMMRegister dst, Register src) {
1930
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1931
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1932
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1933
emit_int16(0x2A, (0xC0 | encode));
1934
}
1935
1936
void Assembler::cvtsi2ssl(XMMRegister dst, Address src) {
1937
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1938
InstructionMark im(this);
1939
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1940
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
1941
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1942
emit_int8(0x2A);
1943
emit_operand(dst, src);
1944
}
1945
1946
void Assembler::cvtsi2ssq(XMMRegister dst, Register src) {
1947
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1948
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1949
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1950
emit_int16(0x2A, (0xC0 | encode));
1951
}
1952
1953
void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
1954
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1955
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1956
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1957
emit_int16(0x5A, (0xC0 | encode));
1958
}
1959
1960
void Assembler::cvtss2sd(XMMRegister dst, Address src) {
1961
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1962
InstructionMark im(this);
1963
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1964
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
1965
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1966
emit_int8(0x5A);
1967
emit_operand(dst, src);
1968
}
1969
1970
1971
void Assembler::cvttsd2sil(Register dst, XMMRegister src) {
1972
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1973
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1974
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
1975
emit_int16(0x2C, (0xC0 | encode));
1976
}
1977
1978
void Assembler::cvttss2sil(Register dst, XMMRegister src) {
1979
NOT_LP64(assert(VM_Version::supports_sse(), ""));
1980
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
1981
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
1982
emit_int16(0x2C, (0xC0 | encode));
1983
}
1984
1985
void Assembler::cvttpd2dq(XMMRegister dst, XMMRegister src) {
1986
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1987
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
1988
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
1989
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
1990
emit_int16((unsigned char)0xE6, (0xC0 | encode));
1991
}
1992
1993
void Assembler::pabsb(XMMRegister dst, XMMRegister src) {
1994
assert(VM_Version::supports_ssse3(), "");
1995
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
1996
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
1997
emit_int16(0x1C, (0xC0 | encode));
1998
}
1999
2000
void Assembler::pabsw(XMMRegister dst, XMMRegister src) {
2001
assert(VM_Version::supports_ssse3(), "");
2002
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2003
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
2004
emit_int16(0x1D, (0xC0 | encode));
2005
}
2006
2007
void Assembler::pabsd(XMMRegister dst, XMMRegister src) {
2008
assert(VM_Version::supports_ssse3(), "");
2009
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2010
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
2011
emit_int16(0x1E, (0xC0 | encode));
2012
}
2013
2014
void Assembler::vpabsb(XMMRegister dst, XMMRegister src, int vector_len) {
2015
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
2016
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
2017
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : false, "not supported");
2018
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2019
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
2020
emit_int16(0x1C, (0xC0 | encode));
2021
}
2022
2023
void Assembler::vpabsw(XMMRegister dst, XMMRegister src, int vector_len) {
2024
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
2025
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
2026
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : false, "");
2027
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2028
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
2029
emit_int16(0x1D, (0xC0 | encode));
2030
}
2031
2032
void Assembler::vpabsd(XMMRegister dst, XMMRegister src, int vector_len) {
2033
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
2034
vector_len == AVX_256bit? VM_Version::supports_avx2() :
2035
vector_len == AVX_512bit? VM_Version::supports_evex() : 0, "");
2036
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2037
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
2038
emit_int16(0x1E, (0xC0 | encode));
2039
}
2040
2041
void Assembler::evpabsq(XMMRegister dst, XMMRegister src, int vector_len) {
2042
assert(UseAVX > 2, "");
2043
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2044
attributes.set_is_evex_instruction();
2045
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
2046
emit_int16(0x1F, (0xC0 | encode));
2047
}
2048
2049
void Assembler::vcvtps2pd(XMMRegister dst, XMMRegister src, int vector_len) {
2050
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
2051
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2052
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2053
emit_int16(0x5A, (0xC0 | encode));
2054
}
2055
2056
void Assembler::vcvtpd2ps(XMMRegister dst, XMMRegister src, int vector_len) {
2057
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
2058
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2059
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2060
attributes.set_rex_vex_w_reverted();
2061
emit_int16(0x5A, (0xC0 | encode));
2062
}
2063
2064
void Assembler::evcvtqq2ps(XMMRegister dst, XMMRegister src, int vector_len) {
2065
assert(UseAVX > 2 && VM_Version::supports_avx512dq(), "");
2066
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2067
attributes.set_is_evex_instruction();
2068
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2069
emit_int16(0x5B, (0xC0 | encode));
2070
}
2071
2072
void Assembler::evcvtqq2pd(XMMRegister dst, XMMRegister src, int vector_len) {
2073
assert(UseAVX > 2 && VM_Version::supports_avx512dq(), "");
2074
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2075
attributes.set_is_evex_instruction();
2076
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2077
emit_int16((unsigned char)0xE6, (0xC0 | encode));
2078
}
2079
2080
void Assembler::evpmovwb(XMMRegister dst, XMMRegister src, int vector_len) {
2081
assert(UseAVX > 2 && VM_Version::supports_avx512bw(), "");
2082
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2083
attributes.set_is_evex_instruction();
2084
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
2085
emit_int16(0x30, (0xC0 | encode));
2086
}
2087
2088
void Assembler::evpmovdw(XMMRegister dst, XMMRegister src, int vector_len) {
2089
assert(UseAVX > 2, "");
2090
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2091
attributes.set_is_evex_instruction();
2092
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
2093
emit_int16(0x33, (0xC0 | encode));
2094
}
2095
2096
void Assembler::evpmovdb(XMMRegister dst, XMMRegister src, int vector_len) {
2097
assert(UseAVX > 2, "");
2098
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2099
attributes.set_is_evex_instruction();
2100
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
2101
emit_int16(0x31, (0xC0 | encode));
2102
}
2103
2104
void Assembler::evpmovqd(XMMRegister dst, XMMRegister src, int vector_len) {
2105
assert(UseAVX > 2, "");
2106
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2107
attributes.set_is_evex_instruction();
2108
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
2109
emit_int16(0x35, (0xC0 | encode));
2110
}
2111
2112
void Assembler::evpmovqb(XMMRegister dst, XMMRegister src, int vector_len) {
2113
assert(UseAVX > 2, "");
2114
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2115
attributes.set_is_evex_instruction();
2116
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
2117
emit_int16(0x32, (0xC0 | encode));
2118
}
2119
2120
void Assembler::evpmovqw(XMMRegister dst, XMMRegister src, int vector_len) {
2121
assert(UseAVX > 2, "");
2122
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2123
attributes.set_is_evex_instruction();
2124
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
2125
emit_int16(0x34, (0xC0 | encode));
2126
}
2127
2128
void Assembler::decl(Address dst) {
2129
// Don't use it directly. Use MacroAssembler::decrement() instead.
2130
InstructionMark im(this);
2131
prefix(dst);
2132
emit_int8((unsigned char)0xFF);
2133
emit_operand(rcx, dst);
2134
}
2135
2136
void Assembler::divsd(XMMRegister dst, Address src) {
2137
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2138
InstructionMark im(this);
2139
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2140
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
2141
attributes.set_rex_vex_w_reverted();
2142
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2143
emit_int8(0x5E);
2144
emit_operand(dst, src);
2145
}
2146
2147
void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2148
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2149
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2150
attributes.set_rex_vex_w_reverted();
2151
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2152
emit_int16(0x5E, (0xC0 | encode));
2153
}
2154
2155
void Assembler::divss(XMMRegister dst, Address src) {
2156
NOT_LP64(assert(VM_Version::supports_sse(), ""));
2157
InstructionMark im(this);
2158
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2159
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
2160
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2161
emit_int8(0x5E);
2162
emit_operand(dst, src);
2163
}
2164
2165
void Assembler::divss(XMMRegister dst, XMMRegister src) {
2166
NOT_LP64(assert(VM_Version::supports_sse(), ""));
2167
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2168
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2169
emit_int16(0x5E, (0xC0 | encode));
2170
}
2171
2172
void Assembler::hlt() {
2173
emit_int8((unsigned char)0xF4);
2174
}
2175
2176
void Assembler::idivl(Register src) {
2177
int encode = prefix_and_encode(src->encoding());
2178
emit_int16((unsigned char)0xF7, (0xF8 | encode));
2179
}
2180
2181
void Assembler::divl(Register src) { // Unsigned
2182
int encode = prefix_and_encode(src->encoding());
2183
emit_int16((unsigned char)0xF7, (0xF0 | encode));
2184
}
2185
2186
void Assembler::imull(Register src) {
2187
int encode = prefix_and_encode(src->encoding());
2188
emit_int16((unsigned char)0xF7, (0xE8 | encode));
2189
}
2190
2191
void Assembler::imull(Register dst, Register src) {
2192
int encode = prefix_and_encode(dst->encoding(), src->encoding());
2193
emit_int24(0x0F,
2194
(unsigned char)0xAF,
2195
(0xC0 | encode));
2196
}
2197
2198
void Assembler::imull(Register dst, Address src, int32_t value) {
2199
InstructionMark im(this);
2200
prefix(src, dst);
2201
if (is8bit(value)) {
2202
emit_int8((unsigned char)0x6B);
2203
emit_operand(dst, src);
2204
emit_int8(value);
2205
} else {
2206
emit_int8((unsigned char)0x69);
2207
emit_operand(dst, src);
2208
emit_int32(value);
2209
}
2210
}
2211
2212
void Assembler::imull(Register dst, Register src, int value) {
2213
int encode = prefix_and_encode(dst->encoding(), src->encoding());
2214
if (is8bit(value)) {
2215
emit_int24(0x6B, (0xC0 | encode), value & 0xFF);
2216
} else {
2217
emit_int16(0x69, (0xC0 | encode));
2218
emit_int32(value);
2219
}
2220
}
2221
2222
void Assembler::imull(Register dst, Address src) {
2223
InstructionMark im(this);
2224
prefix(src, dst);
2225
emit_int16(0x0F, (unsigned char)0xAF);
2226
emit_operand(dst, src);
2227
}
2228
2229
2230
void Assembler::incl(Address dst) {
2231
// Don't use it directly. Use MacroAssembler::increment() instead.
2232
InstructionMark im(this);
2233
prefix(dst);
2234
emit_int8((unsigned char)0xFF);
2235
emit_operand(rax, dst);
2236
}
2237
2238
void Assembler::jcc(Condition cc, Label& L, bool maybe_short) {
2239
InstructionMark im(this);
2240
assert((0 <= cc) && (cc < 16), "illegal cc");
2241
if (L.is_bound()) {
2242
address dst = target(L);
2243
assert(dst != NULL, "jcc most probably wrong");
2244
2245
const int short_size = 2;
2246
const int long_size = 6;
2247
intptr_t offs = (intptr_t)dst - (intptr_t)pc();
2248
if (maybe_short && is8bit(offs - short_size)) {
2249
// 0111 tttn #8-bit disp
2250
emit_int16(0x70 | cc, (offs - short_size) & 0xFF);
2251
} else {
2252
// 0000 1111 1000 tttn #32-bit disp
2253
assert(is_simm32(offs - long_size),
2254
"must be 32bit offset (call4)");
2255
emit_int16(0x0F, (0x80 | cc));
2256
emit_int32(offs - long_size);
2257
}
2258
} else {
2259
// Note: could eliminate cond. jumps to this jump if condition
2260
// is the same however, seems to be rather unlikely case.
2261
// Note: use jccb() if label to be bound is very close to get
2262
// an 8-bit displacement
2263
L.add_patch_at(code(), locator());
2264
emit_int16(0x0F, (0x80 | cc));
2265
emit_int32(0);
2266
}
2267
}
2268
2269
void Assembler::jccb_0(Condition cc, Label& L, const char* file, int line) {
2270
if (L.is_bound()) {
2271
const int short_size = 2;
2272
address entry = target(L);
2273
#ifdef ASSERT
2274
intptr_t dist = (intptr_t)entry - ((intptr_t)pc() + short_size);
2275
intptr_t delta = short_branch_delta();
2276
if (delta != 0) {
2277
dist += (dist < 0 ? (-delta) :delta);
2278
}
2279
assert(is8bit(dist), "Dispacement too large for a short jmp at %s:%d", file, line);
2280
#endif
2281
intptr_t offs = (intptr_t)entry - (intptr_t)pc();
2282
// 0111 tttn #8-bit disp
2283
emit_int16(0x70 | cc, (offs - short_size) & 0xFF);
2284
} else {
2285
InstructionMark im(this);
2286
L.add_patch_at(code(), locator(), file, line);
2287
emit_int16(0x70 | cc, 0);
2288
}
2289
}
2290
2291
void Assembler::jmp(Address adr) {
2292
InstructionMark im(this);
2293
prefix(adr);
2294
emit_int8((unsigned char)0xFF);
2295
emit_operand(rsp, adr);
2296
}
2297
2298
void Assembler::jmp(Label& L, bool maybe_short) {
2299
if (L.is_bound()) {
2300
address entry = target(L);
2301
assert(entry != NULL, "jmp most probably wrong");
2302
InstructionMark im(this);
2303
const int short_size = 2;
2304
const int long_size = 5;
2305
intptr_t offs = entry - pc();
2306
if (maybe_short && is8bit(offs - short_size)) {
2307
emit_int16((unsigned char)0xEB, ((offs - short_size) & 0xFF));
2308
} else {
2309
emit_int8((unsigned char)0xE9);
2310
emit_int32(offs - long_size);
2311
}
2312
} else {
2313
// By default, forward jumps are always 32-bit displacements, since
2314
// we can't yet know where the label will be bound. If you're sure that
2315
// the forward jump will not run beyond 256 bytes, use jmpb to
2316
// force an 8-bit displacement.
2317
InstructionMark im(this);
2318
L.add_patch_at(code(), locator());
2319
emit_int8((unsigned char)0xE9);
2320
emit_int32(0);
2321
}
2322
}
2323
2324
void Assembler::jmp(Register entry) {
2325
int encode = prefix_and_encode(entry->encoding());
2326
emit_int16((unsigned char)0xFF, (0xE0 | encode));
2327
}
2328
2329
void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) {
2330
InstructionMark im(this);
2331
emit_int8((unsigned char)0xE9);
2332
assert(dest != NULL, "must have a target");
2333
intptr_t disp = dest - (pc() + sizeof(int32_t));
2334
assert(is_simm32(disp), "must be 32bit offset (jmp)");
2335
emit_data(disp, rspec.reloc(), call32_operand);
2336
}
2337
2338
void Assembler::jmpb_0(Label& L, const char* file, int line) {
2339
if (L.is_bound()) {
2340
const int short_size = 2;
2341
address entry = target(L);
2342
assert(entry != NULL, "jmp most probably wrong");
2343
#ifdef ASSERT
2344
intptr_t dist = (intptr_t)entry - ((intptr_t)pc() + short_size);
2345
intptr_t delta = short_branch_delta();
2346
if (delta != 0) {
2347
dist += (dist < 0 ? (-delta) :delta);
2348
}
2349
assert(is8bit(dist), "Dispacement too large for a short jmp at %s:%d", file, line);
2350
#endif
2351
intptr_t offs = entry - pc();
2352
emit_int16((unsigned char)0xEB, (offs - short_size) & 0xFF);
2353
} else {
2354
InstructionMark im(this);
2355
L.add_patch_at(code(), locator(), file, line);
2356
emit_int16((unsigned char)0xEB, 0);
2357
}
2358
}
2359
2360
void Assembler::ldmxcsr( Address src) {
2361
if (UseAVX > 0 ) {
2362
InstructionMark im(this);
2363
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2364
vex_prefix(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2365
emit_int8((unsigned char)0xAE);
2366
emit_operand(as_Register(2), src);
2367
} else {
2368
NOT_LP64(assert(VM_Version::supports_sse(), ""));
2369
InstructionMark im(this);
2370
prefix(src);
2371
emit_int16(0x0F, (unsigned char)0xAE);
2372
emit_operand(as_Register(2), src);
2373
}
2374
}
2375
2376
void Assembler::leal(Register dst, Address src) {
2377
InstructionMark im(this);
2378
#ifdef _LP64
2379
emit_int8(0x67); // addr32
2380
prefix(src, dst);
2381
#endif // LP64
2382
emit_int8((unsigned char)0x8D);
2383
emit_operand(dst, src);
2384
}
2385
2386
void Assembler::lfence() {
2387
emit_int24(0x0F, (unsigned char)0xAE, (unsigned char)0xE8);
2388
}
2389
2390
void Assembler::lock() {
2391
emit_int8((unsigned char)0xF0);
2392
}
2393
2394
void Assembler::size_prefix() {
2395
emit_int8(0x66);
2396
}
2397
2398
void Assembler::lzcntl(Register dst, Register src) {
2399
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
2400
emit_int8((unsigned char)0xF3);
2401
int encode = prefix_and_encode(dst->encoding(), src->encoding());
2402
emit_int24(0x0F, (unsigned char)0xBD, (0xC0 | encode));
2403
}
2404
2405
// Emit mfence instruction
2406
void Assembler::mfence() {
2407
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
2408
emit_int24(0x0F, (unsigned char)0xAE, (unsigned char)0xF0);
2409
}
2410
2411
// Emit sfence instruction
2412
void Assembler::sfence() {
2413
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
2414
emit_int24(0x0F, (unsigned char)0xAE, (unsigned char)0xF8);
2415
}
2416
2417
void Assembler::mov(Register dst, Register src) {
2418
LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src));
2419
}
2420
2421
void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2422
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2423
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
2424
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2425
attributes.set_rex_vex_w_reverted();
2426
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2427
emit_int16(0x28, (0xC0 | encode));
2428
}
2429
2430
void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2431
NOT_LP64(assert(VM_Version::supports_sse(), ""));
2432
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
2433
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2434
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2435
emit_int16(0x28, (0xC0 | encode));
2436
}
2437
2438
void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
2439
NOT_LP64(assert(VM_Version::supports_sse(), ""));
2440
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2441
int encode = simd_prefix_and_encode(dst, src, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2442
emit_int16(0x16, (0xC0 | encode));
2443
}
2444
2445
void Assembler::movb(Register dst, Address src) {
2446
NOT_LP64(assert(dst->has_byte_register(), "must have byte register"));
2447
InstructionMark im(this);
2448
prefix(src, dst, true);
2449
emit_int8((unsigned char)0x8A);
2450
emit_operand(dst, src);
2451
}
2452
2453
void Assembler::movddup(XMMRegister dst, XMMRegister src) {
2454
NOT_LP64(assert(VM_Version::supports_sse3(), ""));
2455
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
2456
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2457
attributes.set_rex_vex_w_reverted();
2458
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2459
emit_int16(0x12, 0xC0 | encode);
2460
}
2461
2462
void Assembler::kmovbl(KRegister dst, Register src) {
2463
assert(VM_Version::supports_avx512dq(), "");
2464
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2465
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2466
emit_int16((unsigned char)0x92, (0xC0 | encode));
2467
}
2468
2469
void Assembler::kmovbl(Register dst, KRegister src) {
2470
assert(VM_Version::supports_avx512dq(), "");
2471
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2472
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2473
emit_int16((unsigned char)0x93, (0xC0 | encode));
2474
}
2475
2476
void Assembler::kmovwl(KRegister dst, Register src) {
2477
assert(VM_Version::supports_evex(), "");
2478
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2479
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2480
emit_int16((unsigned char)0x92, (0xC0 | encode));
2481
}
2482
2483
void Assembler::kmovwl(Register dst, KRegister src) {
2484
assert(VM_Version::supports_evex(), "");
2485
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2486
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2487
emit_int16((unsigned char)0x93, (0xC0 | encode));
2488
}
2489
2490
void Assembler::kmovwl(KRegister dst, Address src) {
2491
assert(VM_Version::supports_evex(), "");
2492
InstructionMark im(this);
2493
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2494
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2495
emit_int8((unsigned char)0x90);
2496
emit_operand((Register)dst, src);
2497
}
2498
2499
void Assembler::kmovwl(Address dst, KRegister src) {
2500
assert(VM_Version::supports_evex(), "");
2501
InstructionMark im(this);
2502
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2503
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2504
emit_int8((unsigned char)0x91);
2505
emit_operand((Register)src, dst);
2506
}
2507
2508
void Assembler::kmovwl(KRegister dst, KRegister src) {
2509
assert(VM_Version::supports_avx512bw(), "");
2510
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2511
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2512
emit_int16((unsigned char)0x90, (0xC0 | encode));
2513
}
2514
2515
void Assembler::kmovdl(KRegister dst, Register src) {
2516
assert(VM_Version::supports_avx512bw(), "");
2517
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2518
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2519
emit_int16((unsigned char)0x92, (0xC0 | encode));
2520
}
2521
2522
void Assembler::kmovdl(Register dst, KRegister src) {
2523
assert(VM_Version::supports_avx512bw(), "");
2524
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2525
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2526
emit_int16((unsigned char)0x93, (0xC0 | encode));
2527
}
2528
2529
void Assembler::kmovql(KRegister dst, KRegister src) {
2530
assert(VM_Version::supports_avx512bw(), "");
2531
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2532
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2533
emit_int16((unsigned char)0x90, (0xC0 | encode));
2534
}
2535
2536
void Assembler::kmovql(KRegister dst, Address src) {
2537
assert(VM_Version::supports_avx512bw(), "");
2538
InstructionMark im(this);
2539
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2540
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2541
emit_int8((unsigned char)0x90);
2542
emit_operand((Register)dst, src);
2543
}
2544
2545
void Assembler::kmovql(Address dst, KRegister src) {
2546
assert(VM_Version::supports_avx512bw(), "");
2547
InstructionMark im(this);
2548
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2549
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2550
emit_int8((unsigned char)0x91);
2551
emit_operand((Register)src, dst);
2552
}
2553
2554
void Assembler::kmovql(KRegister dst, Register src) {
2555
assert(VM_Version::supports_avx512bw(), "");
2556
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2557
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2558
emit_int16((unsigned char)0x92, (0xC0 | encode));
2559
}
2560
2561
void Assembler::kmovql(Register dst, KRegister src) {
2562
assert(VM_Version::supports_avx512bw(), "");
2563
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2564
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2565
emit_int16((unsigned char)0x93, (0xC0 | encode));
2566
}
2567
2568
void Assembler::knotwl(KRegister dst, KRegister src) {
2569
assert(VM_Version::supports_evex(), "");
2570
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2571
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2572
emit_int16(0x44, (0xC0 | encode));
2573
}
2574
2575
// This instruction produces ZF or CF flags
2576
void Assembler::kortestbl(KRegister src1, KRegister src2) {
2577
assert(VM_Version::supports_avx512dq(), "");
2578
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2579
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2580
emit_int16((unsigned char)0x98, (0xC0 | encode));
2581
}
2582
2583
// This instruction produces ZF or CF flags
2584
void Assembler::kortestwl(KRegister src1, KRegister src2) {
2585
assert(VM_Version::supports_evex(), "");
2586
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2587
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2588
emit_int16((unsigned char)0x98, (0xC0 | encode));
2589
}
2590
2591
// This instruction produces ZF or CF flags
2592
void Assembler::kortestdl(KRegister src1, KRegister src2) {
2593
assert(VM_Version::supports_avx512bw(), "");
2594
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2595
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2596
emit_int16((unsigned char)0x98, (0xC0 | encode));
2597
}
2598
2599
// This instruction produces ZF or CF flags
2600
void Assembler::kortestql(KRegister src1, KRegister src2) {
2601
assert(VM_Version::supports_avx512bw(), "");
2602
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2603
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2604
emit_int16((unsigned char)0x98, (0xC0 | encode));
2605
}
2606
2607
// This instruction produces ZF or CF flags
2608
void Assembler::ktestql(KRegister src1, KRegister src2) {
2609
assert(VM_Version::supports_avx512bw(), "");
2610
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2611
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2612
emit_int16((unsigned char)0x99, (0xC0 | encode));
2613
}
2614
2615
void Assembler::ktestq(KRegister src1, KRegister src2) {
2616
assert(VM_Version::supports_avx512bw(), "");
2617
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2618
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2619
emit_int16((unsigned char)0x99, (0xC0 | encode));
2620
}
2621
2622
void Assembler::ktestd(KRegister src1, KRegister src2) {
2623
assert(VM_Version::supports_avx512bw(), "");
2624
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2625
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2626
emit_int16((unsigned char)0x99, (0xC0 | encode));
2627
}
2628
2629
void Assembler::movb(Address dst, int imm8) {
2630
InstructionMark im(this);
2631
prefix(dst);
2632
emit_int8((unsigned char)0xC6);
2633
emit_operand(rax, dst, 1);
2634
emit_int8(imm8);
2635
}
2636
2637
2638
void Assembler::movb(Address dst, Register src) {
2639
assert(src->has_byte_register(), "must have byte register");
2640
InstructionMark im(this);
2641
prefix(dst, src, true);
2642
emit_int8((unsigned char)0x88);
2643
emit_operand(src, dst);
2644
}
2645
2646
void Assembler::movdl(XMMRegister dst, Register src) {
2647
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2648
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2649
int encode = simd_prefix_and_encode(dst, xnoreg, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2650
emit_int16(0x6E, (0xC0 | encode));
2651
}
2652
2653
void Assembler::movdl(Register dst, XMMRegister src) {
2654
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2655
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2656
// swap src/dst to get correct prefix
2657
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2658
emit_int16(0x7E, (0xC0 | encode));
2659
}
2660
2661
void Assembler::movdl(XMMRegister dst, Address src) {
2662
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2663
InstructionMark im(this);
2664
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2665
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
2666
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2667
emit_int8(0x6E);
2668
emit_operand(dst, src);
2669
}
2670
2671
void Assembler::movdl(Address dst, XMMRegister src) {
2672
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2673
InstructionMark im(this);
2674
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2675
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
2676
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2677
emit_int8(0x7E);
2678
emit_operand(src, dst);
2679
}
2680
2681
void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
2682
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2683
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2684
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2685
emit_int16(0x6F, (0xC0 | encode));
2686
}
2687
2688
void Assembler::movdqa(XMMRegister dst, Address src) {
2689
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2690
InstructionMark im(this);
2691
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2692
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2693
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2694
emit_int8(0x6F);
2695
emit_operand(dst, src);
2696
}
2697
2698
void Assembler::movdqu(XMMRegister dst, Address src) {
2699
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2700
InstructionMark im(this);
2701
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2702
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2703
simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2704
emit_int8(0x6F);
2705
emit_operand(dst, src);
2706
}
2707
2708
void Assembler::movdqu(XMMRegister dst, XMMRegister src) {
2709
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2710
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2711
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2712
emit_int16(0x6F, (0xC0 | encode));
2713
}
2714
2715
void Assembler::movdqu(Address dst, XMMRegister src) {
2716
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2717
InstructionMark im(this);
2718
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2719
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2720
attributes.reset_is_clear_context();
2721
simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2722
emit_int8(0x7F);
2723
emit_operand(src, dst);
2724
}
2725
2726
// Move Unaligned 256bit Vector
2727
void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
2728
assert(UseAVX > 0, "");
2729
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2730
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2731
emit_int16(0x6F, (0xC0 | encode));
2732
}
2733
2734
void Assembler::vmovdqu(XMMRegister dst, Address src) {
2735
assert(UseAVX > 0, "");
2736
InstructionMark im(this);
2737
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2738
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2739
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2740
emit_int8(0x6F);
2741
emit_operand(dst, src);
2742
}
2743
2744
void Assembler::vmovdqu(Address dst, XMMRegister src) {
2745
assert(UseAVX > 0, "");
2746
InstructionMark im(this);
2747
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2748
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2749
attributes.reset_is_clear_context();
2750
// swap src<->dst for encoding
2751
assert(src != xnoreg, "sanity");
2752
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2753
emit_int8(0x7F);
2754
emit_operand(src, dst);
2755
}
2756
2757
// Move Unaligned EVEX enabled Vector (programmable : 8,16,32,64)
2758
void Assembler::evmovdqub(XMMRegister dst, XMMRegister src, bool merge, int vector_len) {
2759
assert(VM_Version::supports_evex(), "");
2760
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2761
attributes.set_is_evex_instruction();
2762
if (merge) {
2763
attributes.reset_is_clear_context();
2764
}
2765
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2766
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2767
emit_int16(0x6F, (0xC0 | encode));
2768
}
2769
2770
void Assembler::evmovdqub(XMMRegister dst, Address src, bool merge, int vector_len) {
2771
assert(VM_Version::supports_evex(), "");
2772
InstructionMark im(this);
2773
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2774
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2775
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2776
attributes.set_is_evex_instruction();
2777
if (merge) {
2778
attributes.reset_is_clear_context();
2779
}
2780
vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2781
emit_int8(0x6F);
2782
emit_operand(dst, src);
2783
}
2784
2785
void Assembler::evmovdqub(Address dst, XMMRegister src, bool merge, int vector_len) {
2786
assert(VM_Version::supports_evex(), "");
2787
assert(src != xnoreg, "sanity");
2788
InstructionMark im(this);
2789
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2790
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2791
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2792
attributes.set_is_evex_instruction();
2793
if (merge) {
2794
attributes.reset_is_clear_context();
2795
}
2796
vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2797
emit_int8(0x7F);
2798
emit_operand(src, dst);
2799
}
2800
2801
void Assembler::evmovdqub(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2802
assert(VM_Version::supports_avx512vlbw(), "");
2803
InstructionMark im(this);
2804
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2805
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2806
attributes.set_embedded_opmask_register_specifier(mask);
2807
attributes.set_is_evex_instruction();
2808
if (merge) {
2809
attributes.reset_is_clear_context();
2810
}
2811
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2812
emit_int8(0x6F);
2813
emit_operand(dst, src);
2814
}
2815
2816
void Assembler::evmovdqub(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2817
assert(VM_Version::supports_avx512vlbw(), "");
2818
assert(src != xnoreg, "sanity");
2819
InstructionMark im(this);
2820
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2821
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2822
attributes.set_embedded_opmask_register_specifier(mask);
2823
attributes.set_is_evex_instruction();
2824
if (merge) {
2825
attributes.reset_is_clear_context();
2826
}
2827
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2828
emit_int8(0x7F);
2829
emit_operand(src, dst);
2830
}
2831
2832
void Assembler::evmovdquw(XMMRegister dst, Address src, bool merge, int vector_len) {
2833
assert(VM_Version::supports_evex(), "");
2834
InstructionMark im(this);
2835
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2836
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2837
attributes.set_is_evex_instruction();
2838
if (merge) {
2839
attributes.reset_is_clear_context();
2840
}
2841
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2842
vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2843
emit_int8(0x6F);
2844
emit_operand(dst, src);
2845
}
2846
2847
void Assembler::evmovdquw(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2848
assert(VM_Version::supports_avx512vlbw(), "");
2849
InstructionMark im(this);
2850
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2851
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2852
attributes.set_embedded_opmask_register_specifier(mask);
2853
attributes.set_is_evex_instruction();
2854
if (merge) {
2855
attributes.reset_is_clear_context();
2856
}
2857
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2858
emit_int8(0x6F);
2859
emit_operand(dst, src);
2860
}
2861
2862
void Assembler::evmovdquw(Address dst, XMMRegister src, bool merge, int vector_len) {
2863
assert(VM_Version::supports_evex(), "");
2864
assert(src != xnoreg, "sanity");
2865
InstructionMark im(this);
2866
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2867
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2868
attributes.set_is_evex_instruction();
2869
if (merge) {
2870
attributes.reset_is_clear_context();
2871
}
2872
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2873
vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2874
emit_int8(0x7F);
2875
emit_operand(src, dst);
2876
}
2877
2878
void Assembler::evmovdquw(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2879
assert(VM_Version::supports_avx512vlbw(), "");
2880
assert(src != xnoreg, "sanity");
2881
InstructionMark im(this);
2882
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2883
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2884
attributes.set_embedded_opmask_register_specifier(mask);
2885
attributes.set_is_evex_instruction();
2886
if (merge) {
2887
attributes.reset_is_clear_context();
2888
}
2889
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2890
emit_int8(0x7F);
2891
emit_operand(src, dst);
2892
}
2893
2894
void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) {
2895
// Unmasked instruction
2896
evmovdqul(dst, k0, src, /*merge*/ false, vector_len);
2897
}
2898
2899
void Assembler::evmovdqul(XMMRegister dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2900
assert(VM_Version::supports_evex(), "");
2901
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2902
attributes.set_embedded_opmask_register_specifier(mask);
2903
attributes.set_is_evex_instruction();
2904
if (merge) {
2905
attributes.reset_is_clear_context();
2906
}
2907
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2908
emit_int16(0x6F, (0xC0 | encode));
2909
}
2910
2911
void Assembler::evmovdqul(XMMRegister dst, Address src, int vector_len) {
2912
// Unmasked instruction
2913
evmovdqul(dst, k0, src, /*merge*/ false, vector_len);
2914
}
2915
2916
void Assembler::evmovdqul(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2917
assert(VM_Version::supports_evex(), "");
2918
InstructionMark im(this);
2919
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false , /* uses_vl */ true);
2920
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2921
attributes.set_embedded_opmask_register_specifier(mask);
2922
attributes.set_is_evex_instruction();
2923
if (merge) {
2924
attributes.reset_is_clear_context();
2925
}
2926
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2927
emit_int8(0x6F);
2928
emit_operand(dst, src);
2929
}
2930
2931
void Assembler::evmovdqul(Address dst, XMMRegister src, int vector_len) {
2932
// Unmasked isntruction
2933
evmovdqul(dst, k0, src, /*merge*/ true, vector_len);
2934
}
2935
2936
void Assembler::evmovdqul(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2937
assert(VM_Version::supports_evex(), "");
2938
assert(src != xnoreg, "sanity");
2939
InstructionMark im(this);
2940
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2941
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2942
attributes.set_embedded_opmask_register_specifier(mask);
2943
attributes.set_is_evex_instruction();
2944
if (merge) {
2945
attributes.reset_is_clear_context();
2946
}
2947
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2948
emit_int8(0x7F);
2949
emit_operand(src, dst);
2950
}
2951
2952
void Assembler::evmovdquq(XMMRegister dst, XMMRegister src, int vector_len) {
2953
// Unmasked instruction
2954
if (dst->encoding() == src->encoding()) return;
2955
evmovdquq(dst, k0, src, /*merge*/ false, vector_len);
2956
}
2957
2958
void Assembler::evmovdquq(XMMRegister dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2959
assert(VM_Version::supports_evex(), "");
2960
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2961
attributes.set_embedded_opmask_register_specifier(mask);
2962
attributes.set_is_evex_instruction();
2963
if (merge) {
2964
attributes.reset_is_clear_context();
2965
}
2966
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2967
emit_int16(0x6F, (0xC0 | encode));
2968
}
2969
2970
void Assembler::evmovdquq(XMMRegister dst, Address src, int vector_len) {
2971
// Unmasked instruction
2972
evmovdquq(dst, k0, src, /*merge*/ false, vector_len);
2973
}
2974
2975
void Assembler::evmovdquq(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2976
assert(VM_Version::supports_evex(), "");
2977
InstructionMark im(this);
2978
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2979
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2980
attributes.set_embedded_opmask_register_specifier(mask);
2981
attributes.set_is_evex_instruction();
2982
if (merge) {
2983
attributes.reset_is_clear_context();
2984
}
2985
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2986
emit_int8(0x6F);
2987
emit_operand(dst, src);
2988
}
2989
2990
void Assembler::evmovdquq(Address dst, XMMRegister src, int vector_len) {
2991
// Unmasked instruction
2992
evmovdquq(dst, k0, src, /*merge*/ true, vector_len);
2993
}
2994
2995
void Assembler::evmovdquq(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2996
assert(VM_Version::supports_evex(), "");
2997
assert(src != xnoreg, "sanity");
2998
InstructionMark im(this);
2999
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
3000
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3001
attributes.set_embedded_opmask_register_specifier(mask);
3002
if (merge) {
3003
attributes.reset_is_clear_context();
3004
}
3005
attributes.set_is_evex_instruction();
3006
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3007
emit_int8(0x7F);
3008
emit_operand(src, dst);
3009
}
3010
3011
// Uses zero extension on 64bit
3012
3013
void Assembler::movl(Register dst, int32_t imm32) {
3014
int encode = prefix_and_encode(dst->encoding());
3015
emit_int8(0xB8 | encode);
3016
emit_int32(imm32);
3017
}
3018
3019
void Assembler::movl(Register dst, Register src) {
3020
int encode = prefix_and_encode(dst->encoding(), src->encoding());
3021
emit_int16((unsigned char)0x8B, (0xC0 | encode));
3022
}
3023
3024
void Assembler::movl(Register dst, Address src) {
3025
InstructionMark im(this);
3026
prefix(src, dst);
3027
emit_int8((unsigned char)0x8B);
3028
emit_operand(dst, src);
3029
}
3030
3031
void Assembler::movl(Address dst, int32_t imm32) {
3032
InstructionMark im(this);
3033
prefix(dst);
3034
emit_int8((unsigned char)0xC7);
3035
emit_operand(rax, dst, 4);
3036
emit_int32(imm32);
3037
}
3038
3039
void Assembler::movl(Address dst, Register src) {
3040
InstructionMark im(this);
3041
prefix(dst, src);
3042
emit_int8((unsigned char)0x89);
3043
emit_operand(src, dst);
3044
}
3045
3046
// New cpus require to use movsd and movss to avoid partial register stall
3047
// when loading from memory. But for old Opteron use movlpd instead of movsd.
3048
// The selection is done in MacroAssembler::movdbl() and movflt().
3049
void Assembler::movlpd(XMMRegister dst, Address src) {
3050
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3051
InstructionMark im(this);
3052
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3053
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3054
attributes.set_rex_vex_w_reverted();
3055
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3056
emit_int8(0x12);
3057
emit_operand(dst, src);
3058
}
3059
3060
void Assembler::movq(XMMRegister dst, Address src) {
3061
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3062
InstructionMark im(this);
3063
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3064
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3065
attributes.set_rex_vex_w_reverted();
3066
simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3067
emit_int8(0x7E);
3068
emit_operand(dst, src);
3069
}
3070
3071
void Assembler::movq(Address dst, XMMRegister src) {
3072
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3073
InstructionMark im(this);
3074
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3075
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3076
attributes.set_rex_vex_w_reverted();
3077
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3078
emit_int8((unsigned char)0xD6);
3079
emit_operand(src, dst);
3080
}
3081
3082
void Assembler::movq(XMMRegister dst, XMMRegister src) {
3083
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3084
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3085
attributes.set_rex_vex_w_reverted();
3086
int encode = simd_prefix_and_encode(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3087
emit_int16((unsigned char)0xD6, (0xC0 | encode));
3088
}
3089
3090
void Assembler::movq(Register dst, XMMRegister src) {
3091
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3092
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3093
// swap src/dst to get correct prefix
3094
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3095
emit_int16(0x7E, (0xC0 | encode));
3096
}
3097
3098
void Assembler::movq(XMMRegister dst, Register src) {
3099
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3100
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3101
int encode = simd_prefix_and_encode(dst, xnoreg, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3102
emit_int16(0x6E, (0xC0 | encode));
3103
}
3104
3105
void Assembler::movsbl(Register dst, Address src) { // movsxb
3106
InstructionMark im(this);
3107
prefix(src, dst);
3108
emit_int16(0x0F, (unsigned char)0xBE);
3109
emit_operand(dst, src);
3110
}
3111
3112
void Assembler::movsbl(Register dst, Register src) { // movsxb
3113
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
3114
int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
3115
emit_int24(0x0F, (unsigned char)0xBE, (0xC0 | encode));
3116
}
3117
3118
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
3119
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3120
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3121
attributes.set_rex_vex_w_reverted();
3122
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3123
emit_int16(0x10, (0xC0 | encode));
3124
}
3125
3126
void Assembler::movsd(XMMRegister dst, Address src) {
3127
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3128
InstructionMark im(this);
3129
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3130
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3131
attributes.set_rex_vex_w_reverted();
3132
simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3133
emit_int8(0x10);
3134
emit_operand(dst, src);
3135
}
3136
3137
void Assembler::movsd(Address dst, XMMRegister src) {
3138
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3139
InstructionMark im(this);
3140
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3141
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3142
attributes.reset_is_clear_context();
3143
attributes.set_rex_vex_w_reverted();
3144
simd_prefix(src, xnoreg, dst, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3145
emit_int8(0x11);
3146
emit_operand(src, dst);
3147
}
3148
3149
void Assembler::movss(XMMRegister dst, XMMRegister src) {
3150
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3151
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3152
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3153
emit_int16(0x10, (0xC0 | encode));
3154
}
3155
3156
void Assembler::movss(XMMRegister dst, Address src) {
3157
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3158
InstructionMark im(this);
3159
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3160
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
3161
simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3162
emit_int8(0x10);
3163
emit_operand(dst, src);
3164
}
3165
3166
void Assembler::movss(Address dst, XMMRegister src) {
3167
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3168
InstructionMark im(this);
3169
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3170
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
3171
attributes.reset_is_clear_context();
3172
simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3173
emit_int8(0x11);
3174
emit_operand(src, dst);
3175
}
3176
3177
void Assembler::movswl(Register dst, Address src) { // movsxw
3178
InstructionMark im(this);
3179
prefix(src, dst);
3180
emit_int16(0x0F, (unsigned char)0xBF);
3181
emit_operand(dst, src);
3182
}
3183
3184
void Assembler::movswl(Register dst, Register src) { // movsxw
3185
int encode = prefix_and_encode(dst->encoding(), src->encoding());
3186
emit_int24(0x0F, (unsigned char)0xBF, (0xC0 | encode));
3187
}
3188
3189
void Assembler::movw(Address dst, int imm16) {
3190
InstructionMark im(this);
3191
3192
emit_int8(0x66); // switch to 16-bit mode
3193
prefix(dst);
3194
emit_int8((unsigned char)0xC7);
3195
emit_operand(rax, dst, 2);
3196
emit_int16(imm16);
3197
}
3198
3199
void Assembler::movw(Register dst, Address src) {
3200
InstructionMark im(this);
3201
emit_int8(0x66);
3202
prefix(src, dst);
3203
emit_int8((unsigned char)0x8B);
3204
emit_operand(dst, src);
3205
}
3206
3207
void Assembler::movw(Address dst, Register src) {
3208
InstructionMark im(this);
3209
emit_int8(0x66);
3210
prefix(dst, src);
3211
emit_int8((unsigned char)0x89);
3212
emit_operand(src, dst);
3213
}
3214
3215
void Assembler::movzbl(Register dst, Address src) { // movzxb
3216
InstructionMark im(this);
3217
prefix(src, dst);
3218
emit_int16(0x0F, (unsigned char)0xB6);
3219
emit_operand(dst, src);
3220
}
3221
3222
void Assembler::movzbl(Register dst, Register src) { // movzxb
3223
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
3224
int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
3225
emit_int24(0x0F, (unsigned char)0xB6, 0xC0 | encode);
3226
}
3227
3228
void Assembler::movzwl(Register dst, Address src) { // movzxw
3229
InstructionMark im(this);
3230
prefix(src, dst);
3231
emit_int16(0x0F, (unsigned char)0xB7);
3232
emit_operand(dst, src);
3233
}
3234
3235
void Assembler::movzwl(Register dst, Register src) { // movzxw
3236
int encode = prefix_and_encode(dst->encoding(), src->encoding());
3237
emit_int24(0x0F, (unsigned char)0xB7, 0xC0 | encode);
3238
}
3239
3240
void Assembler::mull(Address src) {
3241
InstructionMark im(this);
3242
prefix(src);
3243
emit_int8((unsigned char)0xF7);
3244
emit_operand(rsp, src);
3245
}
3246
3247
void Assembler::mull(Register src) {
3248
int encode = prefix_and_encode(src->encoding());
3249
emit_int16((unsigned char)0xF7, (0xE0 | encode));
3250
}
3251
3252
void Assembler::mulsd(XMMRegister dst, Address src) {
3253
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3254
InstructionMark im(this);
3255
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3256
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3257
attributes.set_rex_vex_w_reverted();
3258
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3259
emit_int8(0x59);
3260
emit_operand(dst, src);
3261
}
3262
3263
void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
3264
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3265
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3266
attributes.set_rex_vex_w_reverted();
3267
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3268
emit_int16(0x59, (0xC0 | encode));
3269
}
3270
3271
void Assembler::mulss(XMMRegister dst, Address src) {
3272
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3273
InstructionMark im(this);
3274
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3275
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
3276
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3277
emit_int8(0x59);
3278
emit_operand(dst, src);
3279
}
3280
3281
void Assembler::mulss(XMMRegister dst, XMMRegister src) {
3282
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3283
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3284
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3285
emit_int16(0x59, (0xC0 | encode));
3286
}
3287
3288
void Assembler::negl(Register dst) {
3289
int encode = prefix_and_encode(dst->encoding());
3290
emit_int16((unsigned char)0xF7, (0xD8 | encode));
3291
}
3292
3293
void Assembler::negl(Address dst) {
3294
InstructionMark im(this);
3295
prefix(dst);
3296
emit_int8((unsigned char)0xF7);
3297
emit_operand(as_Register(3), dst);
3298
}
3299
3300
void Assembler::nop(int i) {
3301
#ifdef ASSERT
3302
assert(i > 0, " ");
3303
// The fancy nops aren't currently recognized by debuggers making it a
3304
// pain to disassemble code while debugging. If asserts are on clearly
3305
// speed is not an issue so simply use the single byte traditional nop
3306
// to do alignment.
3307
3308
for (; i > 0 ; i--) emit_int8((unsigned char)0x90);
3309
return;
3310
3311
#endif // ASSERT
3312
3313
if (UseAddressNop && VM_Version::is_intel()) {
3314
//
3315
// Using multi-bytes nops "0x0F 0x1F [address]" for Intel
3316
// 1: 0x90
3317
// 2: 0x66 0x90
3318
// 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
3319
// 4: 0x0F 0x1F 0x40 0x00
3320
// 5: 0x0F 0x1F 0x44 0x00 0x00
3321
// 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
3322
// 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3323
// 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3324
// 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3325
// 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3326
// 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3327
3328
// The rest coding is Intel specific - don't use consecutive address nops
3329
3330
// 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3331
// 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3332
// 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3333
// 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3334
3335
while(i >= 15) {
3336
// For Intel don't generate consecutive addess nops (mix with regular nops)
3337
i -= 15;
3338
emit_int24(0x66, 0x66, 0x66);
3339
addr_nop_8();
3340
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3341
}
3342
switch (i) {
3343
case 14:
3344
emit_int8(0x66); // size prefix
3345
case 13:
3346
emit_int8(0x66); // size prefix
3347
case 12:
3348
addr_nop_8();
3349
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3350
break;
3351
case 11:
3352
emit_int8(0x66); // size prefix
3353
case 10:
3354
emit_int8(0x66); // size prefix
3355
case 9:
3356
emit_int8(0x66); // size prefix
3357
case 8:
3358
addr_nop_8();
3359
break;
3360
case 7:
3361
addr_nop_7();
3362
break;
3363
case 6:
3364
emit_int8(0x66); // size prefix
3365
case 5:
3366
addr_nop_5();
3367
break;
3368
case 4:
3369
addr_nop_4();
3370
break;
3371
case 3:
3372
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
3373
emit_int8(0x66); // size prefix
3374
case 2:
3375
emit_int8(0x66); // size prefix
3376
case 1:
3377
emit_int8((unsigned char)0x90);
3378
// nop
3379
break;
3380
default:
3381
assert(i == 0, " ");
3382
}
3383
return;
3384
}
3385
if (UseAddressNop && VM_Version::is_amd_family()) {
3386
//
3387
// Using multi-bytes nops "0x0F 0x1F [address]" for AMD.
3388
// 1: 0x90
3389
// 2: 0x66 0x90
3390
// 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
3391
// 4: 0x0F 0x1F 0x40 0x00
3392
// 5: 0x0F 0x1F 0x44 0x00 0x00
3393
// 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
3394
// 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3395
// 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3396
// 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3397
// 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3398
// 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3399
3400
// The rest coding is AMD specific - use consecutive address nops
3401
3402
// 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
3403
// 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
3404
// 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3405
// 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3406
// 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3407
// Size prefixes (0x66) are added for larger sizes
3408
3409
while(i >= 22) {
3410
i -= 11;
3411
emit_int24(0x66, 0x66, 0x66);
3412
addr_nop_8();
3413
}
3414
// Generate first nop for size between 21-12
3415
switch (i) {
3416
case 21:
3417
i -= 1;
3418
emit_int8(0x66); // size prefix
3419
case 20:
3420
case 19:
3421
i -= 1;
3422
emit_int8(0x66); // size prefix
3423
case 18:
3424
case 17:
3425
i -= 1;
3426
emit_int8(0x66); // size prefix
3427
case 16:
3428
case 15:
3429
i -= 8;
3430
addr_nop_8();
3431
break;
3432
case 14:
3433
case 13:
3434
i -= 7;
3435
addr_nop_7();
3436
break;
3437
case 12:
3438
i -= 6;
3439
emit_int8(0x66); // size prefix
3440
addr_nop_5();
3441
break;
3442
default:
3443
assert(i < 12, " ");
3444
}
3445
3446
// Generate second nop for size between 11-1
3447
switch (i) {
3448
case 11:
3449
emit_int8(0x66); // size prefix
3450
case 10:
3451
emit_int8(0x66); // size prefix
3452
case 9:
3453
emit_int8(0x66); // size prefix
3454
case 8:
3455
addr_nop_8();
3456
break;
3457
case 7:
3458
addr_nop_7();
3459
break;
3460
case 6:
3461
emit_int8(0x66); // size prefix
3462
case 5:
3463
addr_nop_5();
3464
break;
3465
case 4:
3466
addr_nop_4();
3467
break;
3468
case 3:
3469
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
3470
emit_int8(0x66); // size prefix
3471
case 2:
3472
emit_int8(0x66); // size prefix
3473
case 1:
3474
emit_int8((unsigned char)0x90);
3475
// nop
3476
break;
3477
default:
3478
assert(i == 0, " ");
3479
}
3480
return;
3481
}
3482
3483
if (UseAddressNop && VM_Version::is_zx()) {
3484
//
3485
// Using multi-bytes nops "0x0F 0x1F [address]" for ZX
3486
// 1: 0x90
3487
// 2: 0x66 0x90
3488
// 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
3489
// 4: 0x0F 0x1F 0x40 0x00
3490
// 5: 0x0F 0x1F 0x44 0x00 0x00
3491
// 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
3492
// 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3493
// 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3494
// 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3495
// 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3496
// 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3497
3498
// The rest coding is ZX specific - don't use consecutive address nops
3499
3500
// 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3501
// 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3502
// 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3503
// 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3504
3505
while (i >= 15) {
3506
// For ZX don't generate consecutive addess nops (mix with regular nops)
3507
i -= 15;
3508
emit_int24(0x66, 0x66, 0x66);
3509
addr_nop_8();
3510
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3511
}
3512
switch (i) {
3513
case 14:
3514
emit_int8(0x66); // size prefix
3515
case 13:
3516
emit_int8(0x66); // size prefix
3517
case 12:
3518
addr_nop_8();
3519
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3520
break;
3521
case 11:
3522
emit_int8(0x66); // size prefix
3523
case 10:
3524
emit_int8(0x66); // size prefix
3525
case 9:
3526
emit_int8(0x66); // size prefix
3527
case 8:
3528
addr_nop_8();
3529
break;
3530
case 7:
3531
addr_nop_7();
3532
break;
3533
case 6:
3534
emit_int8(0x66); // size prefix
3535
case 5:
3536
addr_nop_5();
3537
break;
3538
case 4:
3539
addr_nop_4();
3540
break;
3541
case 3:
3542
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
3543
emit_int8(0x66); // size prefix
3544
case 2:
3545
emit_int8(0x66); // size prefix
3546
case 1:
3547
emit_int8((unsigned char)0x90);
3548
// nop
3549
break;
3550
default:
3551
assert(i == 0, " ");
3552
}
3553
return;
3554
}
3555
3556
// Using nops with size prefixes "0x66 0x90".
3557
// From AMD Optimization Guide:
3558
// 1: 0x90
3559
// 2: 0x66 0x90
3560
// 3: 0x66 0x66 0x90
3561
// 4: 0x66 0x66 0x66 0x90
3562
// 5: 0x66 0x66 0x90 0x66 0x90
3563
// 6: 0x66 0x66 0x90 0x66 0x66 0x90
3564
// 7: 0x66 0x66 0x66 0x90 0x66 0x66 0x90
3565
// 8: 0x66 0x66 0x66 0x90 0x66 0x66 0x66 0x90
3566
// 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
3567
// 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
3568
//
3569
while (i > 12) {
3570
i -= 4;
3571
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3572
}
3573
// 1 - 12 nops
3574
if (i > 8) {
3575
if (i > 9) {
3576
i -= 1;
3577
emit_int8(0x66);
3578
}
3579
i -= 3;
3580
emit_int24(0x66, 0x66, (unsigned char)0x90);
3581
}
3582
// 1 - 8 nops
3583
if (i > 4) {
3584
if (i > 6) {
3585
i -= 1;
3586
emit_int8(0x66);
3587
}
3588
i -= 3;
3589
emit_int24(0x66, 0x66, (unsigned char)0x90);
3590
}
3591
switch (i) {
3592
case 4:
3593
emit_int8(0x66);
3594
case 3:
3595
emit_int8(0x66);
3596
case 2:
3597
emit_int8(0x66);
3598
case 1:
3599
emit_int8((unsigned char)0x90);
3600
break;
3601
default:
3602
assert(i == 0, " ");
3603
}
3604
}
3605
3606
void Assembler::notl(Register dst) {
3607
int encode = prefix_and_encode(dst->encoding());
3608
emit_int16((unsigned char)0xF7, (0xD0 | encode));
3609
}
3610
3611
void Assembler::orw(Register dst, Register src) {
3612
(void)prefix_and_encode(dst->encoding(), src->encoding());
3613
emit_arith(0x0B, 0xC0, dst, src);
3614
}
3615
3616
void Assembler::orl(Address dst, int32_t imm32) {
3617
InstructionMark im(this);
3618
prefix(dst);
3619
emit_arith_operand(0x81, rcx, dst, imm32);
3620
}
3621
3622
void Assembler::orl(Register dst, int32_t imm32) {
3623
prefix(dst);
3624
emit_arith(0x81, 0xC8, dst, imm32);
3625
}
3626
3627
void Assembler::orl(Register dst, Address src) {
3628
InstructionMark im(this);
3629
prefix(src, dst);
3630
emit_int8(0x0B);
3631
emit_operand(dst, src);
3632
}
3633
3634
void Assembler::orl(Register dst, Register src) {
3635
(void) prefix_and_encode(dst->encoding(), src->encoding());
3636
emit_arith(0x0B, 0xC0, dst, src);
3637
}
3638
3639
void Assembler::orl(Address dst, Register src) {
3640
InstructionMark im(this);
3641
prefix(dst, src);
3642
emit_int8(0x09);
3643
emit_operand(src, dst);
3644
}
3645
3646
void Assembler::orb(Address dst, int imm8) {
3647
InstructionMark im(this);
3648
prefix(dst);
3649
emit_int8((unsigned char)0x80);
3650
emit_operand(rcx, dst, 1);
3651
emit_int8(imm8);
3652
}
3653
3654
void Assembler::orb(Address dst, Register src) {
3655
InstructionMark im(this);
3656
prefix(dst, src, true);
3657
emit_int8(0x08);
3658
emit_operand(src, dst);
3659
}
3660
3661
void Assembler::packsswb(XMMRegister dst, XMMRegister src) {
3662
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3663
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3664
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3665
emit_int16(0x63, (0xC0 | encode));
3666
}
3667
3668
void Assembler::vpacksswb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3669
assert(UseAVX > 0, "some form of AVX must be enabled");
3670
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3671
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3672
emit_int16(0x63, (0xC0 | encode));
3673
}
3674
3675
void Assembler::packssdw(XMMRegister dst, XMMRegister src) {
3676
assert(VM_Version::supports_sse2(), "");
3677
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3678
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3679
emit_int16(0x6B, (0xC0 | encode));
3680
}
3681
3682
void Assembler::vpackssdw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3683
assert(UseAVX > 0, "some form of AVX must be enabled");
3684
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3685
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3686
emit_int16(0x6B, (0xC0 | encode));
3687
}
3688
3689
void Assembler::packuswb(XMMRegister dst, Address src) {
3690
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3691
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
3692
InstructionMark im(this);
3693
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3694
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
3695
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3696
emit_int8(0x67);
3697
emit_operand(dst, src);
3698
}
3699
3700
void Assembler::packuswb(XMMRegister dst, XMMRegister src) {
3701
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3702
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3703
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3704
emit_int16(0x67, (0xC0 | encode));
3705
}
3706
3707
void Assembler::vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3708
assert(UseAVX > 0, "some form of AVX must be enabled");
3709
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3710
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3711
emit_int16(0x67, (0xC0 | encode));
3712
}
3713
3714
void Assembler::packusdw(XMMRegister dst, XMMRegister src) {
3715
assert(VM_Version::supports_sse4_1(), "");
3716
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3717
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3718
emit_int16(0x2B, (0xC0 | encode));
3719
}
3720
3721
void Assembler::vpackusdw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3722
assert(UseAVX > 0, "some form of AVX must be enabled");
3723
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3724
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3725
emit_int16(0x2B, (0xC0 | encode));
3726
}
3727
3728
void Assembler::vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3729
assert(VM_Version::supports_avx2(), "");
3730
assert(vector_len != AVX_128bit, "");
3731
// VEX.256.66.0F3A.W1 00 /r ib
3732
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3733
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3734
emit_int24(0x00, (0xC0 | encode), imm8);
3735
}
3736
3737
void Assembler::vpermq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3738
assert(vector_len == AVX_256bit ? VM_Version::supports_avx512vl() :
3739
vector_len == AVX_512bit ? VM_Version::supports_evex() : false, "not supported");
3740
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3741
attributes.set_is_evex_instruction();
3742
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3743
emit_int16(0x36, (0xC0 | encode));
3744
}
3745
3746
void Assembler::vpermb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3747
assert(VM_Version::supports_avx512_vbmi(), "");
3748
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3749
attributes.set_is_evex_instruction();
3750
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3751
emit_int16((unsigned char)0x8D, (0xC0 | encode));
3752
}
3753
3754
void Assembler::vpermw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3755
assert(vector_len == AVX_128bit ? VM_Version::supports_avx512vlbw() :
3756
vector_len == AVX_256bit ? VM_Version::supports_avx512vlbw() :
3757
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : false, "not supported");
3758
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3759
attributes.set_is_evex_instruction();
3760
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3761
emit_int16((unsigned char)0x8D, (0xC0 | encode));
3762
}
3763
3764
void Assembler::vpermd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3765
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex(), "");
3766
// VEX.NDS.256.66.0F38.W0 36 /r
3767
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3768
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3769
emit_int16(0x36, (0xC0 | encode));
3770
}
3771
3772
void Assembler::vpermd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
3773
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex(), "");
3774
// VEX.NDS.256.66.0F38.W0 36 /r
3775
InstructionMark im(this);
3776
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3777
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3778
emit_int8(0x36);
3779
emit_operand(dst, src);
3780
}
3781
3782
void Assembler::vperm2i128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
3783
assert(VM_Version::supports_avx2(), "");
3784
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3785
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3786
emit_int24(0x46, (0xC0 | encode), imm8);
3787
}
3788
3789
void Assembler::vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
3790
assert(VM_Version::supports_avx(), "");
3791
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3792
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3793
emit_int24(0x06, (0xC0 | encode), imm8);
3794
}
3795
3796
void Assembler::vpermilps(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3797
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
3798
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3799
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3800
emit_int24(0x04, (0xC0 | encode), imm8);
3801
}
3802
3803
void Assembler::vpermilpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3804
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
3805
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(),/* legacy_mode */ false,/* no_mask_reg */ true, /* uses_vl */ false);
3806
attributes.set_rex_vex_w_reverted();
3807
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3808
emit_int24(0x05, (0xC0 | encode), imm8);
3809
}
3810
3811
void Assembler::vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3812
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex(), "");
3813
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */false, /* no_mask_reg */ true, /* uses_vl */ false);
3814
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3815
emit_int24(0x01, (0xC0 | encode), imm8);
3816
}
3817
3818
void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3819
assert(VM_Version::supports_evex(), "");
3820
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3821
attributes.set_is_evex_instruction();
3822
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3823
emit_int16(0x76, (0xC0 | encode));
3824
}
3825
3826
void Assembler::pause() {
3827
emit_int16((unsigned char)0xF3, (unsigned char)0x90);
3828
}
3829
3830
void Assembler::ud2() {
3831
emit_int16(0x0F, 0x0B);
3832
}
3833
3834
void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
3835
assert(VM_Version::supports_sse4_2(), "");
3836
InstructionMark im(this);
3837
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3838
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3839
emit_int8(0x61);
3840
emit_operand(dst, src);
3841
emit_int8(imm8);
3842
}
3843
3844
void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
3845
assert(VM_Version::supports_sse4_2(), "");
3846
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3847
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3848
emit_int24(0x61, (0xC0 | encode), imm8);
3849
}
3850
3851
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3852
void Assembler::pcmpeqb(XMMRegister dst, XMMRegister src) {
3853
assert(VM_Version::supports_sse2(), "");
3854
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3855
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3856
emit_int16(0x74, (0xC0 | encode));
3857
}
3858
3859
void Assembler::vpcmpCCbwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cond_encoding, int vector_len) {
3860
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
3861
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
3862
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3863
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3864
emit_int16(cond_encoding, (0xC0 | encode));
3865
}
3866
3867
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3868
void Assembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3869
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
3870
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
3871
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3872
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3873
emit_int16(0x74, (0xC0 | encode));
3874
}
3875
3876
// In this context, kdst is written the mask used to process the equal components
3877
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
3878
assert(VM_Version::supports_avx512bw(), "");
3879
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3880
attributes.set_is_evex_instruction();
3881
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3882
emit_int16(0x74, (0xC0 | encode));
3883
}
3884
3885
void Assembler::evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
3886
assert(VM_Version::supports_avx512vlbw(), "");
3887
InstructionMark im(this);
3888
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3889
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3890
attributes.set_is_evex_instruction();
3891
int dst_enc = kdst->encoding();
3892
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3893
emit_int8(0x64);
3894
emit_operand(as_Register(dst_enc), src);
3895
}
3896
3897
void Assembler::evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
3898
assert(VM_Version::supports_avx512vlbw(), "");
3899
InstructionMark im(this);
3900
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
3901
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3902
attributes.reset_is_clear_context();
3903
attributes.set_embedded_opmask_register_specifier(mask);
3904
attributes.set_is_evex_instruction();
3905
int dst_enc = kdst->encoding();
3906
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3907
emit_int8(0x64);
3908
emit_operand(as_Register(dst_enc), src);
3909
}
3910
3911
void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
3912
assert(VM_Version::supports_avx512vlbw(), "");
3913
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3914
attributes.set_is_evex_instruction();
3915
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3916
emit_int24(0x3E, (0xC0 | encode), vcc);
3917
}
3918
3919
void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len) {
3920
assert(VM_Version::supports_avx512vlbw(), "");
3921
InstructionMark im(this);
3922
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3923
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3924
attributes.set_is_evex_instruction();
3925
int dst_enc = kdst->encoding();
3926
vex_prefix(src, nds->encoding(), kdst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3927
emit_int8(0x3E);
3928
emit_operand(as_Register(dst_enc), src);
3929
emit_int8(vcc);
3930
}
3931
3932
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
3933
assert(VM_Version::supports_avx512bw(), "");
3934
InstructionMark im(this);
3935
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3936
attributes.set_is_evex_instruction();
3937
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3938
int dst_enc = kdst->encoding();
3939
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3940
emit_int8(0x74);
3941
emit_operand(as_Register(dst_enc), src);
3942
}
3943
3944
void Assembler::evpcmpeqb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
3945
assert(VM_Version::supports_avx512vlbw(), "");
3946
InstructionMark im(this);
3947
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
3948
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3949
attributes.reset_is_clear_context();
3950
attributes.set_embedded_opmask_register_specifier(mask);
3951
attributes.set_is_evex_instruction();
3952
vex_prefix(src, nds->encoding(), kdst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3953
emit_int8(0x74);
3954
emit_operand(as_Register(kdst->encoding()), src);
3955
}
3956
3957
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3958
void Assembler::pcmpeqw(XMMRegister dst, XMMRegister src) {
3959
assert(VM_Version::supports_sse2(), "");
3960
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3961
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3962
emit_int16(0x75, (0xC0 | encode));
3963
}
3964
3965
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3966
void Assembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3967
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
3968
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
3969
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3970
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3971
emit_int16(0x75, (0xC0 | encode));
3972
}
3973
3974
// In this context, kdst is written the mask used to process the equal components
3975
void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
3976
assert(VM_Version::supports_avx512bw(), "");
3977
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3978
attributes.set_is_evex_instruction();
3979
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3980
emit_int16(0x75, (0xC0 | encode));
3981
}
3982
3983
void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
3984
assert(VM_Version::supports_avx512bw(), "");
3985
InstructionMark im(this);
3986
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3987
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3988
attributes.set_is_evex_instruction();
3989
int dst_enc = kdst->encoding();
3990
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3991
emit_int8(0x75);
3992
emit_operand(as_Register(dst_enc), src);
3993
}
3994
3995
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3996
void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
3997
assert(VM_Version::supports_sse2(), "");
3998
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3999
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4000
emit_int16(0x76, (0xC0 | encode));
4001
}
4002
4003
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4004
void Assembler::vpcmpeqd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4005
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
4006
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
4007
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4008
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4009
emit_int16(0x76, (0xC0 | encode));
4010
}
4011
4012
// In this context, kdst is written the mask used to process the equal components
4013
void Assembler::evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, int vector_len) {
4014
assert(VM_Version::supports_evex(), "");
4015
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4016
attributes.set_is_evex_instruction();
4017
attributes.reset_is_clear_context();
4018
attributes.set_embedded_opmask_register_specifier(mask);
4019
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4020
emit_int16(0x76, (0xC0 | encode));
4021
}
4022
4023
void Assembler::evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
4024
assert(VM_Version::supports_evex(), "");
4025
InstructionMark im(this);
4026
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4027
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
4028
attributes.set_is_evex_instruction();
4029
attributes.reset_is_clear_context();
4030
attributes.set_embedded_opmask_register_specifier(mask);
4031
int dst_enc = kdst->encoding();
4032
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4033
emit_int8(0x76);
4034
emit_operand(as_Register(dst_enc), src);
4035
}
4036
4037
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4038
void Assembler::pcmpeqq(XMMRegister dst, XMMRegister src) {
4039
assert(VM_Version::supports_sse4_1(), "");
4040
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4041
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4042
emit_int16(0x29, (0xC0 | encode));
4043
}
4044
4045
void Assembler::vpcmpCCq(XMMRegister dst, XMMRegister nds, XMMRegister src, int cond_encoding, int vector_len) {
4046
assert(VM_Version::supports_avx(), "");
4047
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4048
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4049
emit_int16(cond_encoding, (0xC0 | encode));
4050
}
4051
4052
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4053
void Assembler::vpcmpeqq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4054
assert(VM_Version::supports_avx(), "");
4055
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4056
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4057
emit_int16(0x29, (0xC0 | encode));
4058
}
4059
4060
// In this context, kdst is written the mask used to process the equal components
4061
void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
4062
assert(VM_Version::supports_evex(), "");
4063
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4064
attributes.reset_is_clear_context();
4065
attributes.set_is_evex_instruction();
4066
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4067
emit_int16(0x29, (0xC0 | encode));
4068
}
4069
4070
// In this context, kdst is written the mask used to process the equal components
4071
void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
4072
assert(VM_Version::supports_evex(), "");
4073
InstructionMark im(this);
4074
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4075
attributes.reset_is_clear_context();
4076
attributes.set_is_evex_instruction();
4077
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
4078
int dst_enc = kdst->encoding();
4079
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4080
emit_int8(0x29);
4081
emit_operand(as_Register(dst_enc), src);
4082
}
4083
4084
void Assembler::evpmovd2m(KRegister kdst, XMMRegister src, int vector_len) {
4085
assert(UseAVX > 2 && VM_Version::supports_avx512dq(), "");
4086
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
4087
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4088
attributes.set_is_evex_instruction();
4089
int encode = vex_prefix_and_encode(kdst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4090
emit_int16(0x39, (0xC0 | encode));
4091
}
4092
4093
void Assembler::evpmovq2m(KRegister kdst, XMMRegister src, int vector_len) {
4094
assert(UseAVX > 2 && VM_Version::supports_avx512dq(), "");
4095
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
4096
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4097
attributes.set_is_evex_instruction();
4098
int encode = vex_prefix_and_encode(kdst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4099
emit_int16(0x39, (0xC0 | encode));
4100
}
4101
4102
void Assembler::pcmpgtq(XMMRegister dst, XMMRegister src) {
4103
assert(VM_Version::supports_sse4_1(), "");
4104
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4105
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4106
emit_int16(0x37, (0xC0 | encode));
4107
}
4108
4109
void Assembler::pmovmskb(Register dst, XMMRegister src) {
4110
assert(VM_Version::supports_sse2(), "");
4111
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4112
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4113
emit_int16((unsigned char)0xD7, (0xC0 | encode));
4114
}
4115
4116
void Assembler::vpmovmskb(Register dst, XMMRegister src, int vec_enc) {
4117
assert((VM_Version::supports_avx() && vec_enc == AVX_128bit) ||
4118
(VM_Version::supports_avx2() && vec_enc == AVX_256bit), "");
4119
InstructionAttr attributes(vec_enc, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4120
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4121
emit_int16((unsigned char)0xD7, (0xC0 | encode));
4122
}
4123
4124
void Assembler::pextrd(Register dst, XMMRegister src, int imm8) {
4125
assert(VM_Version::supports_sse4_1(), "");
4126
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4127
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4128
emit_int24(0x16, (0xC0 | encode), imm8);
4129
}
4130
4131
void Assembler::pextrd(Address dst, XMMRegister src, int imm8) {
4132
assert(VM_Version::supports_sse4_1(), "");
4133
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4134
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
4135
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4136
emit_int8(0x16);
4137
emit_operand(src, dst);
4138
emit_int8(imm8);
4139
}
4140
4141
void Assembler::pextrq(Register dst, XMMRegister src, int imm8) {
4142
assert(VM_Version::supports_sse4_1(), "");
4143
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4144
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4145
emit_int24(0x16, (0xC0 | encode), imm8);
4146
}
4147
4148
void Assembler::pextrq(Address dst, XMMRegister src, int imm8) {
4149
assert(VM_Version::supports_sse4_1(), "");
4150
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4151
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
4152
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4153
emit_int8(0x16);
4154
emit_operand(src, dst);
4155
emit_int8(imm8);
4156
}
4157
4158
void Assembler::pextrw(Register dst, XMMRegister src, int imm8) {
4159
assert(VM_Version::supports_sse2(), "");
4160
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4161
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4162
emit_int24((unsigned char)0xC5, (0xC0 | encode), imm8);
4163
}
4164
4165
void Assembler::pextrw(Address dst, XMMRegister src, int imm8) {
4166
assert(VM_Version::supports_sse4_1(), "");
4167
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4168
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_16bit);
4169
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4170
emit_int8(0x15);
4171
emit_operand(src, dst);
4172
emit_int8(imm8);
4173
}
4174
4175
void Assembler::pextrb(Register dst, XMMRegister src, int imm8) {
4176
assert(VM_Version::supports_sse4_1(), "");
4177
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4178
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4179
emit_int24(0x14, (0xC0 | encode), imm8);
4180
}
4181
4182
void Assembler::pextrb(Address dst, XMMRegister src, int imm8) {
4183
assert(VM_Version::supports_sse4_1(), "");
4184
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4185
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_8bit);
4186
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4187
emit_int8(0x14);
4188
emit_operand(src, dst);
4189
emit_int8(imm8);
4190
}
4191
4192
void Assembler::pinsrd(XMMRegister dst, Register src, int imm8) {
4193
assert(VM_Version::supports_sse4_1(), "");
4194
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4195
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4196
emit_int24(0x22, (0xC0 | encode), imm8);
4197
}
4198
4199
void Assembler::pinsrd(XMMRegister dst, Address src, int imm8) {
4200
assert(VM_Version::supports_sse4_1(), "");
4201
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4202
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
4203
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4204
emit_int8(0x22);
4205
emit_operand(dst,src);
4206
emit_int8(imm8);
4207
}
4208
4209
void Assembler::vpinsrd(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4210
assert(VM_Version::supports_avx(), "");
4211
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4212
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4213
emit_int24(0x22, (0xC0 | encode), imm8);
4214
}
4215
4216
void Assembler::pinsrq(XMMRegister dst, Register src, int imm8) {
4217
assert(VM_Version::supports_sse4_1(), "");
4218
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4219
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4220
emit_int24(0x22, (0xC0 | encode), imm8);
4221
}
4222
4223
void Assembler::pinsrq(XMMRegister dst, Address src, int imm8) {
4224
assert(VM_Version::supports_sse4_1(), "");
4225
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4226
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
4227
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4228
emit_int8(0x22);
4229
emit_operand(dst, src);
4230
emit_int8(imm8);
4231
}
4232
4233
void Assembler::vpinsrq(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4234
assert(VM_Version::supports_avx(), "");
4235
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4236
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4237
emit_int24(0x22, (0xC0 | encode), imm8);
4238
}
4239
4240
void Assembler::pinsrw(XMMRegister dst, Register src, int imm8) {
4241
assert(VM_Version::supports_sse2(), "");
4242
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4243
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4244
emit_int24((unsigned char)0xC4, (0xC0 | encode), imm8);
4245
}
4246
4247
void Assembler::pinsrw(XMMRegister dst, Address src, int imm8) {
4248
assert(VM_Version::supports_sse2(), "");
4249
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4250
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_16bit);
4251
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4252
emit_int8((unsigned char)0xC4);
4253
emit_operand(dst, src);
4254
emit_int8(imm8);
4255
}
4256
4257
void Assembler::vpinsrw(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4258
assert(VM_Version::supports_avx(), "");
4259
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4260
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4261
emit_int24((unsigned char)0xC4, (0xC0 | encode), imm8);
4262
}
4263
4264
void Assembler::pinsrb(XMMRegister dst, Address src, int imm8) {
4265
assert(VM_Version::supports_sse4_1(), "");
4266
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4267
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_8bit);
4268
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4269
emit_int8(0x20);
4270
emit_operand(dst, src);
4271
emit_int8(imm8);
4272
}
4273
4274
void Assembler::pinsrb(XMMRegister dst, Register src, int imm8) {
4275
assert(VM_Version::supports_sse4_1(), "");
4276
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4277
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4278
emit_int24(0x20, (0xC0 | encode), imm8);
4279
}
4280
4281
void Assembler::vpinsrb(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4282
assert(VM_Version::supports_avx(), "");
4283
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4284
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4285
emit_int24(0x20, (0xC0 | encode), imm8);
4286
}
4287
4288
void Assembler::insertps(XMMRegister dst, XMMRegister src, int imm8) {
4289
assert(VM_Version::supports_sse4_1(), "");
4290
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
4291
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4292
emit_int24(0x21, (0xC0 | encode), imm8);
4293
}
4294
4295
void Assembler::vinsertps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
4296
assert(VM_Version::supports_avx(), "");
4297
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
4298
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4299
emit_int24(0x21, (0xC0 | encode), imm8);
4300
}
4301
4302
void Assembler::pmovzxbw(XMMRegister dst, Address src) {
4303
assert(VM_Version::supports_sse4_1(), "");
4304
InstructionMark im(this);
4305
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4306
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4307
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4308
emit_int8(0x30);
4309
emit_operand(dst, src);
4310
}
4311
4312
void Assembler::pmovzxbw(XMMRegister dst, XMMRegister src) {
4313
assert(VM_Version::supports_sse4_1(), "");
4314
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4315
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4316
emit_int16(0x30, (0xC0 | encode));
4317
}
4318
4319
void Assembler::pmovsxbw(XMMRegister dst, XMMRegister src) {
4320
assert(VM_Version::supports_sse4_1(), "");
4321
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4322
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4323
emit_int16(0x20, (0xC0 | encode));
4324
}
4325
4326
void Assembler::pmovzxdq(XMMRegister dst, XMMRegister src) {
4327
assert(VM_Version::supports_sse4_1(), "");
4328
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4329
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4330
emit_int16(0x35, (0xC0 | encode));
4331
}
4332
4333
void Assembler::pmovsxbd(XMMRegister dst, XMMRegister src) {
4334
assert(VM_Version::supports_sse4_1(), "");
4335
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4336
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4337
emit_int16(0x21, (0xC0 | encode));
4338
}
4339
4340
void Assembler::pmovzxbd(XMMRegister dst, XMMRegister src) {
4341
assert(VM_Version::supports_sse4_1(), "");
4342
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4343
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4344
emit_int16(0x31, (0xC0 | encode));
4345
}
4346
4347
void Assembler::pmovsxbq(XMMRegister dst, XMMRegister src) {
4348
assert(VM_Version::supports_sse4_1(), "");
4349
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4350
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4351
emit_int16(0x22, (0xC0 | encode));
4352
}
4353
4354
void Assembler::pmovsxwd(XMMRegister dst, XMMRegister src) {
4355
assert(VM_Version::supports_sse4_1(), "");
4356
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4357
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4358
emit_int16(0x23, (0xC0 | encode));
4359
}
4360
4361
void Assembler::vpmovzxbw(XMMRegister dst, Address src, int vector_len) {
4362
assert(VM_Version::supports_avx(), "");
4363
InstructionMark im(this);
4364
assert(dst != xnoreg, "sanity");
4365
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4366
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4367
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4368
emit_int8(0x30);
4369
emit_operand(dst, src);
4370
}
4371
4372
void Assembler::vpmovzxbw(XMMRegister dst, XMMRegister src, int vector_len) {
4373
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4374
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4375
vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
4376
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4377
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4378
emit_int16(0x30, (unsigned char) (0xC0 | encode));
4379
}
4380
4381
void Assembler::vpmovsxbw(XMMRegister dst, XMMRegister src, int vector_len) {
4382
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4383
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4384
vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
4385
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4386
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4387
emit_int16(0x20, (0xC0 | encode));
4388
}
4389
4390
void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len) {
4391
assert(VM_Version::supports_avx512vlbw(), "");
4392
assert(dst != xnoreg, "sanity");
4393
InstructionMark im(this);
4394
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
4395
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4396
attributes.set_embedded_opmask_register_specifier(mask);
4397
attributes.set_is_evex_instruction();
4398
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4399
emit_int8(0x30);
4400
emit_operand(dst, src);
4401
}
4402
4403
void Assembler::evpandd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
4404
assert(VM_Version::supports_evex(), "");
4405
// Encoding: EVEX.NDS.XXX.66.0F.W0 DB /r
4406
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4407
attributes.set_is_evex_instruction();
4408
attributes.set_embedded_opmask_register_specifier(mask);
4409
if (merge) {
4410
attributes.reset_is_clear_context();
4411
}
4412
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4413
emit_int16((unsigned char)0xDB, (0xC0 | encode));
4414
}
4415
4416
void Assembler::vpmovzxdq(XMMRegister dst, XMMRegister src, int vector_len) {
4417
assert(vector_len > AVX_128bit ? VM_Version::supports_avx2() : VM_Version::supports_avx(), "");
4418
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4419
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4420
emit_int16(0x35, (0xC0 | encode));
4421
}
4422
4423
void Assembler::vpmovzxbd(XMMRegister dst, XMMRegister src, int vector_len) {
4424
assert(vector_len > AVX_128bit ? VM_Version::supports_avx2() : VM_Version::supports_avx(), "");
4425
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4426
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4427
emit_int16(0x31, (0xC0 | encode));
4428
}
4429
4430
void Assembler::vpmovzxbq(XMMRegister dst, XMMRegister src, int vector_len) {
4431
assert(vector_len > AVX_128bit ? VM_Version::supports_avx2() : VM_Version::supports_avx(), "");
4432
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4433
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4434
emit_int16(0x32, (0xC0 | encode));
4435
}
4436
4437
void Assembler::vpmovsxbd(XMMRegister dst, XMMRegister src, int vector_len) {
4438
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4439
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4440
VM_Version::supports_evex(), "");
4441
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4442
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4443
emit_int16(0x21, (0xC0 | encode));
4444
}
4445
4446
void Assembler::vpmovsxbq(XMMRegister dst, XMMRegister src, int vector_len) {
4447
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4448
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4449
VM_Version::supports_evex(), "");
4450
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4451
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4452
emit_int16(0x22, (0xC0 | encode));
4453
}
4454
4455
void Assembler::vpmovsxwd(XMMRegister dst, XMMRegister src, int vector_len) {
4456
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4457
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4458
VM_Version::supports_evex(), "");
4459
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4460
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4461
emit_int16(0x23, (0xC0 | encode));
4462
}
4463
4464
void Assembler::vpmovsxwq(XMMRegister dst, XMMRegister src, int vector_len) {
4465
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4466
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4467
VM_Version::supports_evex(), "");
4468
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4469
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4470
emit_int16(0x24, (0xC0 | encode));
4471
}
4472
4473
void Assembler::vpmovsxdq(XMMRegister dst, XMMRegister src, int vector_len) {
4474
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4475
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4476
VM_Version::supports_evex(), "");
4477
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4478
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4479
emit_int16(0x25, (0xC0 | encode));
4480
}
4481
4482
void Assembler::evpmovwb(Address dst, XMMRegister src, int vector_len) {
4483
assert(VM_Version::supports_avx512vlbw(), "");
4484
assert(src != xnoreg, "sanity");
4485
InstructionMark im(this);
4486
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4487
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4488
attributes.set_is_evex_instruction();
4489
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4490
emit_int8(0x30);
4491
emit_operand(src, dst);
4492
}
4493
4494
void Assembler::evpmovwb(Address dst, KRegister mask, XMMRegister src, int vector_len) {
4495
assert(VM_Version::supports_avx512vlbw(), "");
4496
assert(src != xnoreg, "sanity");
4497
InstructionMark im(this);
4498
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4499
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4500
attributes.reset_is_clear_context();
4501
attributes.set_embedded_opmask_register_specifier(mask);
4502
attributes.set_is_evex_instruction();
4503
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4504
emit_int8(0x30);
4505
emit_operand(src, dst);
4506
}
4507
4508
void Assembler::evpmovdb(Address dst, XMMRegister src, int vector_len) {
4509
assert(VM_Version::supports_evex(), "");
4510
assert(src != xnoreg, "sanity");
4511
InstructionMark im(this);
4512
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4513
attributes.set_address_attributes(/* tuple_type */ EVEX_QVM, /* input_size_in_bits */ EVEX_NObit);
4514
attributes.set_is_evex_instruction();
4515
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4516
emit_int8(0x31);
4517
emit_operand(src, dst);
4518
}
4519
4520
void Assembler::vpmovzxwd(XMMRegister dst, XMMRegister src, int vector_len) {
4521
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4522
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4523
vector_len == AVX_512bit? VM_Version::supports_evex() : 0, " ");
4524
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4525
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4526
emit_int16(0x33, (0xC0 | encode));
4527
}
4528
4529
void Assembler::pmaddwd(XMMRegister dst, XMMRegister src) {
4530
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4531
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4532
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4533
emit_int16((unsigned char)0xF5, (0xC0 | encode));
4534
}
4535
4536
void Assembler::vpmaddwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4537
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4538
(vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4539
(vector_len == AVX_512bit ? VM_Version::supports_evex() : 0)), "");
4540
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4541
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4542
emit_int16((unsigned char)0xF5, (0xC0 | encode));
4543
}
4544
4545
void Assembler::evpdpwssd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4546
assert(VM_Version::supports_evex(), "");
4547
assert(VM_Version::supports_avx512_vnni(), "must support vnni");
4548
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4549
attributes.set_is_evex_instruction();
4550
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4551
emit_int16(0x52, (0xC0 | encode));
4552
}
4553
4554
// generic
4555
void Assembler::pop(Register dst) {
4556
int encode = prefix_and_encode(dst->encoding());
4557
emit_int8(0x58 | encode);
4558
}
4559
4560
void Assembler::popcntl(Register dst, Address src) {
4561
assert(VM_Version::supports_popcnt(), "must support");
4562
InstructionMark im(this);
4563
emit_int8((unsigned char)0xF3);
4564
prefix(src, dst);
4565
emit_int16(0x0F, (unsigned char)0xB8);
4566
emit_operand(dst, src);
4567
}
4568
4569
void Assembler::popcntl(Register dst, Register src) {
4570
assert(VM_Version::supports_popcnt(), "must support");
4571
emit_int8((unsigned char)0xF3);
4572
int encode = prefix_and_encode(dst->encoding(), src->encoding());
4573
emit_int24(0x0F, (unsigned char)0xB8, (0xC0 | encode));
4574
}
4575
4576
void Assembler::vpopcntd(XMMRegister dst, XMMRegister src, int vector_len) {
4577
assert(VM_Version::supports_avx512_vpopcntdq(), "must support vpopcntdq feature");
4578
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4579
attributes.set_is_evex_instruction();
4580
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4581
emit_int16(0x55, (0xC0 | encode));
4582
}
4583
4584
void Assembler::popf() {
4585
emit_int8((unsigned char)0x9D);
4586
}
4587
4588
#ifndef _LP64 // no 32bit push/pop on amd64
4589
void Assembler::popl(Address dst) {
4590
// NOTE: this will adjust stack by 8byte on 64bits
4591
InstructionMark im(this);
4592
prefix(dst);
4593
emit_int8((unsigned char)0x8F);
4594
emit_operand(rax, dst);
4595
}
4596
#endif
4597
4598
void Assembler::prefetchnta(Address src) {
4599
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4600
InstructionMark im(this);
4601
prefix(src);
4602
emit_int16(0x0F, 0x18);
4603
emit_operand(rax, src); // 0, src
4604
}
4605
4606
void Assembler::prefetchr(Address src) {
4607
assert(VM_Version::supports_3dnow_prefetch(), "must support");
4608
InstructionMark im(this);
4609
prefix(src);
4610
emit_int16(0x0F, 0x0D);
4611
emit_operand(rax, src); // 0, src
4612
}
4613
4614
void Assembler::prefetcht0(Address src) {
4615
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4616
InstructionMark im(this);
4617
prefix(src);
4618
emit_int16(0x0F, 0x18);
4619
emit_operand(rcx, src); // 1, src
4620
}
4621
4622
void Assembler::prefetcht1(Address src) {
4623
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4624
InstructionMark im(this);
4625
prefix(src);
4626
emit_int16(0x0F, 0x18);
4627
emit_operand(rdx, src); // 2, src
4628
}
4629
4630
void Assembler::prefetcht2(Address src) {
4631
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4632
InstructionMark im(this);
4633
prefix(src);
4634
emit_int16(0x0F, 0x18);
4635
emit_operand(rbx, src); // 3, src
4636
}
4637
4638
void Assembler::prefetchw(Address src) {
4639
assert(VM_Version::supports_3dnow_prefetch(), "must support");
4640
InstructionMark im(this);
4641
prefix(src);
4642
emit_int16(0x0F, 0x0D);
4643
emit_operand(rcx, src); // 1, src
4644
}
4645
4646
void Assembler::prefix(Prefix p) {
4647
emit_int8(p);
4648
}
4649
4650
void Assembler::pshufb(XMMRegister dst, XMMRegister src) {
4651
assert(VM_Version::supports_ssse3(), "");
4652
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4653
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4654
emit_int16(0x00, (0xC0 | encode));
4655
}
4656
4657
void Assembler::vpshufb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4658
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4659
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4660
vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
4661
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4662
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4663
emit_int16(0x00, (0xC0 | encode));
4664
}
4665
4666
void Assembler::pshufb(XMMRegister dst, Address src) {
4667
assert(VM_Version::supports_ssse3(), "");
4668
InstructionMark im(this);
4669
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4670
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
4671
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4672
emit_int8(0x00);
4673
emit_operand(dst, src);
4674
}
4675
4676
void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) {
4677
assert(isByte(mode), "invalid value");
4678
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4679
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
4680
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4681
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4682
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4683
}
4684
4685
void Assembler::vpshufd(XMMRegister dst, XMMRegister src, int mode, int vector_len) {
4686
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4687
(vector_len == AVX_256bit? VM_Version::supports_avx2() :
4688
(vector_len == AVX_512bit? VM_Version::supports_evex() : 0)), "");
4689
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4690
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4691
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4692
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4693
}
4694
4695
void Assembler::pshufd(XMMRegister dst, Address src, int mode) {
4696
assert(isByte(mode), "invalid value");
4697
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4698
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4699
InstructionMark im(this);
4700
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4701
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
4702
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4703
emit_int8(0x70);
4704
emit_operand(dst, src);
4705
emit_int8(mode & 0xFF);
4706
}
4707
4708
void Assembler::pshufhw(XMMRegister dst, XMMRegister src, int mode) {
4709
assert(isByte(mode), "invalid value");
4710
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4711
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4712
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
4713
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4714
}
4715
4716
void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) {
4717
assert(isByte(mode), "invalid value");
4718
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4719
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4720
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
4721
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4722
}
4723
4724
void Assembler::pshuflw(XMMRegister dst, Address src, int mode) {
4725
assert(isByte(mode), "invalid value");
4726
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4727
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4728
InstructionMark im(this);
4729
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4730
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
4731
simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
4732
emit_int8(0x70);
4733
emit_operand(dst, src);
4734
emit_int8(mode & 0xFF);
4735
}
4736
4737
void Assembler::evshufi64x2(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
4738
assert(VM_Version::supports_evex(), "requires EVEX support");
4739
assert(vector_len == Assembler::AVX_256bit || vector_len == Assembler::AVX_512bit, "");
4740
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4741
attributes.set_is_evex_instruction();
4742
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4743
emit_int24(0x43, (0xC0 | encode), imm8 & 0xFF);
4744
}
4745
4746
void Assembler::pshufpd(XMMRegister dst, XMMRegister src, int imm8) {
4747
assert(isByte(imm8), "invalid value");
4748
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4749
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4750
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4751
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4752
}
4753
4754
void Assembler::vpshufpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
4755
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4756
attributes.set_rex_vex_w_reverted();
4757
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4758
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4759
}
4760
4761
void Assembler::pshufps(XMMRegister dst, XMMRegister src, int imm8) {
4762
assert(isByte(imm8), "invalid value");
4763
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4764
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4765
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
4766
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4767
}
4768
4769
void Assembler::vpshufps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
4770
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4771
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
4772
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4773
}
4774
4775
void Assembler::psrldq(XMMRegister dst, int shift) {
4776
// Shift left 128 bit value in dst XMMRegister by shift number of bytes.
4777
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4778
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4779
int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4780
emit_int24(0x73, (0xC0 | encode), shift);
4781
}
4782
4783
void Assembler::vpsrldq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
4784
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4785
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4786
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : 0, "");
4787
InstructionAttr attributes(vector_len, /*vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4788
int encode = vex_prefix_and_encode(xmm3->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4789
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
4790
}
4791
4792
void Assembler::pslldq(XMMRegister dst, int shift) {
4793
// Shift left 128 bit value in dst XMMRegister by shift number of bytes.
4794
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4795
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4796
// XMM7 is for /7 encoding: 66 0F 73 /7 ib
4797
int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4798
emit_int24(0x73, (0xC0 | encode), shift);
4799
}
4800
4801
void Assembler::vpslldq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
4802
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4803
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4804
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : 0, "");
4805
InstructionAttr attributes(vector_len, /*vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4806
int encode = vex_prefix_and_encode(xmm7->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4807
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
4808
}
4809
4810
void Assembler::ptest(XMMRegister dst, Address src) {
4811
assert(VM_Version::supports_sse4_1(), "");
4812
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4813
InstructionMark im(this);
4814
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4815
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4816
emit_int8(0x17);
4817
emit_operand(dst, src);
4818
}
4819
4820
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
4821
assert(VM_Version::supports_sse4_1() || VM_Version::supports_avx(), "");
4822
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4823
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4824
emit_int8(0x17);
4825
emit_int8((0xC0 | encode));
4826
}
4827
4828
void Assembler::vptest(XMMRegister dst, Address src) {
4829
assert(VM_Version::supports_avx(), "");
4830
InstructionMark im(this);
4831
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4832
assert(dst != xnoreg, "sanity");
4833
// swap src<->dst for encoding
4834
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4835
emit_int8(0x17);
4836
emit_operand(dst, src);
4837
}
4838
4839
void Assembler::vptest(XMMRegister dst, XMMRegister src) {
4840
assert(VM_Version::supports_avx(), "");
4841
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4842
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4843
emit_int16(0x17, (0xC0 | encode));
4844
}
4845
4846
void Assembler::vptest(XMMRegister dst, XMMRegister src, int vector_len) {
4847
assert(VM_Version::supports_avx(), "");
4848
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4849
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4850
emit_int16(0x17, (0xC0 | encode));
4851
}
4852
4853
void Assembler::punpcklbw(XMMRegister dst, Address src) {
4854
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4855
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4856
InstructionMark im(this);
4857
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_vlbw, /* no_mask_reg */ true, /* uses_vl */ true);
4858
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
4859
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4860
emit_int8(0x60);
4861
emit_operand(dst, src);
4862
}
4863
4864
void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
4865
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4866
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_vlbw, /* no_mask_reg */ true, /* uses_vl */ true);
4867
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4868
emit_int16(0x60, (0xC0 | encode));
4869
}
4870
4871
void Assembler::punpckldq(XMMRegister dst, Address src) {
4872
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4873
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4874
InstructionMark im(this);
4875
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4876
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
4877
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4878
emit_int8(0x62);
4879
emit_operand(dst, src);
4880
}
4881
4882
void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
4883
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4884
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4885
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4886
emit_int16(0x62, (0xC0 | encode));
4887
}
4888
4889
void Assembler::punpcklqdq(XMMRegister dst, XMMRegister src) {
4890
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4891
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4892
attributes.set_rex_vex_w_reverted();
4893
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4894
emit_int16(0x6C, (0xC0 | encode));
4895
}
4896
4897
void Assembler::push(int32_t imm32) {
4898
// in 64bits we push 64bits onto the stack but only
4899
// take a 32bit immediate
4900
emit_int8(0x68);
4901
emit_int32(imm32);
4902
}
4903
4904
void Assembler::push(Register src) {
4905
int encode = prefix_and_encode(src->encoding());
4906
emit_int8(0x50 | encode);
4907
}
4908
4909
void Assembler::pushf() {
4910
emit_int8((unsigned char)0x9C);
4911
}
4912
4913
#ifndef _LP64 // no 32bit push/pop on amd64
4914
void Assembler::pushl(Address src) {
4915
// Note this will push 64bit on 64bit
4916
InstructionMark im(this);
4917
prefix(src);
4918
emit_int8((unsigned char)0xFF);
4919
emit_operand(rsi, src);
4920
}
4921
#endif
4922
4923
void Assembler::rcll(Register dst, int imm8) {
4924
assert(isShiftCount(imm8), "illegal shift count");
4925
int encode = prefix_and_encode(dst->encoding());
4926
if (imm8 == 1) {
4927
emit_int16((unsigned char)0xD1, (0xD0 | encode));
4928
} else {
4929
emit_int24((unsigned char)0xC1, (0xD0 | encode), imm8);
4930
}
4931
}
4932
4933
void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
4934
NOT_LP64(assert(VM_Version::supports_sse(), ""));
4935
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4936
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
4937
emit_int16(0x53, (0xC0 | encode));
4938
}
4939
4940
void Assembler::rcpss(XMMRegister dst, XMMRegister src) {
4941
NOT_LP64(assert(VM_Version::supports_sse(), ""));
4942
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4943
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
4944
emit_int16(0x53, (0xC0 | encode));
4945
}
4946
4947
void Assembler::rdtsc() {
4948
emit_int16(0x0F, 0x31);
4949
}
4950
4951
// copies data from [esi] to [edi] using rcx pointer sized words
4952
// generic
4953
void Assembler::rep_mov() {
4954
// REP
4955
// MOVSQ
4956
LP64_ONLY(emit_int24((unsigned char)0xF3, REX_W, (unsigned char)0xA5);)
4957
NOT_LP64( emit_int16((unsigned char)0xF3, (unsigned char)0xA5);)
4958
}
4959
4960
// sets rcx bytes with rax, value at [edi]
4961
void Assembler::rep_stosb() {
4962
// REP
4963
// STOSB
4964
LP64_ONLY(emit_int24((unsigned char)0xF3, REX_W, (unsigned char)0xAA);)
4965
NOT_LP64( emit_int16((unsigned char)0xF3, (unsigned char)0xAA);)
4966
}
4967
4968
// sets rcx pointer sized words with rax, value at [edi]
4969
// generic
4970
void Assembler::rep_stos() {
4971
// REP
4972
// LP64:STOSQ, LP32:STOSD
4973
LP64_ONLY(emit_int24((unsigned char)0xF3, REX_W, (unsigned char)0xAB);)
4974
NOT_LP64( emit_int16((unsigned char)0xF3, (unsigned char)0xAB);)
4975
}
4976
4977
// scans rcx pointer sized words at [edi] for occurance of rax,
4978
// generic
4979
void Assembler::repne_scan() { // repne_scan
4980
// SCASQ
4981
LP64_ONLY(emit_int24((unsigned char)0xF2, REX_W, (unsigned char)0xAF);)
4982
NOT_LP64( emit_int16((unsigned char)0xF2, (unsigned char)0xAF);)
4983
}
4984
4985
#ifdef _LP64
4986
// scans rcx 4 byte words at [edi] for occurance of rax,
4987
// generic
4988
void Assembler::repne_scanl() { // repne_scan
4989
// SCASL
4990
emit_int16((unsigned char)0xF2, (unsigned char)0xAF);
4991
}
4992
#endif
4993
4994
void Assembler::ret(int imm16) {
4995
if (imm16 == 0) {
4996
emit_int8((unsigned char)0xC3);
4997
} else {
4998
emit_int8((unsigned char)0xC2);
4999
emit_int16(imm16);
5000
}
5001
}
5002
5003
void Assembler::roll(Register dst, int imm8) {
5004
assert(isShiftCount(imm8), "illegal shift count");
5005
int encode = prefix_and_encode(dst->encoding());
5006
if (imm8 == 1) {
5007
emit_int16((unsigned char)0xD1, (0xC0 | encode));
5008
} else {
5009
emit_int24((unsigned char)0xC1, (0xc0 | encode), imm8);
5010
}
5011
}
5012
5013
void Assembler::roll(Register dst) {
5014
int encode = prefix_and_encode(dst->encoding());
5015
emit_int16((unsigned char)0xD3, (0xC0 | encode));
5016
}
5017
5018
void Assembler::rorl(Register dst, int imm8) {
5019
assert(isShiftCount(imm8), "illegal shift count");
5020
int encode = prefix_and_encode(dst->encoding());
5021
if (imm8 == 1) {
5022
emit_int16((unsigned char)0xD1, (0xC8 | encode));
5023
} else {
5024
emit_int24((unsigned char)0xC1, (0xc8 | encode), imm8);
5025
}
5026
}
5027
5028
void Assembler::rorl(Register dst) {
5029
int encode = prefix_and_encode(dst->encoding());
5030
emit_int16((unsigned char)0xD3, (0xC8 | encode));
5031
}
5032
5033
#ifdef _LP64
5034
void Assembler::rorq(Register dst) {
5035
int encode = prefixq_and_encode(dst->encoding());
5036
emit_int16((unsigned char)0xD3, (0xC8 | encode));
5037
}
5038
5039
void Assembler::rorq(Register dst, int imm8) {
5040
assert(isShiftCount(imm8 >> 1), "illegal shift count");
5041
int encode = prefixq_and_encode(dst->encoding());
5042
if (imm8 == 1) {
5043
emit_int16((unsigned char)0xD1, (0xC8 | encode));
5044
} else {
5045
emit_int24((unsigned char)0xC1, (0xc8 | encode), imm8);
5046
}
5047
}
5048
5049
void Assembler::rolq(Register dst) {
5050
int encode = prefixq_and_encode(dst->encoding());
5051
emit_int16((unsigned char)0xD3, (0xC0 | encode));
5052
}
5053
5054
void Assembler::rolq(Register dst, int imm8) {
5055
assert(isShiftCount(imm8 >> 1), "illegal shift count");
5056
int encode = prefixq_and_encode(dst->encoding());
5057
if (imm8 == 1) {
5058
emit_int16((unsigned char)0xD1, (0xC0 | encode));
5059
} else {
5060
emit_int24((unsigned char)0xC1, (0xc0 | encode), imm8);
5061
}
5062
}
5063
#endif
5064
5065
void Assembler::sahf() {
5066
#ifdef _LP64
5067
// Not supported in 64bit mode
5068
ShouldNotReachHere();
5069
#endif
5070
emit_int8((unsigned char)0x9E);
5071
}
5072
5073
void Assembler::sall(Address dst, int imm8) {
5074
InstructionMark im(this);
5075
assert(isShiftCount(imm8), "illegal shift count");
5076
prefix(dst);
5077
if (imm8 == 1) {
5078
emit_int8((unsigned char)0xD1);
5079
emit_operand(as_Register(4), dst);
5080
}
5081
else {
5082
emit_int8((unsigned char)0xC1);
5083
emit_operand(as_Register(4), dst);
5084
emit_int8(imm8);
5085
}
5086
}
5087
5088
void Assembler::sall(Address dst) {
5089
InstructionMark im(this);
5090
prefix(dst);
5091
emit_int8((unsigned char)0xD3);
5092
emit_operand(as_Register(4), dst);
5093
}
5094
5095
void Assembler::sall(Register dst, int imm8) {
5096
assert(isShiftCount(imm8), "illegal shift count");
5097
int encode = prefix_and_encode(dst->encoding());
5098
if (imm8 == 1) {
5099
emit_int16((unsigned char)0xD1, (0xE0 | encode));
5100
} else {
5101
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
5102
}
5103
}
5104
5105
void Assembler::sall(Register dst) {
5106
int encode = prefix_and_encode(dst->encoding());
5107
emit_int16((unsigned char)0xD3, (0xE0 | encode));
5108
}
5109
5110
void Assembler::sarl(Address dst, int imm8) {
5111
assert(isShiftCount(imm8), "illegal shift count");
5112
InstructionMark im(this);
5113
prefix(dst);
5114
if (imm8 == 1) {
5115
emit_int8((unsigned char)0xD1);
5116
emit_operand(as_Register(7), dst);
5117
}
5118
else {
5119
emit_int8((unsigned char)0xC1);
5120
emit_operand(as_Register(7), dst);
5121
emit_int8(imm8);
5122
}
5123
}
5124
5125
void Assembler::sarl(Address dst) {
5126
InstructionMark im(this);
5127
prefix(dst);
5128
emit_int8((unsigned char)0xD3);
5129
emit_operand(as_Register(7), dst);
5130
}
5131
5132
void Assembler::sarl(Register dst, int imm8) {
5133
int encode = prefix_and_encode(dst->encoding());
5134
assert(isShiftCount(imm8), "illegal shift count");
5135
if (imm8 == 1) {
5136
emit_int16((unsigned char)0xD1, (0xF8 | encode));
5137
} else {
5138
emit_int24((unsigned char)0xC1, (0xF8 | encode), imm8);
5139
}
5140
}
5141
5142
void Assembler::sarl(Register dst) {
5143
int encode = prefix_and_encode(dst->encoding());
5144
emit_int16((unsigned char)0xD3, (0xF8 | encode));
5145
}
5146
5147
void Assembler::sbbl(Address dst, int32_t imm32) {
5148
InstructionMark im(this);
5149
prefix(dst);
5150
emit_arith_operand(0x81, rbx, dst, imm32);
5151
}
5152
5153
void Assembler::sbbl(Register dst, int32_t imm32) {
5154
prefix(dst);
5155
emit_arith(0x81, 0xD8, dst, imm32);
5156
}
5157
5158
5159
void Assembler::sbbl(Register dst, Address src) {
5160
InstructionMark im(this);
5161
prefix(src, dst);
5162
emit_int8(0x1B);
5163
emit_operand(dst, src);
5164
}
5165
5166
void Assembler::sbbl(Register dst, Register src) {
5167
(void) prefix_and_encode(dst->encoding(), src->encoding());
5168
emit_arith(0x1B, 0xC0, dst, src);
5169
}
5170
5171
void Assembler::setb(Condition cc, Register dst) {
5172
assert(0 <= cc && cc < 16, "illegal cc");
5173
int encode = prefix_and_encode(dst->encoding(), true);
5174
emit_int24(0x0F, (unsigned char)0x90 | cc, (0xC0 | encode));
5175
}
5176
5177
void Assembler::sete(Register dst) {
5178
int encode = prefix_and_encode(dst->encoding(), true);
5179
emit_int24(0x0F, (unsigned char)0x94, (0xC0 | encode));
5180
}
5181
5182
void Assembler::setl(Register dst) {
5183
int encode = prefix_and_encode(dst->encoding(), true);
5184
emit_int24(0x0F, (unsigned char)0x9C, (0xC0 | encode));
5185
}
5186
5187
void Assembler::setne(Register dst) {
5188
int encode = prefix_and_encode(dst->encoding(), true);
5189
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | encode));
5190
}
5191
5192
void Assembler::palignr(XMMRegister dst, XMMRegister src, int imm8) {
5193
assert(VM_Version::supports_ssse3(), "");
5194
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
5195
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5196
emit_int24(0x0F, (0xC0 | encode), imm8);
5197
}
5198
5199
void Assembler::vpalignr(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
5200
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
5201
vector_len == AVX_256bit? VM_Version::supports_avx2() :
5202
0, "");
5203
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
5204
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5205
emit_int24(0x0F, (0xC0 | encode), imm8);
5206
}
5207
5208
void Assembler::evalignq(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
5209
assert(VM_Version::supports_evex(), "");
5210
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5211
attributes.set_is_evex_instruction();
5212
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5213
emit_int24(0x3, (0xC0 | encode), imm8);
5214
}
5215
5216
void Assembler::pblendw(XMMRegister dst, XMMRegister src, int imm8) {
5217
assert(VM_Version::supports_sse4_1(), "");
5218
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5219
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5220
emit_int24(0x0E, (0xC0 | encode), imm8);
5221
}
5222
5223
void Assembler::sha1rnds4(XMMRegister dst, XMMRegister src, int imm8) {
5224
assert(VM_Version::supports_sha(), "");
5225
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3A, /* rex_w */ false);
5226
emit_int24((unsigned char)0xCC, (0xC0 | encode), (unsigned char)imm8);
5227
}
5228
5229
void Assembler::sha1nexte(XMMRegister dst, XMMRegister src) {
5230
assert(VM_Version::supports_sha(), "");
5231
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5232
emit_int16((unsigned char)0xC8, (0xC0 | encode));
5233
}
5234
5235
void Assembler::sha1msg1(XMMRegister dst, XMMRegister src) {
5236
assert(VM_Version::supports_sha(), "");
5237
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5238
emit_int16((unsigned char)0xC9, (0xC0 | encode));
5239
}
5240
5241
void Assembler::sha1msg2(XMMRegister dst, XMMRegister src) {
5242
assert(VM_Version::supports_sha(), "");
5243
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5244
emit_int16((unsigned char)0xCA, (0xC0 | encode));
5245
}
5246
5247
// xmm0 is implicit additional source to this instruction.
5248
void Assembler::sha256rnds2(XMMRegister dst, XMMRegister src) {
5249
assert(VM_Version::supports_sha(), "");
5250
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5251
emit_int16((unsigned char)0xCB, (0xC0 | encode));
5252
}
5253
5254
void Assembler::sha256msg1(XMMRegister dst, XMMRegister src) {
5255
assert(VM_Version::supports_sha(), "");
5256
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5257
emit_int16((unsigned char)0xCC, (0xC0 | encode));
5258
}
5259
5260
void Assembler::sha256msg2(XMMRegister dst, XMMRegister src) {
5261
assert(VM_Version::supports_sha(), "");
5262
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5263
emit_int16((unsigned char)0xCD, (0xC0 | encode));
5264
}
5265
5266
5267
void Assembler::shll(Register dst, int imm8) {
5268
assert(isShiftCount(imm8), "illegal shift count");
5269
int encode = prefix_and_encode(dst->encoding());
5270
if (imm8 == 1 ) {
5271
emit_int16((unsigned char)0xD1, (0xE0 | encode));
5272
} else {
5273
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
5274
}
5275
}
5276
5277
void Assembler::shll(Register dst) {
5278
int encode = prefix_and_encode(dst->encoding());
5279
emit_int16((unsigned char)0xD3, (0xE0 | encode));
5280
}
5281
5282
void Assembler::shrl(Register dst, int imm8) {
5283
assert(isShiftCount(imm8), "illegal shift count");
5284
int encode = prefix_and_encode(dst->encoding());
5285
if (imm8 == 1) {
5286
emit_int16((unsigned char)0xD1, (0xE8 | encode));
5287
}
5288
else {
5289
emit_int24((unsigned char)0xC1, (0xE8 | encode), imm8);
5290
}
5291
}
5292
5293
void Assembler::shrl(Register dst) {
5294
int encode = prefix_and_encode(dst->encoding());
5295
emit_int16((unsigned char)0xD3, (0xE8 | encode));
5296
}
5297
5298
void Assembler::shrl(Address dst) {
5299
InstructionMark im(this);
5300
prefix(dst);
5301
emit_int8((unsigned char)0xD3);
5302
emit_operand(as_Register(5), dst);
5303
}
5304
5305
void Assembler::shrl(Address dst, int imm8) {
5306
InstructionMark im(this);
5307
assert(isShiftCount(imm8), "illegal shift count");
5308
prefix(dst);
5309
if (imm8 == 1) {
5310
emit_int8((unsigned char)0xD1);
5311
emit_operand(as_Register(5), dst);
5312
}
5313
else {
5314
emit_int8((unsigned char)0xC1);
5315
emit_operand(as_Register(5), dst);
5316
emit_int8(imm8);
5317
}
5318
}
5319
5320
5321
void Assembler::shldl(Register dst, Register src) {
5322
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5323
emit_int24(0x0F, (unsigned char)0xA5, (0xC0 | encode));
5324
}
5325
5326
void Assembler::shldl(Register dst, Register src, int8_t imm8) {
5327
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5328
emit_int32(0x0F, (unsigned char)0xA4, (0xC0 | encode), imm8);
5329
}
5330
5331
void Assembler::shrdl(Register dst, Register src) {
5332
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5333
emit_int24(0x0F, (unsigned char)0xAD, (0xC0 | encode));
5334
}
5335
5336
void Assembler::shrdl(Register dst, Register src, int8_t imm8) {
5337
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5338
emit_int32(0x0F, (unsigned char)0xAC, (0xC0 | encode), imm8);
5339
}
5340
5341
// copies a single word from [esi] to [edi]
5342
void Assembler::smovl() {
5343
emit_int8((unsigned char)0xA5);
5344
}
5345
5346
void Assembler::roundsd(XMMRegister dst, XMMRegister src, int32_t rmode) {
5347
assert(VM_Version::supports_sse4_1(), "");
5348
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5349
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5350
emit_int24(0x0B, (0xC0 | encode), (unsigned char)rmode);
5351
}
5352
5353
void Assembler::roundsd(XMMRegister dst, Address src, int32_t rmode) {
5354
assert(VM_Version::supports_sse4_1(), "");
5355
InstructionMark im(this);
5356
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5357
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5358
emit_int8(0x0B);
5359
emit_operand(dst, src);
5360
emit_int8((unsigned char)rmode);
5361
}
5362
5363
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
5364
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5365
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5366
attributes.set_rex_vex_w_reverted();
5367
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5368
emit_int16(0x51, (0xC0 | encode));
5369
}
5370
5371
void Assembler::sqrtsd(XMMRegister dst, Address src) {
5372
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5373
InstructionMark im(this);
5374
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5375
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5376
attributes.set_rex_vex_w_reverted();
5377
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5378
emit_int8(0x51);
5379
emit_operand(dst, src);
5380
}
5381
5382
void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
5383
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5384
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5385
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5386
emit_int16(0x51, (0xC0 | encode));
5387
}
5388
5389
void Assembler::std() {
5390
emit_int8((unsigned char)0xFD);
5391
}
5392
5393
void Assembler::sqrtss(XMMRegister dst, Address src) {
5394
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5395
InstructionMark im(this);
5396
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5397
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5398
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5399
emit_int8(0x51);
5400
emit_operand(dst, src);
5401
}
5402
5403
void Assembler::stmxcsr( Address dst) {
5404
if (UseAVX > 0 ) {
5405
assert(VM_Version::supports_avx(), "");
5406
InstructionMark im(this);
5407
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5408
vex_prefix(dst, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5409
emit_int8((unsigned char)0xAE);
5410
emit_operand(as_Register(3), dst);
5411
} else {
5412
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5413
InstructionMark im(this);
5414
prefix(dst);
5415
emit_int16(0x0F, (unsigned char)0xAE);
5416
emit_operand(as_Register(3), dst);
5417
}
5418
}
5419
5420
void Assembler::subl(Address dst, int32_t imm32) {
5421
InstructionMark im(this);
5422
prefix(dst);
5423
emit_arith_operand(0x81, rbp, dst, imm32);
5424
}
5425
5426
void Assembler::subl(Address dst, Register src) {
5427
InstructionMark im(this);
5428
prefix(dst, src);
5429
emit_int8(0x29);
5430
emit_operand(src, dst);
5431
}
5432
5433
void Assembler::subl(Register dst, int32_t imm32) {
5434
prefix(dst);
5435
emit_arith(0x81, 0xE8, dst, imm32);
5436
}
5437
5438
// Force generation of a 4 byte immediate value even if it fits into 8bit
5439
void Assembler::subl_imm32(Register dst, int32_t imm32) {
5440
prefix(dst);
5441
emit_arith_imm32(0x81, 0xE8, dst, imm32);
5442
}
5443
5444
void Assembler::subl(Register dst, Address src) {
5445
InstructionMark im(this);
5446
prefix(src, dst);
5447
emit_int8(0x2B);
5448
emit_operand(dst, src);
5449
}
5450
5451
void Assembler::subl(Register dst, Register src) {
5452
(void) prefix_and_encode(dst->encoding(), src->encoding());
5453
emit_arith(0x2B, 0xC0, dst, src);
5454
}
5455
5456
void Assembler::subsd(XMMRegister dst, XMMRegister src) {
5457
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5458
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5459
attributes.set_rex_vex_w_reverted();
5460
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5461
emit_int16(0x5C, (0xC0 | encode));
5462
}
5463
5464
void Assembler::subsd(XMMRegister dst, Address src) {
5465
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5466
InstructionMark im(this);
5467
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5468
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5469
attributes.set_rex_vex_w_reverted();
5470
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5471
emit_int8(0x5C);
5472
emit_operand(dst, src);
5473
}
5474
5475
void Assembler::subss(XMMRegister dst, XMMRegister src) {
5476
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5477
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true , /* uses_vl */ false);
5478
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5479
emit_int16(0x5C, (0xC0 | encode));
5480
}
5481
5482
void Assembler::subss(XMMRegister dst, Address src) {
5483
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5484
InstructionMark im(this);
5485
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5486
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5487
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5488
emit_int8(0x5C);
5489
emit_operand(dst, src);
5490
}
5491
5492
void Assembler::testb(Register dst, int imm8) {
5493
NOT_LP64(assert(dst->has_byte_register(), "must have byte register"));
5494
(void) prefix_and_encode(dst->encoding(), true);
5495
emit_arith_b(0xF6, 0xC0, dst, imm8);
5496
}
5497
5498
void Assembler::testb(Address dst, int imm8) {
5499
InstructionMark im(this);
5500
prefix(dst);
5501
emit_int8((unsigned char)0xF6);
5502
emit_operand(rax, dst, 1);
5503
emit_int8(imm8);
5504
}
5505
5506
void Assembler::testl(Register dst, int32_t imm32) {
5507
// not using emit_arith because test
5508
// doesn't support sign-extension of
5509
// 8bit operands
5510
int encode = dst->encoding();
5511
encode = prefix_and_encode(encode);
5512
emit_int16((unsigned char)0xF7, (0xC0 | encode));
5513
emit_int32(imm32);
5514
}
5515
5516
void Assembler::testl(Register dst, Register src) {
5517
(void) prefix_and_encode(dst->encoding(), src->encoding());
5518
emit_arith(0x85, 0xC0, dst, src);
5519
}
5520
5521
void Assembler::testl(Register dst, Address src) {
5522
InstructionMark im(this);
5523
prefix(src, dst);
5524
emit_int8((unsigned char)0x85);
5525
emit_operand(dst, src);
5526
}
5527
5528
void Assembler::tzcntl(Register dst, Register src) {
5529
assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported");
5530
emit_int8((unsigned char)0xF3);
5531
int encode = prefix_and_encode(dst->encoding(), src->encoding());
5532
emit_int24(0x0F,
5533
(unsigned char)0xBC,
5534
0xC0 | encode);
5535
}
5536
5537
void Assembler::tzcntq(Register dst, Register src) {
5538
assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported");
5539
emit_int8((unsigned char)0xF3);
5540
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
5541
emit_int24(0x0F, (unsigned char)0xBC, (0xC0 | encode));
5542
}
5543
5544
void Assembler::ucomisd(XMMRegister dst, Address src) {
5545
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5546
InstructionMark im(this);
5547
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5548
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5549
attributes.set_rex_vex_w_reverted();
5550
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5551
emit_int8(0x2E);
5552
emit_operand(dst, src);
5553
}
5554
5555
void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
5556
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5557
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5558
attributes.set_rex_vex_w_reverted();
5559
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5560
emit_int16(0x2E, (0xC0 | encode));
5561
}
5562
5563
void Assembler::ucomiss(XMMRegister dst, Address src) {
5564
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5565
InstructionMark im(this);
5566
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5567
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5568
simd_prefix(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5569
emit_int8(0x2E);
5570
emit_operand(dst, src);
5571
}
5572
5573
void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
5574
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5575
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5576
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5577
emit_int16(0x2E, (0xC0 | encode));
5578
}
5579
5580
void Assembler::xabort(int8_t imm8) {
5581
emit_int24((unsigned char)0xC6, (unsigned char)0xF8, (imm8 & 0xFF));
5582
}
5583
5584
void Assembler::xaddb(Address dst, Register src) {
5585
InstructionMark im(this);
5586
prefix(dst, src, true);
5587
emit_int16(0x0F, (unsigned char)0xC0);
5588
emit_operand(src, dst);
5589
}
5590
5591
void Assembler::xaddw(Address dst, Register src) {
5592
InstructionMark im(this);
5593
emit_int8(0x66);
5594
prefix(dst, src);
5595
emit_int16(0x0F, (unsigned char)0xC1);
5596
emit_operand(src, dst);
5597
}
5598
5599
void Assembler::xaddl(Address dst, Register src) {
5600
InstructionMark im(this);
5601
prefix(dst, src);
5602
emit_int16(0x0F, (unsigned char)0xC1);
5603
emit_operand(src, dst);
5604
}
5605
5606
void Assembler::xbegin(Label& abort, relocInfo::relocType rtype) {
5607
InstructionMark im(this);
5608
relocate(rtype);
5609
if (abort.is_bound()) {
5610
address entry = target(abort);
5611
assert(entry != NULL, "abort entry NULL");
5612
intptr_t offset = entry - pc();
5613
emit_int16((unsigned char)0xC7, (unsigned char)0xF8);
5614
emit_int32(offset - 6); // 2 opcode + 4 address
5615
} else {
5616
abort.add_patch_at(code(), locator());
5617
emit_int16((unsigned char)0xC7, (unsigned char)0xF8);
5618
emit_int32(0);
5619
}
5620
}
5621
5622
void Assembler::xchgb(Register dst, Address src) { // xchg
5623
InstructionMark im(this);
5624
prefix(src, dst, true);
5625
emit_int8((unsigned char)0x86);
5626
emit_operand(dst, src);
5627
}
5628
5629
void Assembler::xchgw(Register dst, Address src) { // xchg
5630
InstructionMark im(this);
5631
emit_int8(0x66);
5632
prefix(src, dst);
5633
emit_int8((unsigned char)0x87);
5634
emit_operand(dst, src);
5635
}
5636
5637
void Assembler::xchgl(Register dst, Address src) { // xchg
5638
InstructionMark im(this);
5639
prefix(src, dst);
5640
emit_int8((unsigned char)0x87);
5641
emit_operand(dst, src);
5642
}
5643
5644
void Assembler::xchgl(Register dst, Register src) {
5645
int encode = prefix_and_encode(dst->encoding(), src->encoding());
5646
emit_int16((unsigned char)0x87, (0xC0 | encode));
5647
}
5648
5649
void Assembler::xend() {
5650
emit_int24(0x0F, 0x01, (unsigned char)0xD5);
5651
}
5652
5653
void Assembler::xgetbv() {
5654
emit_int24(0x0F, 0x01, (unsigned char)0xD0);
5655
}
5656
5657
void Assembler::xorl(Address dst, int32_t imm32) {
5658
InstructionMark im(this);
5659
prefix(dst);
5660
emit_arith_operand(0x81, as_Register(6), dst, imm32);
5661
}
5662
5663
void Assembler::xorl(Register dst, int32_t imm32) {
5664
prefix(dst);
5665
emit_arith(0x81, 0xF0, dst, imm32);
5666
}
5667
5668
void Assembler::xorl(Register dst, Address src) {
5669
InstructionMark im(this);
5670
prefix(src, dst);
5671
emit_int8(0x33);
5672
emit_operand(dst, src);
5673
}
5674
5675
void Assembler::xorl(Register dst, Register src) {
5676
(void) prefix_and_encode(dst->encoding(), src->encoding());
5677
emit_arith(0x33, 0xC0, dst, src);
5678
}
5679
5680
void Assembler::xorl(Address dst, Register src) {
5681
InstructionMark im(this);
5682
prefix(dst, src);
5683
emit_int8(0x31);
5684
emit_operand(src, dst);
5685
}
5686
5687
void Assembler::xorb(Register dst, Address src) {
5688
InstructionMark im(this);
5689
prefix(src, dst);
5690
emit_int8(0x32);
5691
emit_operand(dst, src);
5692
}
5693
5694
void Assembler::xorb(Address dst, Register src) {
5695
InstructionMark im(this);
5696
prefix(dst, src, true);
5697
emit_int8(0x30);
5698
emit_operand(src, dst);
5699
}
5700
5701
void Assembler::xorw(Register dst, Register src) {
5702
(void)prefix_and_encode(dst->encoding(), src->encoding());
5703
emit_arith(0x33, 0xC0, dst, src);
5704
}
5705
5706
// AVX 3-operands scalar float-point arithmetic instructions
5707
5708
void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
5709
assert(VM_Version::supports_avx(), "");
5710
InstructionMark im(this);
5711
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5712
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5713
attributes.set_rex_vex_w_reverted();
5714
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5715
emit_int8(0x58);
5716
emit_operand(dst, src);
5717
}
5718
5719
void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5720
assert(VM_Version::supports_avx(), "");
5721
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5722
attributes.set_rex_vex_w_reverted();
5723
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5724
emit_int16(0x58, (0xC0 | encode));
5725
}
5726
5727
void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
5728
assert(VM_Version::supports_avx(), "");
5729
InstructionMark im(this);
5730
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5731
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5732
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5733
emit_int8(0x58);
5734
emit_operand(dst, src);
5735
}
5736
5737
void Assembler::vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5738
assert(VM_Version::supports_avx(), "");
5739
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5740
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5741
emit_int16(0x58, (0xC0 | encode));
5742
}
5743
5744
void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
5745
assert(VM_Version::supports_avx(), "");
5746
InstructionMark im(this);
5747
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5748
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5749
attributes.set_rex_vex_w_reverted();
5750
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5751
emit_int8(0x5E);
5752
emit_operand(dst, src);
5753
}
5754
5755
void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5756
assert(VM_Version::supports_avx(), "");
5757
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5758
attributes.set_rex_vex_w_reverted();
5759
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5760
emit_int16(0x5E, (0xC0 | encode));
5761
}
5762
5763
void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
5764
assert(VM_Version::supports_avx(), "");
5765
InstructionMark im(this);
5766
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5767
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5768
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5769
emit_int8(0x5E);
5770
emit_operand(dst, src);
5771
}
5772
5773
void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5774
assert(VM_Version::supports_avx(), "");
5775
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5776
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5777
emit_int16(0x5E, (0xC0 | encode));
5778
}
5779
5780
void Assembler::vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
5781
assert(VM_Version::supports_fma(), "");
5782
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5783
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
5784
emit_int16((unsigned char)0xB9, (0xC0 | encode));
5785
}
5786
5787
void Assembler::vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
5788
assert(VM_Version::supports_fma(), "");
5789
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5790
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
5791
emit_int16((unsigned char)0xB9, (0xC0 | encode));
5792
}
5793
5794
void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
5795
assert(VM_Version::supports_avx(), "");
5796
InstructionMark im(this);
5797
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5798
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5799
attributes.set_rex_vex_w_reverted();
5800
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5801
emit_int8(0x59);
5802
emit_operand(dst, src);
5803
}
5804
5805
void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5806
assert(VM_Version::supports_avx(), "");
5807
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5808
attributes.set_rex_vex_w_reverted();
5809
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5810
emit_int16(0x59, (0xC0 | encode));
5811
}
5812
5813
void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
5814
assert(VM_Version::supports_avx(), "");
5815
InstructionMark im(this);
5816
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5817
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5818
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5819
emit_int8(0x59);
5820
emit_operand(dst, src);
5821
}
5822
5823
void Assembler::vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5824
assert(VM_Version::supports_avx(), "");
5825
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5826
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5827
emit_int16(0x59, (0xC0 | encode));
5828
}
5829
5830
void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
5831
assert(VM_Version::supports_avx(), "");
5832
InstructionMark im(this);
5833
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5834
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5835
attributes.set_rex_vex_w_reverted();
5836
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5837
emit_int8(0x5C);
5838
emit_operand(dst, src);
5839
}
5840
5841
void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5842
assert(VM_Version::supports_avx(), "");
5843
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5844
attributes.set_rex_vex_w_reverted();
5845
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5846
emit_int16(0x5C, (0xC0 | encode));
5847
}
5848
5849
void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
5850
assert(VM_Version::supports_avx(), "");
5851
InstructionMark im(this);
5852
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5853
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5854
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5855
emit_int8(0x5C);
5856
emit_operand(dst, src);
5857
}
5858
5859
void Assembler::vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5860
assert(VM_Version::supports_avx(), "");
5861
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5862
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5863
emit_int16(0x5C, (0xC0 | encode));
5864
}
5865
5866
//====================VECTOR ARITHMETIC=====================================
5867
5868
// Float-point vector arithmetic
5869
5870
void Assembler::addpd(XMMRegister dst, XMMRegister src) {
5871
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5872
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5873
attributes.set_rex_vex_w_reverted();
5874
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5875
emit_int16(0x58, (0xC0 | encode));
5876
}
5877
5878
void Assembler::addpd(XMMRegister dst, Address src) {
5879
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5880
InstructionMark im(this);
5881
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5882
attributes.set_rex_vex_w_reverted();
5883
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5884
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5885
emit_int8(0x58);
5886
emit_operand(dst, src);
5887
}
5888
5889
5890
void Assembler::addps(XMMRegister dst, XMMRegister src) {
5891
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5892
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5893
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5894
emit_int16(0x58, (0xC0 | encode));
5895
}
5896
5897
void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5898
assert(VM_Version::supports_avx(), "");
5899
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5900
attributes.set_rex_vex_w_reverted();
5901
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5902
emit_int16(0x58, (0xC0 | encode));
5903
}
5904
5905
void Assembler::vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5906
assert(VM_Version::supports_avx(), "");
5907
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5908
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5909
emit_int16(0x58, (0xC0 | encode));
5910
}
5911
5912
void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5913
assert(VM_Version::supports_avx(), "");
5914
InstructionMark im(this);
5915
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5916
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5917
attributes.set_rex_vex_w_reverted();
5918
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5919
emit_int8(0x58);
5920
emit_operand(dst, src);
5921
}
5922
5923
void Assembler::vaddps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5924
assert(VM_Version::supports_avx(), "");
5925
InstructionMark im(this);
5926
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5927
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
5928
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5929
emit_int8(0x58);
5930
emit_operand(dst, src);
5931
}
5932
5933
void Assembler::subpd(XMMRegister dst, XMMRegister src) {
5934
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5935
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5936
attributes.set_rex_vex_w_reverted();
5937
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5938
emit_int16(0x5C, (0xC0 | encode));
5939
}
5940
5941
void Assembler::subps(XMMRegister dst, XMMRegister src) {
5942
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5943
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5944
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5945
emit_int16(0x5C, (0xC0 | encode));
5946
}
5947
5948
void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5949
assert(VM_Version::supports_avx(), "");
5950
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5951
attributes.set_rex_vex_w_reverted();
5952
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5953
emit_int16(0x5C, (0xC0 | encode));
5954
}
5955
5956
void Assembler::vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5957
assert(VM_Version::supports_avx(), "");
5958
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5959
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5960
emit_int16(0x5C, (0xC0 | encode));
5961
}
5962
5963
void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5964
assert(VM_Version::supports_avx(), "");
5965
InstructionMark im(this);
5966
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5967
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5968
attributes.set_rex_vex_w_reverted();
5969
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5970
emit_int8(0x5C);
5971
emit_operand(dst, src);
5972
}
5973
5974
void Assembler::vsubps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5975
assert(VM_Version::supports_avx(), "");
5976
InstructionMark im(this);
5977
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5978
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
5979
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5980
emit_int8(0x5C);
5981
emit_operand(dst, src);
5982
}
5983
5984
void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
5985
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5986
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5987
attributes.set_rex_vex_w_reverted();
5988
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5989
emit_int16(0x59, (0xC0 | encode));
5990
}
5991
5992
void Assembler::mulpd(XMMRegister dst, Address src) {
5993
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5994
InstructionMark im(this);
5995
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5996
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5997
attributes.set_rex_vex_w_reverted();
5998
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5999
emit_int8(0x59);
6000
emit_operand(dst, src);
6001
}
6002
6003
void Assembler::mulps(XMMRegister dst, XMMRegister src) {
6004
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6005
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6006
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6007
emit_int16(0x59, (0xC0 | encode));
6008
}
6009
6010
void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6011
assert(VM_Version::supports_avx(), "");
6012
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6013
attributes.set_rex_vex_w_reverted();
6014
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6015
emit_int16(0x59, (0xC0 | encode));
6016
}
6017
6018
void Assembler::vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6019
assert(VM_Version::supports_avx(), "");
6020
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6021
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6022
emit_int16(0x59, (0xC0 | encode));
6023
}
6024
6025
void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6026
assert(VM_Version::supports_avx(), "");
6027
InstructionMark im(this);
6028
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6029
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6030
attributes.set_rex_vex_w_reverted();
6031
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6032
emit_int8(0x59);
6033
emit_operand(dst, src);
6034
}
6035
6036
void Assembler::vmulps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6037
assert(VM_Version::supports_avx(), "");
6038
InstructionMark im(this);
6039
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6040
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6041
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6042
emit_int8(0x59);
6043
emit_operand(dst, src);
6044
}
6045
6046
void Assembler::vfmadd231pd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len) {
6047
assert(VM_Version::supports_fma(), "");
6048
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6049
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6050
emit_int16((unsigned char)0xB8, (0xC0 | encode));
6051
}
6052
6053
void Assembler::vfmadd231ps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len) {
6054
assert(VM_Version::supports_fma(), "");
6055
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6056
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6057
emit_int16((unsigned char)0xB8, (0xC0 | encode));
6058
}
6059
6060
void Assembler::vfmadd231pd(XMMRegister dst, XMMRegister src1, Address src2, int vector_len) {
6061
assert(VM_Version::supports_fma(), "");
6062
InstructionMark im(this);
6063
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6064
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6065
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6066
emit_int8((unsigned char)0xB8);
6067
emit_operand(dst, src2);
6068
}
6069
6070
void Assembler::vfmadd231ps(XMMRegister dst, XMMRegister src1, Address src2, int vector_len) {
6071
assert(VM_Version::supports_fma(), "");
6072
InstructionMark im(this);
6073
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6074
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6075
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6076
emit_int8((unsigned char)0xB8);
6077
emit_operand(dst, src2);
6078
}
6079
6080
void Assembler::divpd(XMMRegister dst, XMMRegister src) {
6081
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6082
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6083
attributes.set_rex_vex_w_reverted();
6084
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6085
emit_int16(0x5E, (0xC0 | encode));
6086
}
6087
6088
void Assembler::divps(XMMRegister dst, XMMRegister src) {
6089
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6090
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6091
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6092
emit_int16(0x5E, (0xC0 | encode));
6093
}
6094
6095
void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6096
assert(VM_Version::supports_avx(), "");
6097
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6098
attributes.set_rex_vex_w_reverted();
6099
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6100
emit_int16(0x5E, (0xC0 | encode));
6101
}
6102
6103
void Assembler::vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6104
assert(VM_Version::supports_avx(), "");
6105
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6106
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6107
emit_int16(0x5E, (0xC0 | encode));
6108
}
6109
6110
void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6111
assert(VM_Version::supports_avx(), "");
6112
InstructionMark im(this);
6113
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6114
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6115
attributes.set_rex_vex_w_reverted();
6116
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6117
emit_int8(0x5E);
6118
emit_operand(dst, src);
6119
}
6120
6121
void Assembler::vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6122
assert(VM_Version::supports_avx(), "");
6123
InstructionMark im(this);
6124
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6125
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6126
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6127
emit_int8(0x5E);
6128
emit_operand(dst, src);
6129
}
6130
6131
void Assembler::vroundpd(XMMRegister dst, XMMRegister src, int32_t rmode, int vector_len) {
6132
assert(VM_Version::supports_avx(), "");
6133
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
6134
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6135
emit_int24(0x09, (0xC0 | encode), (rmode));
6136
}
6137
6138
void Assembler::vroundpd(XMMRegister dst, Address src, int32_t rmode, int vector_len) {
6139
assert(VM_Version::supports_avx(), "");
6140
InstructionMark im(this);
6141
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
6142
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6143
emit_int8(0x09);
6144
emit_operand(dst, src);
6145
emit_int8((rmode));
6146
}
6147
6148
void Assembler::vrndscalepd(XMMRegister dst, XMMRegister src, int32_t rmode, int vector_len) {
6149
assert(VM_Version::supports_evex(), "requires EVEX support");
6150
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6151
attributes.set_is_evex_instruction();
6152
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6153
emit_int24(0x09, (0xC0 | encode), (rmode));
6154
}
6155
6156
void Assembler::vrndscalepd(XMMRegister dst, Address src, int32_t rmode, int vector_len) {
6157
assert(VM_Version::supports_evex(), "requires EVEX support");
6158
assert(dst != xnoreg, "sanity");
6159
InstructionMark im(this);
6160
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6161
attributes.set_is_evex_instruction();
6162
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6163
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6164
emit_int8(0x09);
6165
emit_operand(dst, src);
6166
emit_int8((rmode));
6167
}
6168
6169
6170
void Assembler::vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len) {
6171
assert(VM_Version::supports_avx(), "");
6172
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6173
attributes.set_rex_vex_w_reverted();
6174
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6175
emit_int16(0x51, (0xC0 | encode));
6176
}
6177
6178
void Assembler::vsqrtpd(XMMRegister dst, Address src, int vector_len) {
6179
assert(VM_Version::supports_avx(), "");
6180
InstructionMark im(this);
6181
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6182
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6183
attributes.set_rex_vex_w_reverted();
6184
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6185
emit_int8(0x51);
6186
emit_operand(dst, src);
6187
}
6188
6189
void Assembler::vsqrtps(XMMRegister dst, XMMRegister src, int vector_len) {
6190
assert(VM_Version::supports_avx(), "");
6191
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6192
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6193
emit_int16(0x51, (0xC0 | encode));
6194
}
6195
6196
void Assembler::vsqrtps(XMMRegister dst, Address src, int vector_len) {
6197
assert(VM_Version::supports_avx(), "");
6198
InstructionMark im(this);
6199
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6200
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6201
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6202
emit_int8(0x51);
6203
emit_operand(dst, src);
6204
}
6205
6206
void Assembler::andpd(XMMRegister dst, XMMRegister src) {
6207
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6208
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6209
attributes.set_rex_vex_w_reverted();
6210
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6211
emit_int16(0x54, (0xC0 | encode));
6212
}
6213
6214
void Assembler::andps(XMMRegister dst, XMMRegister src) {
6215
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6216
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6217
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6218
emit_int16(0x54, (0xC0 | encode));
6219
}
6220
6221
void Assembler::andps(XMMRegister dst, Address src) {
6222
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6223
InstructionMark im(this);
6224
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6225
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6226
simd_prefix(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6227
emit_int8(0x54);
6228
emit_operand(dst, src);
6229
}
6230
6231
void Assembler::andpd(XMMRegister dst, Address src) {
6232
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6233
InstructionMark im(this);
6234
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6235
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6236
attributes.set_rex_vex_w_reverted();
6237
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6238
emit_int8(0x54);
6239
emit_operand(dst, src);
6240
}
6241
6242
void Assembler::vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6243
assert(VM_Version::supports_avx(), "");
6244
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6245
attributes.set_rex_vex_w_reverted();
6246
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6247
emit_int16(0x54, (0xC0 | encode));
6248
}
6249
6250
void Assembler::vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6251
assert(VM_Version::supports_avx(), "");
6252
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6253
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6254
emit_int16(0x54, (0xC0 | encode));
6255
}
6256
6257
void Assembler::vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6258
assert(VM_Version::supports_avx(), "");
6259
InstructionMark im(this);
6260
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6261
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6262
attributes.set_rex_vex_w_reverted();
6263
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6264
emit_int8(0x54);
6265
emit_operand(dst, src);
6266
}
6267
6268
void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6269
assert(VM_Version::supports_avx(), "");
6270
InstructionMark im(this);
6271
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6272
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6273
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6274
emit_int8(0x54);
6275
emit_operand(dst, src);
6276
}
6277
6278
void Assembler::unpckhpd(XMMRegister dst, XMMRegister src) {
6279
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6280
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6281
attributes.set_rex_vex_w_reverted();
6282
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6283
emit_int8(0x15);
6284
emit_int8((0xC0 | encode));
6285
}
6286
6287
void Assembler::unpcklpd(XMMRegister dst, XMMRegister src) {
6288
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6289
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6290
attributes.set_rex_vex_w_reverted();
6291
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6292
emit_int16(0x14, (0xC0 | encode));
6293
}
6294
6295
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
6296
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6297
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6298
attributes.set_rex_vex_w_reverted();
6299
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6300
emit_int16(0x57, (0xC0 | encode));
6301
}
6302
6303
void Assembler::xorps(XMMRegister dst, XMMRegister src) {
6304
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6305
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6306
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6307
emit_int16(0x57, (0xC0 | encode));
6308
}
6309
6310
void Assembler::xorpd(XMMRegister dst, Address src) {
6311
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6312
InstructionMark im(this);
6313
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6314
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6315
attributes.set_rex_vex_w_reverted();
6316
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6317
emit_int8(0x57);
6318
emit_operand(dst, src);
6319
}
6320
6321
void Assembler::xorps(XMMRegister dst, Address src) {
6322
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6323
InstructionMark im(this);
6324
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6325
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6326
simd_prefix(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6327
emit_int8(0x57);
6328
emit_operand(dst, src);
6329
}
6330
6331
void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6332
assert(VM_Version::supports_avx(), "");
6333
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6334
attributes.set_rex_vex_w_reverted();
6335
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6336
emit_int16(0x57, (0xC0 | encode));
6337
}
6338
6339
void Assembler::vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6340
assert(VM_Version::supports_avx(), "");
6341
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6342
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6343
emit_int16(0x57, (0xC0 | encode));
6344
}
6345
6346
void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6347
assert(VM_Version::supports_avx(), "");
6348
InstructionMark im(this);
6349
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6350
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6351
attributes.set_rex_vex_w_reverted();
6352
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6353
emit_int8(0x57);
6354
emit_operand(dst, src);
6355
}
6356
6357
void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6358
assert(VM_Version::supports_avx(), "");
6359
InstructionMark im(this);
6360
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6361
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6362
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6363
emit_int8(0x57);
6364
emit_operand(dst, src);
6365
}
6366
6367
// Integer vector arithmetic
6368
void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6369
assert(VM_Version::supports_avx() && (vector_len == 0) ||
6370
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
6371
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6372
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6373
emit_int16(0x01, (0xC0 | encode));
6374
}
6375
6376
void Assembler::vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6377
assert(VM_Version::supports_avx() && (vector_len == 0) ||
6378
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
6379
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6380
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6381
emit_int16(0x02, (0xC0 | encode));
6382
}
6383
6384
void Assembler::paddb(XMMRegister dst, XMMRegister src) {
6385
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6386
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6387
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6388
emit_int16((unsigned char)0xFC, (0xC0 | encode));
6389
}
6390
6391
void Assembler::paddw(XMMRegister dst, XMMRegister src) {
6392
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6393
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6394
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6395
emit_int16((unsigned char)0xFD, (0xC0 | encode));
6396
}
6397
6398
void Assembler::paddd(XMMRegister dst, XMMRegister src) {
6399
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6400
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6401
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6402
emit_int16((unsigned char)0xFE, (0xC0 | encode));
6403
}
6404
6405
void Assembler::paddd(XMMRegister dst, Address src) {
6406
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6407
InstructionMark im(this);
6408
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6409
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6410
emit_int8((unsigned char)0xFE);
6411
emit_operand(dst, src);
6412
}
6413
6414
void Assembler::paddq(XMMRegister dst, XMMRegister src) {
6415
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6416
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6417
attributes.set_rex_vex_w_reverted();
6418
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6419
emit_int16((unsigned char)0xD4, (0xC0 | encode));
6420
}
6421
6422
void Assembler::phaddw(XMMRegister dst, XMMRegister src) {
6423
assert(VM_Version::supports_sse3(), "");
6424
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6425
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6426
emit_int16(0x01, (0xC0 | encode));
6427
}
6428
6429
void Assembler::phaddd(XMMRegister dst, XMMRegister src) {
6430
assert(VM_Version::supports_sse3(), "");
6431
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6432
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6433
emit_int16(0x02, (0xC0 | encode));
6434
}
6435
6436
void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6437
assert(UseAVX > 0, "requires some form of AVX");
6438
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6439
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6440
emit_int16((unsigned char)0xFC, (0xC0 | encode));
6441
}
6442
6443
void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6444
assert(UseAVX > 0, "requires some form of AVX");
6445
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6446
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6447
emit_int16((unsigned char)0xFD, (0xC0 | encode));
6448
}
6449
6450
void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6451
assert(UseAVX > 0, "requires some form of AVX");
6452
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6453
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6454
emit_int16((unsigned char)0xFE, (0xC0 | encode));
6455
}
6456
6457
void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6458
assert(UseAVX > 0, "requires some form of AVX");
6459
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6460
attributes.set_rex_vex_w_reverted();
6461
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6462
emit_int16((unsigned char)0xD4, (0xC0 | encode));
6463
}
6464
6465
void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6466
assert(UseAVX > 0, "requires some form of AVX");
6467
InstructionMark im(this);
6468
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6469
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6470
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6471
emit_int8((unsigned char)0xFC);
6472
emit_operand(dst, src);
6473
}
6474
6475
void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6476
assert(UseAVX > 0, "requires some form of AVX");
6477
InstructionMark im(this);
6478
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6479
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6480
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6481
emit_int8((unsigned char)0xFD);
6482
emit_operand(dst, src);
6483
}
6484
6485
void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6486
assert(UseAVX > 0, "requires some form of AVX");
6487
InstructionMark im(this);
6488
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6489
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6490
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6491
emit_int8((unsigned char)0xFE);
6492
emit_operand(dst, src);
6493
}
6494
6495
void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6496
assert(UseAVX > 0, "requires some form of AVX");
6497
InstructionMark im(this);
6498
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6499
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6500
attributes.set_rex_vex_w_reverted();
6501
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6502
emit_int8((unsigned char)0xD4);
6503
emit_operand(dst, src);
6504
}
6505
6506
void Assembler::psubb(XMMRegister dst, XMMRegister src) {
6507
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6508
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6509
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6510
emit_int16((unsigned char)0xF8, (0xC0 | encode));
6511
}
6512
6513
void Assembler::psubw(XMMRegister dst, XMMRegister src) {
6514
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6515
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6516
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6517
emit_int16((unsigned char)0xF9, (0xC0 | encode));
6518
}
6519
6520
void Assembler::psubd(XMMRegister dst, XMMRegister src) {
6521
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6522
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6523
emit_int16((unsigned char)0xFA, (0xC0 | encode));
6524
}
6525
6526
void Assembler::psubq(XMMRegister dst, XMMRegister src) {
6527
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6528
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6529
attributes.set_rex_vex_w_reverted();
6530
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6531
emit_int8((unsigned char)0xFB);
6532
emit_int8((0xC0 | encode));
6533
}
6534
6535
void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6536
assert(UseAVX > 0, "requires some form of AVX");
6537
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6538
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6539
emit_int16((unsigned char)0xF8, (0xC0 | encode));
6540
}
6541
6542
void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6543
assert(UseAVX > 0, "requires some form of AVX");
6544
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6545
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6546
emit_int16((unsigned char)0xF9, (0xC0 | encode));
6547
}
6548
6549
void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6550
assert(UseAVX > 0, "requires some form of AVX");
6551
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6552
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6553
emit_int16((unsigned char)0xFA, (0xC0 | encode));
6554
}
6555
6556
void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6557
assert(UseAVX > 0, "requires some form of AVX");
6558
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6559
attributes.set_rex_vex_w_reverted();
6560
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6561
emit_int16((unsigned char)0xFB, (0xC0 | encode));
6562
}
6563
6564
void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6565
assert(UseAVX > 0, "requires some form of AVX");
6566
InstructionMark im(this);
6567
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6568
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6569
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6570
emit_int8((unsigned char)0xF8);
6571
emit_operand(dst, src);
6572
}
6573
6574
void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6575
assert(UseAVX > 0, "requires some form of AVX");
6576
InstructionMark im(this);
6577
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6578
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6579
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6580
emit_int8((unsigned char)0xF9);
6581
emit_operand(dst, src);
6582
}
6583
6584
void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6585
assert(UseAVX > 0, "requires some form of AVX");
6586
InstructionMark im(this);
6587
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6588
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6589
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6590
emit_int8((unsigned char)0xFA);
6591
emit_operand(dst, src);
6592
}
6593
6594
void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6595
assert(UseAVX > 0, "requires some form of AVX");
6596
InstructionMark im(this);
6597
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6598
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6599
attributes.set_rex_vex_w_reverted();
6600
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6601
emit_int8((unsigned char)0xFB);
6602
emit_operand(dst, src);
6603
}
6604
6605
void Assembler::pmullw(XMMRegister dst, XMMRegister src) {
6606
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6607
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6608
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6609
emit_int16((unsigned char)0xD5, (0xC0 | encode));
6610
}
6611
6612
void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
6613
assert(VM_Version::supports_sse4_1(), "");
6614
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6615
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6616
emit_int16(0x40, (0xC0 | encode));
6617
}
6618
6619
void Assembler::pmuludq(XMMRegister dst, XMMRegister src) {
6620
assert(VM_Version::supports_sse2(), "");
6621
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6622
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6623
emit_int16((unsigned char)0xF4, (0xC0 | encode));
6624
}
6625
6626
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6627
assert(UseAVX > 0, "requires some form of AVX");
6628
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6629
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6630
emit_int16((unsigned char)0xD5, (0xC0 | encode));
6631
}
6632
6633
void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6634
assert(UseAVX > 0, "requires some form of AVX");
6635
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6636
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6637
emit_int16(0x40, (0xC0 | encode));
6638
}
6639
6640
void Assembler::vpmullq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6641
assert(UseAVX > 2, "requires some form of EVEX");
6642
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6643
attributes.set_is_evex_instruction();
6644
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6645
emit_int16(0x40, (0xC0 | encode));
6646
}
6647
6648
void Assembler::vpmuludq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6649
assert(UseAVX > 0, "requires some form of AVX");
6650
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6651
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6652
emit_int16((unsigned char)0xF4, (0xC0 | encode));
6653
}
6654
6655
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6656
assert(UseAVX > 0, "requires some form of AVX");
6657
InstructionMark im(this);
6658
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6659
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6660
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6661
emit_int8((unsigned char)0xD5);
6662
emit_operand(dst, src);
6663
}
6664
6665
void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6666
assert(UseAVX > 0, "requires some form of AVX");
6667
InstructionMark im(this);
6668
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6669
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6670
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6671
emit_int8(0x40);
6672
emit_operand(dst, src);
6673
}
6674
6675
void Assembler::vpmullq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6676
assert(UseAVX > 2, "requires some form of EVEX");
6677
InstructionMark im(this);
6678
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6679
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6680
attributes.set_is_evex_instruction();
6681
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6682
emit_int8(0x40);
6683
emit_operand(dst, src);
6684
}
6685
6686
// Min, max
6687
void Assembler::pminsb(XMMRegister dst, XMMRegister src) {
6688
assert(VM_Version::supports_sse4_1(), "");
6689
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6690
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6691
emit_int16(0x38, (0xC0 | encode));
6692
}
6693
6694
void Assembler::vpminsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6695
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6696
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6697
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6698
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6699
emit_int16(0x38, (0xC0 | encode));
6700
}
6701
6702
void Assembler::pminsw(XMMRegister dst, XMMRegister src) {
6703
assert(VM_Version::supports_sse2(), "");
6704
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6705
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6706
emit_int16((unsigned char)0xEA, (0xC0 | encode));
6707
}
6708
6709
void Assembler::vpminsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6710
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6711
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6712
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6713
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6714
emit_int16((unsigned char)0xEA, (0xC0 | encode));
6715
}
6716
6717
void Assembler::pminsd(XMMRegister dst, XMMRegister src) {
6718
assert(VM_Version::supports_sse4_1(), "");
6719
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6720
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6721
emit_int16(0x39, (0xC0 | encode));
6722
}
6723
6724
void Assembler::vpminsd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6725
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6726
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex()), "");
6727
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6728
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6729
emit_int16(0x39, (0xC0 | encode));
6730
}
6731
6732
void Assembler::vpminsq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6733
assert(UseAVX > 2, "requires AVX512F");
6734
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6735
attributes.set_is_evex_instruction();
6736
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6737
emit_int16(0x39, (0xC0 | encode));
6738
}
6739
6740
void Assembler::minps(XMMRegister dst, XMMRegister src) {
6741
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6742
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6743
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6744
emit_int16(0x5D, (0xC0 | encode));
6745
}
6746
void Assembler::vminps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6747
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6748
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6749
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6750
emit_int16(0x5D, (0xC0 | encode));
6751
}
6752
6753
void Assembler::minpd(XMMRegister dst, XMMRegister src) {
6754
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6755
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6756
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6757
emit_int16(0x5D, (0xC0 | encode));
6758
}
6759
void Assembler::vminpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6760
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6761
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6762
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6763
emit_int16(0x5D, (0xC0 | encode));
6764
}
6765
6766
void Assembler::pmaxsb(XMMRegister dst, XMMRegister src) {
6767
assert(VM_Version::supports_sse4_1(), "");
6768
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6769
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6770
emit_int16(0x3C, (0xC0 | encode));
6771
}
6772
6773
void Assembler::vpmaxsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6774
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6775
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6776
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6777
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6778
emit_int16(0x3C, (0xC0 | encode));
6779
}
6780
6781
void Assembler::pmaxsw(XMMRegister dst, XMMRegister src) {
6782
assert(VM_Version::supports_sse2(), "");
6783
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6784
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6785
emit_int16((unsigned char)0xEE, (0xC0 | encode));
6786
}
6787
6788
void Assembler::vpmaxsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6789
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6790
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6791
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6792
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6793
emit_int16((unsigned char)0xEE, (0xC0 | encode));
6794
}
6795
6796
void Assembler::pmaxsd(XMMRegister dst, XMMRegister src) {
6797
assert(VM_Version::supports_sse4_1(), "");
6798
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6799
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6800
emit_int16(0x3D, (0xC0 | encode));
6801
}
6802
6803
void Assembler::vpmaxsd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6804
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6805
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex()), "");
6806
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6807
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6808
emit_int16(0x3D, (0xC0 | encode));
6809
}
6810
6811
void Assembler::vpmaxsq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6812
assert(UseAVX > 2, "requires AVX512F");
6813
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6814
attributes.set_is_evex_instruction();
6815
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6816
emit_int16(0x3D, (0xC0 | encode));
6817
}
6818
6819
void Assembler::maxps(XMMRegister dst, XMMRegister src) {
6820
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6821
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6822
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6823
emit_int16(0x5F, (0xC0 | encode));
6824
}
6825
6826
void Assembler::vmaxps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6827
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6828
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6829
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6830
emit_int16(0x5F, (0xC0 | encode));
6831
}
6832
6833
void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
6834
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6835
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6836
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6837
emit_int16(0x5F, (0xC0 | encode));
6838
}
6839
6840
void Assembler::vmaxpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6841
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6842
InstructionAttr attributes(vector_len, /* vex_w */true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6843
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6844
emit_int16(0x5F, (0xC0 | encode));
6845
}
6846
6847
// Shift packed integers left by specified number of bits.
6848
void Assembler::psllw(XMMRegister dst, int shift) {
6849
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6850
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6851
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
6852
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6853
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6854
}
6855
6856
void Assembler::pslld(XMMRegister dst, int shift) {
6857
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6858
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6859
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
6860
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6861
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
6862
}
6863
6864
void Assembler::psllq(XMMRegister dst, int shift) {
6865
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6866
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6867
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
6868
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6869
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
6870
}
6871
6872
void Assembler::psllw(XMMRegister dst, XMMRegister shift) {
6873
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6874
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6875
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6876
emit_int16((unsigned char)0xF1, (0xC0 | encode));
6877
}
6878
6879
void Assembler::pslld(XMMRegister dst, XMMRegister shift) {
6880
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6881
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6882
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6883
emit_int16((unsigned char)0xF2, (0xC0 | encode));
6884
}
6885
6886
void Assembler::psllq(XMMRegister dst, XMMRegister shift) {
6887
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6888
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6889
attributes.set_rex_vex_w_reverted();
6890
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6891
emit_int16((unsigned char)0xF3, (0xC0 | encode));
6892
}
6893
6894
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6895
assert(UseAVX > 0, "requires some form of AVX");
6896
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6897
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
6898
int encode = vex_prefix_and_encode(xmm6->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6899
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6900
}
6901
6902
void Assembler::vpslld(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6903
assert(UseAVX > 0, "requires some form of AVX");
6904
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6905
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6906
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
6907
int encode = vex_prefix_and_encode(xmm6->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6908
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
6909
}
6910
6911
void Assembler::vpsllq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6912
assert(UseAVX > 0, "requires some form of AVX");
6913
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6914
attributes.set_rex_vex_w_reverted();
6915
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
6916
int encode = vex_prefix_and_encode(xmm6->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6917
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
6918
}
6919
6920
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
6921
assert(UseAVX > 0, "requires some form of AVX");
6922
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6923
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6924
emit_int16((unsigned char)0xF1, (0xC0 | encode));
6925
}
6926
6927
void Assembler::vpslld(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
6928
assert(UseAVX > 0, "requires some form of AVX");
6929
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6930
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6931
emit_int16((unsigned char)0xF2, (0xC0 | encode));
6932
}
6933
6934
void Assembler::vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
6935
assert(UseAVX > 0, "requires some form of AVX");
6936
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6937
attributes.set_rex_vex_w_reverted();
6938
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6939
emit_int16((unsigned char)0xF3, (0xC0 | encode));
6940
}
6941
6942
// Shift packed integers logically right by specified number of bits.
6943
void Assembler::psrlw(XMMRegister dst, int shift) {
6944
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6945
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6946
// XMM2 is for /2 encoding: 66 0F 71 /2 ib
6947
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6948
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6949
}
6950
6951
void Assembler::psrld(XMMRegister dst, int shift) {
6952
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6953
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6954
// XMM2 is for /2 encoding: 66 0F 72 /2 ib
6955
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6956
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
6957
}
6958
6959
void Assembler::psrlq(XMMRegister dst, int shift) {
6960
// Do not confuse it with psrldq SSE2 instruction which
6961
// shifts 128 bit value in xmm register by number of bytes.
6962
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6963
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6964
attributes.set_rex_vex_w_reverted();
6965
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
6966
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6967
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
6968
}
6969
6970
void Assembler::psrlw(XMMRegister dst, XMMRegister shift) {
6971
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6972
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6973
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6974
emit_int16((unsigned char)0xD1, (0xC0 | encode));
6975
}
6976
6977
void Assembler::psrld(XMMRegister dst, XMMRegister shift) {
6978
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6979
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6980
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6981
emit_int16((unsigned char)0xD2, (0xC0 | encode));
6982
}
6983
6984
void Assembler::psrlq(XMMRegister dst, XMMRegister shift) {
6985
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6986
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6987
attributes.set_rex_vex_w_reverted();
6988
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6989
emit_int16((unsigned char)0xD3, (0xC0 | encode));
6990
}
6991
6992
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6993
assert(UseAVX > 0, "requires some form of AVX");
6994
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6995
// XMM2 is for /2 encoding: 66 0F 71 /2 ib
6996
int encode = vex_prefix_and_encode(xmm2->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6997
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6998
}
6999
7000
void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7001
assert(UseAVX > 0, "requires some form of AVX");
7002
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7003
// XMM2 is for /2 encoding: 66 0F 72 /2 ib
7004
int encode = vex_prefix_and_encode(xmm2->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7005
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7006
}
7007
7008
void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7009
assert(UseAVX > 0, "requires some form of AVX");
7010
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7011
attributes.set_rex_vex_w_reverted();
7012
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
7013
int encode = vex_prefix_and_encode(xmm2->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7014
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
7015
}
7016
7017
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7018
assert(UseAVX > 0, "requires some form of AVX");
7019
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7020
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7021
emit_int16((unsigned char)0xD1, (0xC0 | encode));
7022
}
7023
7024
void Assembler::vpsrld(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7025
assert(UseAVX > 0, "requires some form of AVX");
7026
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7027
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7028
emit_int16((unsigned char)0xD2, (0xC0 | encode));
7029
}
7030
7031
void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7032
assert(UseAVX > 0, "requires some form of AVX");
7033
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7034
attributes.set_rex_vex_w_reverted();
7035
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7036
emit_int16((unsigned char)0xD3, (0xC0 | encode));
7037
}
7038
7039
void Assembler::evpsrlvw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7040
assert(VM_Version::supports_avx512bw(), "");
7041
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7042
attributes.set_is_evex_instruction();
7043
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7044
emit_int16(0x10, (0xC0 | encode));
7045
}
7046
7047
void Assembler::evpsllvw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7048
assert(VM_Version::supports_avx512bw(), "");
7049
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7050
attributes.set_is_evex_instruction();
7051
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7052
emit_int16(0x12, (0xC0 | encode));
7053
}
7054
7055
// Shift packed integers arithmetically right by specified number of bits.
7056
void Assembler::psraw(XMMRegister dst, int shift) {
7057
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7058
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7059
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
7060
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7061
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
7062
}
7063
7064
void Assembler::psrad(XMMRegister dst, int shift) {
7065
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7066
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7067
// XMM4 is for /4 encoding: 66 0F 72 /4 ib
7068
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7069
emit_int8(0x72);
7070
emit_int8((0xC0 | encode));
7071
emit_int8(shift & 0xFF);
7072
}
7073
7074
void Assembler::psraw(XMMRegister dst, XMMRegister shift) {
7075
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7076
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7077
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7078
emit_int16((unsigned char)0xE1, (0xC0 | encode));
7079
}
7080
7081
void Assembler::psrad(XMMRegister dst, XMMRegister shift) {
7082
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7083
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7084
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7085
emit_int16((unsigned char)0xE2, (0xC0 | encode));
7086
}
7087
7088
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7089
assert(UseAVX > 0, "requires some form of AVX");
7090
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7091
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
7092
int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7093
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
7094
}
7095
7096
void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7097
assert(UseAVX > 0, "requires some form of AVX");
7098
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7099
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
7100
int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7101
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7102
}
7103
7104
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7105
assert(UseAVX > 0, "requires some form of AVX");
7106
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7107
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7108
emit_int16((unsigned char)0xE1, (0xC0 | encode));
7109
}
7110
7111
void Assembler::vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7112
assert(UseAVX > 0, "requires some form of AVX");
7113
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7114
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7115
emit_int16((unsigned char)0xE2, (0xC0 | encode));
7116
}
7117
7118
void Assembler::evpsraq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7119
assert(UseAVX > 2, "requires AVX512");
7120
assert ((VM_Version::supports_avx512vl() || vector_len == 2), "requires AVX512vl");
7121
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7122
attributes.set_is_evex_instruction();
7123
int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7124
emit_int24((unsigned char)0x72, (0xC0 | encode), shift & 0xFF);
7125
}
7126
7127
void Assembler::evpsraq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7128
assert(UseAVX > 2, "requires AVX512");
7129
assert ((VM_Version::supports_avx512vl() || vector_len == 2), "requires AVX512vl");
7130
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7131
attributes.set_is_evex_instruction();
7132
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7133
emit_int16((unsigned char)0xE2, (0xC0 | encode));
7134
}
7135
7136
// logical operations packed integers
7137
void Assembler::pand(XMMRegister dst, XMMRegister src) {
7138
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7139
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7140
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7141
emit_int16((unsigned char)0xDB, (0xC0 | encode));
7142
}
7143
7144
void Assembler::vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7145
assert(UseAVX > 0, "requires some form of AVX");
7146
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7147
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7148
emit_int16((unsigned char)0xDB, (0xC0 | encode));
7149
}
7150
7151
void Assembler::vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7152
assert(UseAVX > 0, "requires some form of AVX");
7153
InstructionMark im(this);
7154
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7155
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
7156
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7157
emit_int8((unsigned char)0xDB);
7158
emit_operand(dst, src);
7159
}
7160
7161
void Assembler::vpandq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7162
assert(VM_Version::supports_evex(), "");
7163
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7164
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7165
emit_int16((unsigned char)0xDB, (0xC0 | encode));
7166
}
7167
7168
//Variable Shift packed integers logically left.
7169
void Assembler::vpsllvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7170
assert(UseAVX > 1, "requires AVX2");
7171
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7172
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7173
emit_int16(0x47, (0xC0 | encode));
7174
}
7175
7176
void Assembler::vpsllvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7177
assert(UseAVX > 1, "requires AVX2");
7178
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7179
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7180
emit_int16(0x47, (0xC0 | encode));
7181
}
7182
7183
//Variable Shift packed integers logically right.
7184
void Assembler::vpsrlvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7185
assert(UseAVX > 1, "requires AVX2");
7186
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7187
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7188
emit_int16(0x45, (0xC0 | encode));
7189
}
7190
7191
void Assembler::vpsrlvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7192
assert(UseAVX > 1, "requires AVX2");
7193
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7194
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7195
emit_int16(0x45, (0xC0 | encode));
7196
}
7197
7198
//Variable right Shift arithmetic packed integers .
7199
void Assembler::vpsravd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7200
assert(UseAVX > 1, "requires AVX2");
7201
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7202
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7203
emit_int16(0x46, (0xC0 | encode));
7204
}
7205
7206
void Assembler::evpsravw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7207
assert(VM_Version::supports_avx512bw(), "");
7208
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7209
attributes.set_is_evex_instruction();
7210
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7211
emit_int16(0x11, (0xC0 | encode));
7212
}
7213
7214
void Assembler::evpsravq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7215
assert(UseAVX > 2, "requires AVX512");
7216
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires AVX512VL");
7217
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7218
attributes.set_is_evex_instruction();
7219
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7220
emit_int16(0x46, (0xC0 | encode));
7221
}
7222
7223
void Assembler::vpshldvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7224
assert(VM_Version::supports_avx512_vbmi2(), "requires vbmi2");
7225
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7226
attributes.set_is_evex_instruction();
7227
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7228
emit_int16(0x71, (0xC0 | encode));
7229
}
7230
7231
void Assembler::vpshrdvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7232
assert(VM_Version::supports_avx512_vbmi2(), "requires vbmi2");
7233
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7234
attributes.set_is_evex_instruction();
7235
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7236
emit_int16(0x73, (0xC0 | encode));
7237
}
7238
7239
void Assembler::pandn(XMMRegister dst, XMMRegister src) {
7240
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7241
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7242
attributes.set_rex_vex_w_reverted();
7243
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7244
emit_int16((unsigned char)0xDF, (0xC0 | encode));
7245
}
7246
7247
void Assembler::vpandn(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7248
assert(UseAVX > 0, "requires some form of AVX");
7249
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7250
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7251
emit_int16((unsigned char)0xDF, (0xC0 | encode));
7252
}
7253
7254
void Assembler::por(XMMRegister dst, XMMRegister src) {
7255
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7256
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7257
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7258
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7259
}
7260
7261
void Assembler::vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7262
assert(UseAVX > 0, "requires some form of AVX");
7263
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7264
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7265
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7266
}
7267
7268
void Assembler::vpor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7269
assert(UseAVX > 0, "requires some form of AVX");
7270
InstructionMark im(this);
7271
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7272
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
7273
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7274
emit_int8((unsigned char)0xEB);
7275
emit_operand(dst, src);
7276
}
7277
7278
void Assembler::vporq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7279
assert(VM_Version::supports_evex(), "");
7280
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7281
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7282
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7283
}
7284
7285
7286
void Assembler::evpord(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
7287
assert(VM_Version::supports_evex(), "");
7288
// Encoding: EVEX.NDS.XXX.66.0F.W0 EB /r
7289
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
7290
attributes.set_is_evex_instruction();
7291
attributes.set_embedded_opmask_register_specifier(mask);
7292
if (merge) {
7293
attributes.reset_is_clear_context();
7294
}
7295
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7296
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7297
}
7298
7299
void Assembler::evpord(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
7300
assert(VM_Version::supports_evex(), "");
7301
// Encoding: EVEX.NDS.XXX.66.0F.W0 EB /r
7302
InstructionMark im(this);
7303
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
7304
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
7305
attributes.set_is_evex_instruction();
7306
attributes.set_embedded_opmask_register_specifier(mask);
7307
if (merge) {
7308
attributes.reset_is_clear_context();
7309
}
7310
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7311
emit_int8((unsigned char)0xEB);
7312
emit_operand(dst, src);
7313
}
7314
7315
void Assembler::pxor(XMMRegister dst, XMMRegister src) {
7316
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7317
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7318
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7319
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7320
}
7321
7322
void Assembler::vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7323
assert(UseAVX > 0, "requires some form of AVX");
7324
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7325
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7326
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7327
}
7328
7329
void Assembler::vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7330
assert(UseAVX > 0, "requires some form of AVX");
7331
InstructionMark im(this);
7332
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7333
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
7334
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7335
emit_int8((unsigned char)0xEF);
7336
emit_operand(dst, src);
7337
}
7338
7339
void Assembler::vpxorq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7340
assert(UseAVX > 2, "requires some form of EVEX");
7341
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7342
attributes.set_rex_vex_w_reverted();
7343
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7344
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7345
}
7346
7347
void Assembler::evpxord(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
7348
assert(VM_Version::supports_evex(), "");
7349
// Encoding: EVEX.NDS.XXX.66.0F.W0 EF /r
7350
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
7351
attributes.set_is_evex_instruction();
7352
attributes.set_embedded_opmask_register_specifier(mask);
7353
if (merge) {
7354
attributes.reset_is_clear_context();
7355
}
7356
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7357
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7358
}
7359
7360
void Assembler::evpxorq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7361
assert(VM_Version::supports_evex(), "requires EVEX support");
7362
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7363
attributes.set_is_evex_instruction();
7364
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7365
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7366
}
7367
7368
void Assembler::evpxorq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7369
assert(VM_Version::supports_evex(), "requires EVEX support");
7370
assert(dst != xnoreg, "sanity");
7371
InstructionMark im(this);
7372
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7373
attributes.set_is_evex_instruction();
7374
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
7375
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7376
emit_int8((unsigned char)0xEF);
7377
emit_operand(dst, src);
7378
}
7379
7380
void Assembler::evprold(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7381
assert(VM_Version::supports_evex(), "requires EVEX support");
7382
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7383
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7384
attributes.set_is_evex_instruction();
7385
int encode = vex_prefix_and_encode(xmm1->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7386
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7387
}
7388
7389
void Assembler::evprolq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7390
assert(VM_Version::supports_evex(), "requires EVEX support");
7391
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7392
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7393
attributes.set_is_evex_instruction();
7394
int encode = vex_prefix_and_encode(xmm1->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7395
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7396
}
7397
7398
void Assembler::evprord(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7399
assert(VM_Version::supports_evex(), "requires EVEX support");
7400
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7401
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7402
attributes.set_is_evex_instruction();
7403
int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7404
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7405
}
7406
7407
void Assembler::evprorq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7408
assert(VM_Version::supports_evex(), "requires EVEX support");
7409
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7410
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7411
attributes.set_is_evex_instruction();
7412
int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7413
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7414
}
7415
7416
void Assembler::evprolvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7417
assert(VM_Version::supports_evex(), "requires EVEX support");
7418
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7419
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7420
attributes.set_is_evex_instruction();
7421
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7422
emit_int16(0x15, (unsigned char)(0xC0 | encode));
7423
}
7424
7425
void Assembler::evprolvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7426
assert(VM_Version::supports_evex(), "requires EVEX support");
7427
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7428
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7429
attributes.set_is_evex_instruction();
7430
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7431
emit_int16(0x15, (unsigned char)(0xC0 | encode));
7432
}
7433
7434
void Assembler::evprorvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7435
assert(VM_Version::supports_evex(), "requires EVEX support");
7436
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7437
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7438
attributes.set_is_evex_instruction();
7439
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7440
emit_int16(0x14, (unsigned char)(0xC0 | encode));
7441
}
7442
7443
void Assembler::evprorvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7444
assert(VM_Version::supports_evex(), "requires EVEX support");
7445
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7446
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7447
attributes.set_is_evex_instruction();
7448
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7449
emit_int16(0x14, (unsigned char)(0xC0 | encode));
7450
}
7451
7452
void Assembler::vpternlogd(XMMRegister dst, int imm8, XMMRegister src2, XMMRegister src3, int vector_len) {
7453
assert(VM_Version::supports_evex(), "requires EVEX support");
7454
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7455
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7456
attributes.set_is_evex_instruction();
7457
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src3->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7458
emit_int8(0x25);
7459
emit_int8((unsigned char)(0xC0 | encode));
7460
emit_int8(imm8);
7461
}
7462
7463
void Assembler::vpternlogd(XMMRegister dst, int imm8, XMMRegister src2, Address src3, int vector_len) {
7464
assert(VM_Version::supports_evex(), "requires EVEX support");
7465
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7466
assert(dst != xnoreg, "sanity");
7467
InstructionMark im(this);
7468
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7469
attributes.set_is_evex_instruction();
7470
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
7471
vex_prefix(src3, src2->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7472
emit_int8(0x25);
7473
emit_operand(dst, src3);
7474
emit_int8(imm8);
7475
}
7476
7477
void Assembler::vpternlogq(XMMRegister dst, int imm8, XMMRegister src2, XMMRegister src3, int vector_len) {
7478
assert(VM_Version::supports_evex(), "requires EVEX support");
7479
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7480
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7481
attributes.set_is_evex_instruction();
7482
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src3->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7483
emit_int8(0x25);
7484
emit_int8((unsigned char)(0xC0 | encode));
7485
emit_int8(imm8);
7486
}
7487
7488
// vinserti forms
7489
7490
void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7491
assert(VM_Version::supports_avx2(), "");
7492
assert(imm8 <= 0x01, "imm8: %u", imm8);
7493
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7494
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7495
// last byte:
7496
// 0x00 - insert into lower 128 bits
7497
// 0x01 - insert into upper 128 bits
7498
emit_int24(0x38, (0xC0 | encode), imm8 & 0x01);
7499
}
7500
7501
void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7502
assert(VM_Version::supports_avx2(), "");
7503
assert(dst != xnoreg, "sanity");
7504
assert(imm8 <= 0x01, "imm8: %u", imm8);
7505
InstructionMark im(this);
7506
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7507
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7508
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7509
emit_int8(0x38);
7510
emit_operand(dst, src);
7511
// 0x00 - insert into lower 128 bits
7512
// 0x01 - insert into upper 128 bits
7513
emit_int8(imm8 & 0x01);
7514
}
7515
7516
void Assembler::vinserti32x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7517
assert(VM_Version::supports_evex(), "");
7518
assert(imm8 <= 0x03, "imm8: %u", imm8);
7519
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7520
attributes.set_is_evex_instruction();
7521
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7522
// imm8:
7523
// 0x00 - insert into q0 128 bits (0..127)
7524
// 0x01 - insert into q1 128 bits (128..255)
7525
// 0x02 - insert into q2 128 bits (256..383)
7526
// 0x03 - insert into q3 128 bits (384..511)
7527
emit_int24(0x38, (0xC0 | encode), imm8 & 0x03);
7528
}
7529
7530
void Assembler::vinserti32x4(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7531
assert(VM_Version::supports_avx(), "");
7532
assert(dst != xnoreg, "sanity");
7533
assert(imm8 <= 0x03, "imm8: %u", imm8);
7534
InstructionMark im(this);
7535
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7536
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7537
attributes.set_is_evex_instruction();
7538
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7539
emit_int8(0x18);
7540
emit_operand(dst, src);
7541
// 0x00 - insert into q0 128 bits (0..127)
7542
// 0x01 - insert into q1 128 bits (128..255)
7543
// 0x02 - insert into q2 128 bits (256..383)
7544
// 0x03 - insert into q3 128 bits (384..511)
7545
emit_int8(imm8 & 0x03);
7546
}
7547
7548
void Assembler::vinserti64x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7549
assert(VM_Version::supports_evex(), "");
7550
assert(imm8 <= 0x01, "imm8: %u", imm8);
7551
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7552
attributes.set_is_evex_instruction();
7553
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7554
//imm8:
7555
// 0x00 - insert into lower 256 bits
7556
// 0x01 - insert into upper 256 bits
7557
emit_int24(0x3A, (0xC0 | encode), imm8 & 0x01);
7558
}
7559
7560
7561
// vinsertf forms
7562
7563
void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7564
assert(VM_Version::supports_avx(), "");
7565
assert(imm8 <= 0x01, "imm8: %u", imm8);
7566
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7567
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7568
// imm8:
7569
// 0x00 - insert into lower 128 bits
7570
// 0x01 - insert into upper 128 bits
7571
emit_int24(0x18, (0xC0 | encode), imm8 & 0x01);
7572
}
7573
7574
void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7575
assert(VM_Version::supports_avx(), "");
7576
assert(dst != xnoreg, "sanity");
7577
assert(imm8 <= 0x01, "imm8: %u", imm8);
7578
InstructionMark im(this);
7579
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7580
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7581
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7582
emit_int8(0x18);
7583
emit_operand(dst, src);
7584
// 0x00 - insert into lower 128 bits
7585
// 0x01 - insert into upper 128 bits
7586
emit_int8(imm8 & 0x01);
7587
}
7588
7589
void Assembler::vinsertf32x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7590
assert(VM_Version::supports_avx2(), "");
7591
assert(imm8 <= 0x03, "imm8: %u", imm8);
7592
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7593
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7594
// imm8:
7595
// 0x00 - insert into q0 128 bits (0..127)
7596
// 0x01 - insert into q1 128 bits (128..255)
7597
// 0x02 - insert into q0 128 bits (256..383)
7598
// 0x03 - insert into q1 128 bits (384..512)
7599
emit_int24(0x18, (0xC0 | encode), imm8 & 0x03);
7600
}
7601
7602
void Assembler::vinsertf32x4(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7603
assert(VM_Version::supports_avx(), "");
7604
assert(dst != xnoreg, "sanity");
7605
assert(imm8 <= 0x03, "imm8: %u", imm8);
7606
InstructionMark im(this);
7607
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7608
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7609
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7610
emit_int8(0x18);
7611
emit_operand(dst, src);
7612
// 0x00 - insert into q0 128 bits (0..127)
7613
// 0x01 - insert into q1 128 bits (128..255)
7614
// 0x02 - insert into q0 128 bits (256..383)
7615
// 0x03 - insert into q1 128 bits (384..512)
7616
emit_int8(imm8 & 0x03);
7617
}
7618
7619
void Assembler::vinsertf64x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7620
assert(VM_Version::supports_evex(), "");
7621
assert(imm8 <= 0x01, "imm8: %u", imm8);
7622
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7623
attributes.set_is_evex_instruction();
7624
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7625
// imm8:
7626
// 0x00 - insert into lower 256 bits
7627
// 0x01 - insert into upper 256 bits
7628
emit_int24(0x1A, (0xC0 | encode), imm8 & 0x01);
7629
}
7630
7631
void Assembler::vinsertf64x4(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7632
assert(VM_Version::supports_evex(), "");
7633
assert(dst != xnoreg, "sanity");
7634
assert(imm8 <= 0x01, "imm8: %u", imm8);
7635
InstructionMark im(this);
7636
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7637
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_64bit);
7638
attributes.set_is_evex_instruction();
7639
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7640
emit_int8(0x1A);
7641
emit_operand(dst, src);
7642
// 0x00 - insert into lower 256 bits
7643
// 0x01 - insert into upper 256 bits
7644
emit_int8(imm8 & 0x01);
7645
}
7646
7647
7648
// vextracti forms
7649
7650
void Assembler::vextracti128(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7651
assert(VM_Version::supports_avx2(), "");
7652
assert(imm8 <= 0x01, "imm8: %u", imm8);
7653
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7654
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7655
// imm8:
7656
// 0x00 - extract from lower 128 bits
7657
// 0x01 - extract from upper 128 bits
7658
emit_int24(0x39, (0xC0 | encode), imm8 & 0x01);
7659
}
7660
7661
void Assembler::vextracti128(Address dst, XMMRegister src, uint8_t imm8) {
7662
assert(VM_Version::supports_avx2(), "");
7663
assert(src != xnoreg, "sanity");
7664
assert(imm8 <= 0x01, "imm8: %u", imm8);
7665
InstructionMark im(this);
7666
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7667
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7668
attributes.reset_is_clear_context();
7669
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7670
emit_int8(0x39);
7671
emit_operand(src, dst);
7672
// 0x00 - extract from lower 128 bits
7673
// 0x01 - extract from upper 128 bits
7674
emit_int8(imm8 & 0x01);
7675
}
7676
7677
void Assembler::vextracti32x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7678
assert(VM_Version::supports_evex(), "");
7679
assert(imm8 <= 0x03, "imm8: %u", imm8);
7680
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7681
attributes.set_is_evex_instruction();
7682
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7683
// imm8:
7684
// 0x00 - extract from bits 127:0
7685
// 0x01 - extract from bits 255:128
7686
// 0x02 - extract from bits 383:256
7687
// 0x03 - extract from bits 511:384
7688
emit_int24(0x39, (0xC0 | encode), imm8 & 0x03);
7689
}
7690
7691
void Assembler::vextracti32x4(Address dst, XMMRegister src, uint8_t imm8) {
7692
assert(VM_Version::supports_evex(), "");
7693
assert(src != xnoreg, "sanity");
7694
assert(imm8 <= 0x03, "imm8: %u", imm8);
7695
InstructionMark im(this);
7696
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7697
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7698
attributes.reset_is_clear_context();
7699
attributes.set_is_evex_instruction();
7700
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7701
emit_int8(0x39);
7702
emit_operand(src, dst);
7703
// 0x00 - extract from bits 127:0
7704
// 0x01 - extract from bits 255:128
7705
// 0x02 - extract from bits 383:256
7706
// 0x03 - extract from bits 511:384
7707
emit_int8(imm8 & 0x03);
7708
}
7709
7710
void Assembler::vextracti64x2(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7711
assert(VM_Version::supports_avx512dq(), "");
7712
assert(imm8 <= 0x03, "imm8: %u", imm8);
7713
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7714
attributes.set_is_evex_instruction();
7715
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7716
// imm8:
7717
// 0x00 - extract from bits 127:0
7718
// 0x01 - extract from bits 255:128
7719
// 0x02 - extract from bits 383:256
7720
// 0x03 - extract from bits 511:384
7721
emit_int24(0x39, (0xC0 | encode), imm8 & 0x03);
7722
}
7723
7724
void Assembler::vextracti64x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7725
assert(VM_Version::supports_evex(), "");
7726
assert(imm8 <= 0x01, "imm8: %u", imm8);
7727
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7728
attributes.set_is_evex_instruction();
7729
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7730
// imm8:
7731
// 0x00 - extract from lower 256 bits
7732
// 0x01 - extract from upper 256 bits
7733
emit_int24(0x3B, (0xC0 | encode), imm8 & 0x01);
7734
}
7735
7736
void Assembler::vextracti64x4(Address dst, XMMRegister src, uint8_t imm8) {
7737
assert(VM_Version::supports_evex(), "");
7738
assert(src != xnoreg, "sanity");
7739
assert(imm8 <= 0x01, "imm8: %u", imm8);
7740
InstructionMark im(this);
7741
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7742
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_64bit);
7743
attributes.reset_is_clear_context();
7744
attributes.set_is_evex_instruction();
7745
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7746
emit_int8(0x38);
7747
emit_operand(src, dst);
7748
// 0x00 - extract from lower 256 bits
7749
// 0x01 - extract from upper 256 bits
7750
emit_int8(imm8 & 0x01);
7751
}
7752
// vextractf forms
7753
7754
void Assembler::vextractf128(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7755
assert(VM_Version::supports_avx(), "");
7756
assert(imm8 <= 0x01, "imm8: %u", imm8);
7757
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7758
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7759
// imm8:
7760
// 0x00 - extract from lower 128 bits
7761
// 0x01 - extract from upper 128 bits
7762
emit_int24(0x19, (0xC0 | encode), imm8 & 0x01);
7763
}
7764
7765
void Assembler::vextractf128(Address dst, XMMRegister src, uint8_t imm8) {
7766
assert(VM_Version::supports_avx(), "");
7767
assert(src != xnoreg, "sanity");
7768
assert(imm8 <= 0x01, "imm8: %u", imm8);
7769
InstructionMark im(this);
7770
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7771
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7772
attributes.reset_is_clear_context();
7773
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7774
emit_int8(0x19);
7775
emit_operand(src, dst);
7776
// 0x00 - extract from lower 128 bits
7777
// 0x01 - extract from upper 128 bits
7778
emit_int8(imm8 & 0x01);
7779
}
7780
7781
void Assembler::vextractf32x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7782
assert(VM_Version::supports_evex(), "");
7783
assert(imm8 <= 0x03, "imm8: %u", imm8);
7784
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7785
attributes.set_is_evex_instruction();
7786
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7787
// imm8:
7788
// 0x00 - extract from bits 127:0
7789
// 0x01 - extract from bits 255:128
7790
// 0x02 - extract from bits 383:256
7791
// 0x03 - extract from bits 511:384
7792
emit_int24(0x19, (0xC0 | encode), imm8 & 0x03);
7793
}
7794
7795
void Assembler::vextractf32x4(Address dst, XMMRegister src, uint8_t imm8) {
7796
assert(VM_Version::supports_evex(), "");
7797
assert(src != xnoreg, "sanity");
7798
assert(imm8 <= 0x03, "imm8: %u", imm8);
7799
InstructionMark im(this);
7800
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7801
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7802
attributes.reset_is_clear_context();
7803
attributes.set_is_evex_instruction();
7804
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7805
emit_int8(0x19);
7806
emit_operand(src, dst);
7807
// 0x00 - extract from bits 127:0
7808
// 0x01 - extract from bits 255:128
7809
// 0x02 - extract from bits 383:256
7810
// 0x03 - extract from bits 511:384
7811
emit_int8(imm8 & 0x03);
7812
}
7813
7814
void Assembler::vextractf64x2(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7815
assert(VM_Version::supports_avx512dq(), "");
7816
assert(imm8 <= 0x03, "imm8: %u", imm8);
7817
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7818
attributes.set_is_evex_instruction();
7819
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7820
// imm8:
7821
// 0x00 - extract from bits 127:0
7822
// 0x01 - extract from bits 255:128
7823
// 0x02 - extract from bits 383:256
7824
// 0x03 - extract from bits 511:384
7825
emit_int24(0x19, (0xC0 | encode), imm8 & 0x03);
7826
}
7827
7828
void Assembler::vextractf64x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7829
assert(VM_Version::supports_evex(), "");
7830
assert(imm8 <= 0x01, "imm8: %u", imm8);
7831
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7832
attributes.set_is_evex_instruction();
7833
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7834
// imm8:
7835
// 0x00 - extract from lower 256 bits
7836
// 0x01 - extract from upper 256 bits
7837
emit_int24(0x1B, (0xC0 | encode), imm8 & 0x01);
7838
}
7839
7840
void Assembler::vextractf64x4(Address dst, XMMRegister src, uint8_t imm8) {
7841
assert(VM_Version::supports_evex(), "");
7842
assert(src != xnoreg, "sanity");
7843
assert(imm8 <= 0x01, "imm8: %u", imm8);
7844
InstructionMark im(this);
7845
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7846
attributes.set_address_attributes(/* tuple_type */ EVEX_T4,/* input_size_in_bits */ EVEX_64bit);
7847
attributes.reset_is_clear_context();
7848
attributes.set_is_evex_instruction();
7849
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7850
emit_int8(0x1B);
7851
emit_operand(src, dst);
7852
// 0x00 - extract from lower 256 bits
7853
// 0x01 - extract from upper 256 bits
7854
emit_int8(imm8 & 0x01);
7855
}
7856
7857
// duplicate 1-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
7858
void Assembler::vpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len) {
7859
assert(VM_Version::supports_avx2(), "");
7860
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7861
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7862
emit_int16(0x78, (0xC0 | encode));
7863
}
7864
7865
void Assembler::vpbroadcastb(XMMRegister dst, Address src, int vector_len) {
7866
assert(VM_Version::supports_avx2(), "");
7867
assert(dst != xnoreg, "sanity");
7868
InstructionMark im(this);
7869
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7870
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_8bit);
7871
// swap src<->dst for encoding
7872
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7873
emit_int8(0x78);
7874
emit_operand(dst, src);
7875
}
7876
7877
// duplicate 2-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
7878
void Assembler::vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len) {
7879
assert(VM_Version::supports_avx2(), "");
7880
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7881
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7882
emit_int16(0x79, (0xC0 | encode));
7883
}
7884
7885
void Assembler::vpbroadcastw(XMMRegister dst, Address src, int vector_len) {
7886
assert(VM_Version::supports_avx2(), "");
7887
assert(dst != xnoreg, "sanity");
7888
InstructionMark im(this);
7889
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7890
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_16bit);
7891
// swap src<->dst for encoding
7892
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7893
emit_int8(0x79);
7894
emit_operand(dst, src);
7895
}
7896
7897
// xmm/mem sourced byte/word/dword/qword replicate
7898
7899
// duplicate 4-byte integer data from src into programmed locations in dest : requires AVX512VL
7900
void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) {
7901
assert(UseAVX >= 2, "");
7902
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7903
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7904
emit_int16(0x58, (0xC0 | encode));
7905
}
7906
7907
void Assembler::vpbroadcastd(XMMRegister dst, Address src, int vector_len) {
7908
assert(VM_Version::supports_avx2(), "");
7909
assert(dst != xnoreg, "sanity");
7910
InstructionMark im(this);
7911
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7912
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
7913
// swap src<->dst for encoding
7914
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7915
emit_int8(0x58);
7916
emit_operand(dst, src);
7917
}
7918
7919
// duplicate 8-byte integer data from src into programmed locations in dest : requires AVX512VL
7920
void Assembler::vpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len) {
7921
assert(VM_Version::supports_avx2(), "");
7922
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7923
attributes.set_rex_vex_w_reverted();
7924
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7925
emit_int16(0x59, (0xC0 | encode));
7926
}
7927
7928
void Assembler::vpbroadcastq(XMMRegister dst, Address src, int vector_len) {
7929
assert(VM_Version::supports_avx2(), "");
7930
assert(dst != xnoreg, "sanity");
7931
InstructionMark im(this);
7932
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7933
attributes.set_rex_vex_w_reverted();
7934
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
7935
// swap src<->dst for encoding
7936
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7937
emit_int8(0x59);
7938
emit_operand(dst, src);
7939
}
7940
7941
void Assembler::evbroadcasti32x4(XMMRegister dst, Address src, int vector_len) {
7942
assert(vector_len != Assembler::AVX_128bit, "");
7943
assert(VM_Version::supports_avx512dq(), "");
7944
assert(dst != xnoreg, "sanity");
7945
InstructionMark im(this);
7946
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7947
attributes.set_rex_vex_w_reverted();
7948
attributes.set_address_attributes(/* tuple_type */ EVEX_T2, /* input_size_in_bits */ EVEX_64bit);
7949
// swap src<->dst for encoding
7950
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7951
emit_int8(0x5A);
7952
emit_operand(dst, src);
7953
}
7954
7955
void Assembler::evbroadcasti64x2(XMMRegister dst, XMMRegister src, int vector_len) {
7956
assert(vector_len != Assembler::AVX_128bit, "");
7957
assert(VM_Version::supports_avx512dq(), "");
7958
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7959
attributes.set_rex_vex_w_reverted();
7960
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7961
emit_int16(0x5A, (0xC0 | encode));
7962
}
7963
7964
void Assembler::evbroadcasti64x2(XMMRegister dst, Address src, int vector_len) {
7965
assert(vector_len != Assembler::AVX_128bit, "");
7966
assert(VM_Version::supports_avx512dq(), "");
7967
assert(dst != xnoreg, "sanity");
7968
InstructionMark im(this);
7969
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7970
attributes.set_rex_vex_w_reverted();
7971
attributes.set_address_attributes(/* tuple_type */ EVEX_T2, /* input_size_in_bits */ EVEX_64bit);
7972
// swap src<->dst for encoding
7973
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7974
emit_int8(0x5A);
7975
emit_operand(dst, src);
7976
}
7977
7978
// scalar single/double precision replicate
7979
7980
// duplicate single precision data from src into programmed locations in dest : requires AVX512VL
7981
void Assembler::vbroadcastss(XMMRegister dst, XMMRegister src, int vector_len) {
7982
assert(VM_Version::supports_avx2(), "");
7983
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7984
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7985
emit_int16(0x18, (0xC0 | encode));
7986
}
7987
7988
void Assembler::vbroadcastss(XMMRegister dst, Address src, int vector_len) {
7989
assert(VM_Version::supports_avx(), "");
7990
assert(dst != xnoreg, "sanity");
7991
InstructionMark im(this);
7992
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7993
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
7994
// swap src<->dst for encoding
7995
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7996
emit_int8(0x18);
7997
emit_operand(dst, src);
7998
}
7999
8000
// duplicate double precision data from src into programmed locations in dest : requires AVX512VL
8001
void Assembler::vbroadcastsd(XMMRegister dst, XMMRegister src, int vector_len) {
8002
assert(VM_Version::supports_avx2(), "");
8003
assert(vector_len == AVX_256bit || vector_len == AVX_512bit, "");
8004
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8005
attributes.set_rex_vex_w_reverted();
8006
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8007
emit_int16(0x19, (0xC0 | encode));
8008
}
8009
8010
void Assembler::vbroadcastsd(XMMRegister dst, Address src, int vector_len) {
8011
assert(VM_Version::supports_avx(), "");
8012
assert(vector_len == AVX_256bit || vector_len == AVX_512bit, "");
8013
assert(dst != xnoreg, "sanity");
8014
InstructionMark im(this);
8015
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8016
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
8017
attributes.set_rex_vex_w_reverted();
8018
// swap src<->dst for encoding
8019
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8020
emit_int8(0x19);
8021
emit_operand(dst, src);
8022
}
8023
8024
void Assembler::vbroadcastf128(XMMRegister dst, Address src, int vector_len) {
8025
assert(VM_Version::supports_avx(), "");
8026
assert(vector_len == AVX_256bit, "");
8027
assert(dst != xnoreg, "sanity");
8028
InstructionMark im(this);
8029
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8030
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
8031
// swap src<->dst for encoding
8032
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8033
emit_int8(0x1A);
8034
emit_operand(dst, src);
8035
}
8036
8037
// gpr source broadcast forms
8038
8039
// duplicate 1-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
8040
void Assembler::evpbroadcastb(XMMRegister dst, Register src, int vector_len) {
8041
assert(VM_Version::supports_avx512bw(), "");
8042
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
8043
attributes.set_is_evex_instruction();
8044
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8045
emit_int16(0x7A, (0xC0 | encode));
8046
}
8047
8048
// duplicate 2-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
8049
void Assembler::evpbroadcastw(XMMRegister dst, Register src, int vector_len) {
8050
assert(VM_Version::supports_avx512bw(), "");
8051
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
8052
attributes.set_is_evex_instruction();
8053
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8054
emit_int16(0x7B, (0xC0 | encode));
8055
}
8056
8057
// duplicate 4-byte integer data from src into programmed locations in dest : requires AVX512VL
8058
void Assembler::evpbroadcastd(XMMRegister dst, Register src, int vector_len) {
8059
assert(VM_Version::supports_evex(), "");
8060
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8061
attributes.set_is_evex_instruction();
8062
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8063
emit_int16(0x7C, (0xC0 | encode));
8064
}
8065
8066
// duplicate 8-byte integer data from src into programmed locations in dest : requires AVX512VL
8067
void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) {
8068
assert(VM_Version::supports_evex(), "");
8069
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8070
attributes.set_is_evex_instruction();
8071
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8072
emit_int16(0x7C, (0xC0 | encode));
8073
}
8074
8075
void Assembler::vpgatherdd(XMMRegister dst, Address src, XMMRegister mask, int vector_len) {
8076
assert(VM_Version::supports_avx2(), "");
8077
assert(vector_len == Assembler::AVX_128bit || vector_len == Assembler::AVX_256bit, "");
8078
assert(dst != xnoreg, "sanity");
8079
assert(src.isxmmindex(),"expected to be xmm index");
8080
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8081
InstructionMark im(this);
8082
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8083
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8084
emit_int8((unsigned char)0x90);
8085
emit_operand(dst, src);
8086
}
8087
8088
void Assembler::vpgatherdq(XMMRegister dst, Address src, XMMRegister mask, int vector_len) {
8089
assert(VM_Version::supports_avx2(), "");
8090
assert(vector_len == Assembler::AVX_128bit || vector_len == Assembler::AVX_256bit, "");
8091
assert(dst != xnoreg, "sanity");
8092
assert(src.isxmmindex(),"expected to be xmm index");
8093
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8094
InstructionMark im(this);
8095
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8096
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8097
emit_int8((unsigned char)0x90);
8098
emit_operand(dst, src);
8099
}
8100
8101
void Assembler::vgatherdpd(XMMRegister dst, Address src, XMMRegister mask, int vector_len) {
8102
assert(VM_Version::supports_avx2(), "");
8103
assert(vector_len == Assembler::AVX_128bit || vector_len == Assembler::AVX_256bit, "");
8104
assert(dst != xnoreg, "sanity");
8105
assert(src.isxmmindex(),"expected to be xmm index");
8106
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8107
InstructionMark im(this);
8108
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8109
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8110
emit_int8((unsigned char)0x92);
8111
emit_operand(dst, src);
8112
}
8113
8114
void Assembler::vgatherdps(XMMRegister dst, Address src, XMMRegister mask, int vector_len) {
8115
assert(VM_Version::supports_avx2(), "");
8116
assert(vector_len == Assembler::AVX_128bit || vector_len == Assembler::AVX_256bit, "");
8117
assert(dst != xnoreg, "sanity");
8118
assert(src.isxmmindex(),"expected to be xmm index");
8119
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8120
InstructionMark im(this);
8121
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ true);
8122
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8123
emit_int8((unsigned char)0x92);
8124
emit_operand(dst, src);
8125
}
8126
void Assembler::evpgatherdd(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8127
assert(VM_Version::supports_evex(), "");
8128
assert(dst != xnoreg, "sanity");
8129
assert(src.isxmmindex(),"expected to be xmm index");
8130
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8131
assert(mask != k0, "instruction will #UD if mask is in k0");
8132
InstructionMark im(this);
8133
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8134
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8135
attributes.reset_is_clear_context();
8136
attributes.set_embedded_opmask_register_specifier(mask);
8137
attributes.set_is_evex_instruction();
8138
// swap src<->dst for encoding
8139
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8140
emit_int8((unsigned char)0x90);
8141
emit_operand(dst, src);
8142
}
8143
8144
void Assembler::evpgatherdq(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8145
assert(VM_Version::supports_evex(), "");
8146
assert(dst != xnoreg, "sanity");
8147
assert(src.isxmmindex(),"expected to be xmm index");
8148
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8149
assert(mask != k0, "instruction will #UD if mask is in k0");
8150
InstructionMark im(this);
8151
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8152
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8153
attributes.reset_is_clear_context();
8154
attributes.set_embedded_opmask_register_specifier(mask);
8155
attributes.set_is_evex_instruction();
8156
// swap src<->dst for encoding
8157
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8158
emit_int8((unsigned char)0x90);
8159
emit_operand(dst, src);
8160
}
8161
8162
void Assembler::evgatherdpd(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8163
assert(VM_Version::supports_evex(), "");
8164
assert(dst != xnoreg, "sanity");
8165
assert(src.isxmmindex(),"expected to be xmm index");
8166
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8167
assert(mask != k0, "instruction will #UD if mask is in k0");
8168
InstructionMark im(this);
8169
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8170
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8171
attributes.reset_is_clear_context();
8172
attributes.set_embedded_opmask_register_specifier(mask);
8173
attributes.set_is_evex_instruction();
8174
// swap src<->dst for encoding
8175
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8176
emit_int8((unsigned char)0x92);
8177
emit_operand(dst, src);
8178
}
8179
8180
void Assembler::evgatherdps(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8181
assert(VM_Version::supports_evex(), "");
8182
assert(dst != xnoreg, "sanity");
8183
assert(src.isxmmindex(),"expected to be xmm index");
8184
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8185
assert(mask != k0, "instruction will #UD if mask is in k0");
8186
InstructionMark im(this);
8187
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8188
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8189
attributes.reset_is_clear_context();
8190
attributes.set_embedded_opmask_register_specifier(mask);
8191
attributes.set_is_evex_instruction();
8192
// swap src<->dst for encoding
8193
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8194
emit_int8((unsigned char)0x92);
8195
emit_operand(dst, src);
8196
}
8197
8198
void Assembler::evpscatterdd(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8199
assert(VM_Version::supports_evex(), "");
8200
assert(mask != k0, "instruction will #UD if mask is in k0");
8201
InstructionMark im(this);
8202
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8203
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8204
attributes.reset_is_clear_context();
8205
attributes.set_embedded_opmask_register_specifier(mask);
8206
attributes.set_is_evex_instruction();
8207
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8208
emit_int8((unsigned char)0xA0);
8209
emit_operand(src, dst);
8210
}
8211
8212
void Assembler::evpscatterdq(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8213
assert(VM_Version::supports_evex(), "");
8214
assert(mask != k0, "instruction will #UD if mask is in k0");
8215
InstructionMark im(this);
8216
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8217
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8218
attributes.reset_is_clear_context();
8219
attributes.set_embedded_opmask_register_specifier(mask);
8220
attributes.set_is_evex_instruction();
8221
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8222
emit_int8((unsigned char)0xA0);
8223
emit_operand(src, dst);
8224
}
8225
8226
void Assembler::evscatterdps(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8227
assert(VM_Version::supports_evex(), "");
8228
assert(mask != k0, "instruction will #UD if mask is in k0");
8229
InstructionMark im(this);
8230
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8231
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8232
attributes.reset_is_clear_context();
8233
attributes.set_embedded_opmask_register_specifier(mask);
8234
attributes.set_is_evex_instruction();
8235
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8236
emit_int8((unsigned char)0xA2);
8237
emit_operand(src, dst);
8238
}
8239
8240
void Assembler::evscatterdpd(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8241
assert(VM_Version::supports_evex(), "");
8242
assert(mask != k0, "instruction will #UD if mask is in k0");
8243
InstructionMark im(this);
8244
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8245
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8246
attributes.reset_is_clear_context();
8247
attributes.set_embedded_opmask_register_specifier(mask);
8248
attributes.set_is_evex_instruction();
8249
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8250
emit_int8((unsigned char)0xA2);
8251
emit_operand(src, dst);
8252
}
8253
// Carry-Less Multiplication Quadword
8254
void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) {
8255
assert(VM_Version::supports_clmul(), "");
8256
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8257
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
8258
emit_int24(0x44, (0xC0 | encode), (unsigned char)mask);
8259
}
8260
8261
// Carry-Less Multiplication Quadword
8262
void Assembler::vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask) {
8263
assert(VM_Version::supports_avx() && VM_Version::supports_clmul(), "");
8264
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8265
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
8266
emit_int24(0x44, (0xC0 | encode), (unsigned char)mask);
8267
}
8268
8269
void Assembler::evpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask, int vector_len) {
8270
assert(VM_Version::supports_avx512_vpclmulqdq(), "Requires vector carryless multiplication support");
8271
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8272
attributes.set_is_evex_instruction();
8273
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
8274
emit_int24(0x44, (0xC0 | encode), (unsigned char)mask);
8275
}
8276
8277
void Assembler::vzeroupper_uncached() {
8278
if (VM_Version::supports_vzeroupper()) {
8279
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
8280
(void)vex_prefix_and_encode(0, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
8281
emit_int8(0x77);
8282
}
8283
}
8284
8285
void Assembler::fld_x(Address adr) {
8286
InstructionMark im(this);
8287
emit_int8((unsigned char)0xDB);
8288
emit_operand32(rbp, adr);
8289
}
8290
8291
void Assembler::fstp_x(Address adr) {
8292
InstructionMark im(this);
8293
emit_int8((unsigned char)0xDB);
8294
emit_operand32(rdi, adr);
8295
}
8296
8297
void Assembler::emit_operand32(Register reg, Address adr) {
8298
assert(reg->encoding() < 8, "no extended registers");
8299
assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers");
8300
emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp,
8301
adr._rspec);
8302
}
8303
8304
#ifndef _LP64
8305
// 32bit only pieces of the assembler
8306
8307
void Assembler::emms() {
8308
NOT_LP64(assert(VM_Version::supports_mmx(), ""));
8309
emit_int16(0x0F, 0x77);
8310
}
8311
8312
void Assembler::vzeroupper() {
8313
vzeroupper_uncached();
8314
}
8315
8316
void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) {
8317
// NO PREFIX AS NEVER 64BIT
8318
InstructionMark im(this);
8319
emit_int16((unsigned char)0x81, (0xF8 | src1->encoding()));
8320
emit_data(imm32, rspec, 0);
8321
}
8322
8323
void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) {
8324
// NO PREFIX AS NEVER 64BIT (not even 32bit versions of 64bit regs
8325
InstructionMark im(this);
8326
emit_int8((unsigned char)0x81);
8327
emit_operand(rdi, src1);
8328
emit_data(imm32, rspec, 0);
8329
}
8330
8331
// The 64-bit (32bit platform) cmpxchg compares the value at adr with the contents of rdx:rax,
8332
// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded
8333
// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise.
8334
void Assembler::cmpxchg8(Address adr) {
8335
InstructionMark im(this);
8336
emit_int16(0x0F, (unsigned char)0xC7);
8337
emit_operand(rcx, adr);
8338
}
8339
8340
void Assembler::decl(Register dst) {
8341
// Don't use it directly. Use MacroAssembler::decrementl() instead.
8342
emit_int8(0x48 | dst->encoding());
8343
}
8344
8345
// 64bit doesn't use the x87
8346
8347
void Assembler::emit_farith(int b1, int b2, int i) {
8348
assert(isByte(b1) && isByte(b2), "wrong opcode");
8349
assert(0 <= i && i < 8, "illegal stack offset");
8350
emit_int16(b1, b2 + i);
8351
}
8352
8353
void Assembler::fabs() {
8354
emit_int16((unsigned char)0xD9, (unsigned char)0xE1);
8355
}
8356
8357
void Assembler::fadd(int i) {
8358
emit_farith(0xD8, 0xC0, i);
8359
}
8360
8361
void Assembler::fadd_d(Address src) {
8362
InstructionMark im(this);
8363
emit_int8((unsigned char)0xDC);
8364
emit_operand32(rax, src);
8365
}
8366
8367
void Assembler::fadd_s(Address src) {
8368
InstructionMark im(this);
8369
emit_int8((unsigned char)0xD8);
8370
emit_operand32(rax, src);
8371
}
8372
8373
void Assembler::fadda(int i) {
8374
emit_farith(0xDC, 0xC0, i);
8375
}
8376
8377
void Assembler::faddp(int i) {
8378
emit_farith(0xDE, 0xC0, i);
8379
}
8380
8381
void Assembler::fchs() {
8382
emit_int16((unsigned char)0xD9, (unsigned char)0xE0);
8383
}
8384
8385
void Assembler::fcom(int i) {
8386
emit_farith(0xD8, 0xD0, i);
8387
}
8388
8389
void Assembler::fcomp(int i) {
8390
emit_farith(0xD8, 0xD8, i);
8391
}
8392
8393
void Assembler::fcomp_d(Address src) {
8394
InstructionMark im(this);
8395
emit_int8((unsigned char)0xDC);
8396
emit_operand32(rbx, src);
8397
}
8398
8399
void Assembler::fcomp_s(Address src) {
8400
InstructionMark im(this);
8401
emit_int8((unsigned char)0xD8);
8402
emit_operand32(rbx, src);
8403
}
8404
8405
void Assembler::fcompp() {
8406
emit_int16((unsigned char)0xDE, (unsigned char)0xD9);
8407
}
8408
8409
void Assembler::fcos() {
8410
emit_int16((unsigned char)0xD9, (unsigned char)0xFF);
8411
}
8412
8413
void Assembler::fdecstp() {
8414
emit_int16((unsigned char)0xD9, (unsigned char)0xF6);
8415
}
8416
8417
void Assembler::fdiv(int i) {
8418
emit_farith(0xD8, 0xF0, i);
8419
}
8420
8421
void Assembler::fdiv_d(Address src) {
8422
InstructionMark im(this);
8423
emit_int8((unsigned char)0xDC);
8424
emit_operand32(rsi, src);
8425
}
8426
8427
void Assembler::fdiv_s(Address src) {
8428
InstructionMark im(this);
8429
emit_int8((unsigned char)0xD8);
8430
emit_operand32(rsi, src);
8431
}
8432
8433
void Assembler::fdiva(int i) {
8434
emit_farith(0xDC, 0xF8, i);
8435
}
8436
8437
// Note: The Intel manual (Pentium Processor User's Manual, Vol.3, 1994)
8438
// is erroneous for some of the floating-point instructions below.
8439
8440
void Assembler::fdivp(int i) {
8441
emit_farith(0xDE, 0xF8, i); // ST(0) <- ST(0) / ST(1) and pop (Intel manual wrong)
8442
}
8443
8444
void Assembler::fdivr(int i) {
8445
emit_farith(0xD8, 0xF8, i);
8446
}
8447
8448
void Assembler::fdivr_d(Address src) {
8449
InstructionMark im(this);
8450
emit_int8((unsigned char)0xDC);
8451
emit_operand32(rdi, src);
8452
}
8453
8454
void Assembler::fdivr_s(Address src) {
8455
InstructionMark im(this);
8456
emit_int8((unsigned char)0xD8);
8457
emit_operand32(rdi, src);
8458
}
8459
8460
void Assembler::fdivra(int i) {
8461
emit_farith(0xDC, 0xF0, i);
8462
}
8463
8464
void Assembler::fdivrp(int i) {
8465
emit_farith(0xDE, 0xF0, i); // ST(0) <- ST(1) / ST(0) and pop (Intel manual wrong)
8466
}
8467
8468
void Assembler::ffree(int i) {
8469
emit_farith(0xDD, 0xC0, i);
8470
}
8471
8472
void Assembler::fild_d(Address adr) {
8473
InstructionMark im(this);
8474
emit_int8((unsigned char)0xDF);
8475
emit_operand32(rbp, adr);
8476
}
8477
8478
void Assembler::fild_s(Address adr) {
8479
InstructionMark im(this);
8480
emit_int8((unsigned char)0xDB);
8481
emit_operand32(rax, adr);
8482
}
8483
8484
void Assembler::fincstp() {
8485
emit_int16((unsigned char)0xD9, (unsigned char)0xF7);
8486
}
8487
8488
void Assembler::finit() {
8489
emit_int24((unsigned char)0x9B, (unsigned char)0xDB, (unsigned char)0xE3);
8490
}
8491
8492
void Assembler::fist_s(Address adr) {
8493
InstructionMark im(this);
8494
emit_int8((unsigned char)0xDB);
8495
emit_operand32(rdx, adr);
8496
}
8497
8498
void Assembler::fistp_d(Address adr) {
8499
InstructionMark im(this);
8500
emit_int8((unsigned char)0xDF);
8501
emit_operand32(rdi, adr);
8502
}
8503
8504
void Assembler::fistp_s(Address adr) {
8505
InstructionMark im(this);
8506
emit_int8((unsigned char)0xDB);
8507
emit_operand32(rbx, adr);
8508
}
8509
8510
void Assembler::fld1() {
8511
emit_int16((unsigned char)0xD9, (unsigned char)0xE8);
8512
}
8513
8514
void Assembler::fld_d(Address adr) {
8515
InstructionMark im(this);
8516
emit_int8((unsigned char)0xDD);
8517
emit_operand32(rax, adr);
8518
}
8519
8520
void Assembler::fld_s(Address adr) {
8521
InstructionMark im(this);
8522
emit_int8((unsigned char)0xD9);
8523
emit_operand32(rax, adr);
8524
}
8525
8526
8527
void Assembler::fld_s(int index) {
8528
emit_farith(0xD9, 0xC0, index);
8529
}
8530
8531
void Assembler::fldcw(Address src) {
8532
InstructionMark im(this);
8533
emit_int8((unsigned char)0xD9);
8534
emit_operand32(rbp, src);
8535
}
8536
8537
void Assembler::fldenv(Address src) {
8538
InstructionMark im(this);
8539
emit_int8((unsigned char)0xD9);
8540
emit_operand32(rsp, src);
8541
}
8542
8543
void Assembler::fldlg2() {
8544
emit_int16((unsigned char)0xD9, (unsigned char)0xEC);
8545
}
8546
8547
void Assembler::fldln2() {
8548
emit_int16((unsigned char)0xD9, (unsigned char)0xED);
8549
}
8550
8551
void Assembler::fldz() {
8552
emit_int16((unsigned char)0xD9, (unsigned char)0xEE);
8553
}
8554
8555
void Assembler::flog() {
8556
fldln2();
8557
fxch();
8558
fyl2x();
8559
}
8560
8561
void Assembler::flog10() {
8562
fldlg2();
8563
fxch();
8564
fyl2x();
8565
}
8566
8567
void Assembler::fmul(int i) {
8568
emit_farith(0xD8, 0xC8, i);
8569
}
8570
8571
void Assembler::fmul_d(Address src) {
8572
InstructionMark im(this);
8573
emit_int8((unsigned char)0xDC);
8574
emit_operand32(rcx, src);
8575
}
8576
8577
void Assembler::fmul_s(Address src) {
8578
InstructionMark im(this);
8579
emit_int8((unsigned char)0xD8);
8580
emit_operand32(rcx, src);
8581
}
8582
8583
void Assembler::fmula(int i) {
8584
emit_farith(0xDC, 0xC8, i);
8585
}
8586
8587
void Assembler::fmulp(int i) {
8588
emit_farith(0xDE, 0xC8, i);
8589
}
8590
8591
void Assembler::fnsave(Address dst) {
8592
InstructionMark im(this);
8593
emit_int8((unsigned char)0xDD);
8594
emit_operand32(rsi, dst);
8595
}
8596
8597
void Assembler::fnstcw(Address src) {
8598
InstructionMark im(this);
8599
emit_int16((unsigned char)0x9B, (unsigned char)0xD9);
8600
emit_operand32(rdi, src);
8601
}
8602
8603
void Assembler::fnstsw_ax() {
8604
emit_int16((unsigned char)0xDF, (unsigned char)0xE0);
8605
}
8606
8607
void Assembler::fprem() {
8608
emit_int16((unsigned char)0xD9, (unsigned char)0xF8);
8609
}
8610
8611
void Assembler::fprem1() {
8612
emit_int16((unsigned char)0xD9, (unsigned char)0xF5);
8613
}
8614
8615
void Assembler::frstor(Address src) {
8616
InstructionMark im(this);
8617
emit_int8((unsigned char)0xDD);
8618
emit_operand32(rsp, src);
8619
}
8620
8621
void Assembler::fsin() {
8622
emit_int16((unsigned char)0xD9, (unsigned char)0xFE);
8623
}
8624
8625
void Assembler::fsqrt() {
8626
emit_int16((unsigned char)0xD9, (unsigned char)0xFA);
8627
}
8628
8629
void Assembler::fst_d(Address adr) {
8630
InstructionMark im(this);
8631
emit_int8((unsigned char)0xDD);
8632
emit_operand32(rdx, adr);
8633
}
8634
8635
void Assembler::fst_s(Address adr) {
8636
InstructionMark im(this);
8637
emit_int8((unsigned char)0xD9);
8638
emit_operand32(rdx, adr);
8639
}
8640
8641
void Assembler::fstp_d(Address adr) {
8642
InstructionMark im(this);
8643
emit_int8((unsigned char)0xDD);
8644
emit_operand32(rbx, adr);
8645
}
8646
8647
void Assembler::fstp_d(int index) {
8648
emit_farith(0xDD, 0xD8, index);
8649
}
8650
8651
void Assembler::fstp_s(Address adr) {
8652
InstructionMark im(this);
8653
emit_int8((unsigned char)0xD9);
8654
emit_operand32(rbx, adr);
8655
}
8656
8657
void Assembler::fsub(int i) {
8658
emit_farith(0xD8, 0xE0, i);
8659
}
8660
8661
void Assembler::fsub_d(Address src) {
8662
InstructionMark im(this);
8663
emit_int8((unsigned char)0xDC);
8664
emit_operand32(rsp, src);
8665
}
8666
8667
void Assembler::fsub_s(Address src) {
8668
InstructionMark im(this);
8669
emit_int8((unsigned char)0xD8);
8670
emit_operand32(rsp, src);
8671
}
8672
8673
void Assembler::fsuba(int i) {
8674
emit_farith(0xDC, 0xE8, i);
8675
}
8676
8677
void Assembler::fsubp(int i) {
8678
emit_farith(0xDE, 0xE8, i); // ST(0) <- ST(0) - ST(1) and pop (Intel manual wrong)
8679
}
8680
8681
void Assembler::fsubr(int i) {
8682
emit_farith(0xD8, 0xE8, i);
8683
}
8684
8685
void Assembler::fsubr_d(Address src) {
8686
InstructionMark im(this);
8687
emit_int8((unsigned char)0xDC);
8688
emit_operand32(rbp, src);
8689
}
8690
8691
void Assembler::fsubr_s(Address src) {
8692
InstructionMark im(this);
8693
emit_int8((unsigned char)0xD8);
8694
emit_operand32(rbp, src);
8695
}
8696
8697
void Assembler::fsubra(int i) {
8698
emit_farith(0xDC, 0xE0, i);
8699
}
8700
8701
void Assembler::fsubrp(int i) {
8702
emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong)
8703
}
8704
8705
void Assembler::ftan() {
8706
emit_int32((unsigned char)0xD9, (unsigned char)0xF2, (unsigned char)0xDD, (unsigned char)0xD8);
8707
}
8708
8709
void Assembler::ftst() {
8710
emit_int16((unsigned char)0xD9, (unsigned char)0xE4);
8711
}
8712
8713
void Assembler::fucomi(int i) {
8714
// make sure the instruction is supported (introduced for P6, together with cmov)
8715
guarantee(VM_Version::supports_cmov(), "illegal instruction");
8716
emit_farith(0xDB, 0xE8, i);
8717
}
8718
8719
void Assembler::fucomip(int i) {
8720
// make sure the instruction is supported (introduced for P6, together with cmov)
8721
guarantee(VM_Version::supports_cmov(), "illegal instruction");
8722
emit_farith(0xDF, 0xE8, i);
8723
}
8724
8725
void Assembler::fwait() {
8726
emit_int8((unsigned char)0x9B);
8727
}
8728
8729
void Assembler::fxch(int i) {
8730
emit_farith(0xD9, 0xC8, i);
8731
}
8732
8733
void Assembler::fyl2x() {
8734
emit_int16((unsigned char)0xD9, (unsigned char)0xF1);
8735
}
8736
8737
void Assembler::frndint() {
8738
emit_int16((unsigned char)0xD9, (unsigned char)0xFC);
8739
}
8740
8741
void Assembler::f2xm1() {
8742
emit_int16((unsigned char)0xD9, (unsigned char)0xF0);
8743
}
8744
8745
void Assembler::fldl2e() {
8746
emit_int16((unsigned char)0xD9, (unsigned char)0xEA);
8747
}
8748
#endif // !_LP64
8749
8750
// SSE SIMD prefix byte values corresponding to VexSimdPrefix encoding.
8751
static int simd_pre[4] = { 0, 0x66, 0xF3, 0xF2 };
8752
// SSE opcode second byte values (first is 0x0F) corresponding to VexOpcode encoding.
8753
static int simd_opc[4] = { 0, 0, 0x38, 0x3A };
8754
8755
// Generate SSE legacy REX prefix and SIMD opcode based on VEX encoding.
8756
void Assembler::rex_prefix(Address adr, XMMRegister xreg, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
8757
if (pre > 0) {
8758
emit_int8(simd_pre[pre]);
8759
}
8760
if (rex_w) {
8761
prefixq(adr, xreg);
8762
} else {
8763
prefix(adr, xreg);
8764
}
8765
if (opc > 0) {
8766
emit_int8(0x0F);
8767
int opc2 = simd_opc[opc];
8768
if (opc2 > 0) {
8769
emit_int8(opc2);
8770
}
8771
}
8772
}
8773
8774
int Assembler::rex_prefix_and_encode(int dst_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
8775
if (pre > 0) {
8776
emit_int8(simd_pre[pre]);
8777
}
8778
int encode = (rex_w) ? prefixq_and_encode(dst_enc, src_enc) : prefix_and_encode(dst_enc, src_enc);
8779
if (opc > 0) {
8780
emit_int8(0x0F);
8781
int opc2 = simd_opc[opc];
8782
if (opc2 > 0) {
8783
emit_int8(opc2);
8784
}
8785
}
8786
return encode;
8787
}
8788
8789
8790
void Assembler::vex_prefix(bool vex_r, bool vex_b, bool vex_x, int nds_enc, VexSimdPrefix pre, VexOpcode opc) {
8791
int vector_len = _attributes->get_vector_len();
8792
bool vex_w = _attributes->is_rex_vex_w();
8793
if (vex_b || vex_x || vex_w || (opc == VEX_OPCODE_0F_38) || (opc == VEX_OPCODE_0F_3A)) {
8794
int byte1 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0);
8795
byte1 = (~byte1) & 0xE0;
8796
byte1 |= opc;
8797
8798
int byte2 = ((~nds_enc) & 0xf) << 3;
8799
byte2 |= (vex_w ? VEX_W : 0) | ((vector_len > 0) ? 4 : 0) | pre;
8800
8801
emit_int24((unsigned char)VEX_3bytes, byte1, byte2);
8802
} else {
8803
int byte1 = vex_r ? VEX_R : 0;
8804
byte1 = (~byte1) & 0x80;
8805
byte1 |= ((~nds_enc) & 0xf) << 3;
8806
byte1 |= ((vector_len > 0 ) ? 4 : 0) | pre;
8807
emit_int16((unsigned char)VEX_2bytes, byte1);
8808
}
8809
}
8810
8811
// This is a 4 byte encoding
8812
void Assembler::evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool evex_r, bool evex_v, int nds_enc, VexSimdPrefix pre, VexOpcode opc){
8813
// EVEX 0x62 prefix
8814
// byte1 = EVEX_4bytes;
8815
8816
bool vex_w = _attributes->is_rex_vex_w();
8817
int evex_encoding = (vex_w ? VEX_W : 0);
8818
// EVEX.b is not currently used for broadcast of single element or data rounding modes
8819
_attributes->set_evex_encoding(evex_encoding);
8820
8821
// P0: byte 2, initialized to RXBR`00mm
8822
// instead of not'd
8823
int byte2 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0) | (evex_r ? EVEX_Rb : 0);
8824
byte2 = (~byte2) & 0xF0;
8825
// confine opc opcode extensions in mm bits to lower two bits
8826
// of form {0F, 0F_38, 0F_3A}
8827
byte2 |= opc;
8828
8829
// P1: byte 3 as Wvvvv1pp
8830
int byte3 = ((~nds_enc) & 0xf) << 3;
8831
// p[10] is always 1
8832
byte3 |= EVEX_F;
8833
byte3 |= (vex_w & 1) << 7;
8834
// confine pre opcode extensions in pp bits to lower two bits
8835
// of form {66, F3, F2}
8836
byte3 |= pre;
8837
8838
// P2: byte 4 as zL'Lbv'aaa
8839
// kregs are implemented in the low 3 bits as aaa
8840
int byte4 = (_attributes->is_no_reg_mask()) ?
8841
0 :
8842
_attributes->get_embedded_opmask_register_specifier();
8843
// EVEX.v` for extending EVEX.vvvv or VIDX
8844
byte4 |= (evex_v ? 0: EVEX_V);
8845
// third EXEC.b for broadcast actions
8846
byte4 |= (_attributes->is_extended_context() ? EVEX_Rb : 0);
8847
// fourth EVEX.L'L for vector length : 0 is 128, 1 is 256, 2 is 512, currently we do not support 1024
8848
byte4 |= ((_attributes->get_vector_len())& 0x3) << 5;
8849
// last is EVEX.z for zero/merge actions
8850
if (_attributes->is_no_reg_mask() == false &&
8851
_attributes->get_embedded_opmask_register_specifier() != 0) {
8852
byte4 |= (_attributes->is_clear_context() ? EVEX_Z : 0);
8853
}
8854
8855
emit_int32(EVEX_4bytes, byte2, byte3, byte4);
8856
}
8857
8858
void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) {
8859
bool vex_r = (xreg_enc & 8) == 8;
8860
bool vex_b = adr.base_needs_rex();
8861
bool vex_x;
8862
if (adr.isxmmindex()) {
8863
vex_x = adr.xmmindex_needs_rex();
8864
} else {
8865
vex_x = adr.index_needs_rex();
8866
}
8867
set_attributes(attributes);
8868
attributes->set_current_assembler(this);
8869
8870
// For EVEX instruction (which is not marked as pure EVEX instruction) check and see if this instruction
8871
// is allowed in legacy mode and has resources which will fit in it.
8872
// Pure EVEX instructions will have is_evex_instruction set in their definition.
8873
if (!attributes->is_legacy_mode()) {
8874
if (UseAVX > 2 && !attributes->is_evex_instruction() && !is_managed()) {
8875
if ((attributes->get_vector_len() != AVX_512bit) && (nds_enc < 16) && (xreg_enc < 16)) {
8876
attributes->set_is_legacy_mode();
8877
}
8878
}
8879
}
8880
8881
if (UseAVX > 2) {
8882
assert(((!attributes->uses_vl()) ||
8883
(attributes->get_vector_len() == AVX_512bit) ||
8884
(!_legacy_mode_vl) ||
8885
(attributes->is_legacy_mode())),"XMM register should be 0-15");
8886
assert(((nds_enc < 16 && xreg_enc < 16) || (!attributes->is_legacy_mode())),"XMM register should be 0-15");
8887
}
8888
8889
clear_managed();
8890
if (UseAVX > 2 && !attributes->is_legacy_mode())
8891
{
8892
bool evex_r = (xreg_enc >= 16);
8893
bool evex_v;
8894
// EVEX.V' is set to true when VSIB is used as we may need to use higher order XMM registers (16-31)
8895
if (adr.isxmmindex()) {
8896
evex_v = ((adr._xmmindex->encoding() > 15) ? true : false);
8897
} else {
8898
evex_v = (nds_enc >= 16);
8899
}
8900
attributes->set_is_evex_instruction();
8901
evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc);
8902
} else {
8903
if (UseAVX > 2 && attributes->is_rex_vex_w_reverted()) {
8904
attributes->set_rex_vex_w(false);
8905
}
8906
vex_prefix(vex_r, vex_b, vex_x, nds_enc, pre, opc);
8907
}
8908
}
8909
8910
int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) {
8911
bool vex_r = (dst_enc & 8) == 8;
8912
bool vex_b = (src_enc & 8) == 8;
8913
bool vex_x = false;
8914
set_attributes(attributes);
8915
attributes->set_current_assembler(this);
8916
8917
// For EVEX instruction (which is not marked as pure EVEX instruction) check and see if this instruction
8918
// is allowed in legacy mode and has resources which will fit in it.
8919
// Pure EVEX instructions will have is_evex_instruction set in their definition.
8920
if (!attributes->is_legacy_mode()) {
8921
if (UseAVX > 2 && !attributes->is_evex_instruction() && !is_managed()) {
8922
if ((!attributes->uses_vl() || (attributes->get_vector_len() != AVX_512bit)) &&
8923
(dst_enc < 16) && (nds_enc < 16) && (src_enc < 16)) {
8924
attributes->set_is_legacy_mode();
8925
}
8926
}
8927
}
8928
8929
if (UseAVX > 2) {
8930
// All the scalar fp instructions (with uses_vl as false) can have legacy_mode as false
8931
// Instruction with uses_vl true are vector instructions
8932
// All the vector instructions with AVX_512bit length can have legacy_mode as false
8933
// All the vector instructions with < AVX_512bit length can have legacy_mode as false if AVX512vl() is supported
8934
// Rest all should have legacy_mode set as true
8935
assert(((!attributes->uses_vl()) ||
8936
(attributes->get_vector_len() == AVX_512bit) ||
8937
(!_legacy_mode_vl) ||
8938
(attributes->is_legacy_mode())),"XMM register should be 0-15");
8939
// Instruction with legacy_mode true should have dst, nds and src < 15
8940
assert(((dst_enc < 16 && nds_enc < 16 && src_enc < 16) || (!attributes->is_legacy_mode())),"XMM register should be 0-15");
8941
}
8942
8943
clear_managed();
8944
if (UseAVX > 2 && !attributes->is_legacy_mode())
8945
{
8946
bool evex_r = (dst_enc >= 16);
8947
bool evex_v = (nds_enc >= 16);
8948
// can use vex_x as bank extender on rm encoding
8949
vex_x = (src_enc >= 16);
8950
attributes->set_is_evex_instruction();
8951
evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc);
8952
} else {
8953
if (UseAVX > 2 && attributes->is_rex_vex_w_reverted()) {
8954
attributes->set_rex_vex_w(false);
8955
}
8956
vex_prefix(vex_r, vex_b, vex_x, nds_enc, pre, opc);
8957
}
8958
8959
// return modrm byte components for operands
8960
return (((dst_enc & 7) << 3) | (src_enc & 7));
8961
}
8962
8963
8964
void Assembler::simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr, VexSimdPrefix pre,
8965
VexOpcode opc, InstructionAttr *attributes) {
8966
if (UseAVX > 0) {
8967
int xreg_enc = xreg->encoding();
8968
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
8969
vex_prefix(adr, nds_enc, xreg_enc, pre, opc, attributes);
8970
} else {
8971
assert((nds == xreg) || (nds == xnoreg), "wrong sse encoding");
8972
rex_prefix(adr, xreg, pre, opc, attributes->is_rex_vex_w());
8973
}
8974
}
8975
8976
int Assembler::simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src, VexSimdPrefix pre,
8977
VexOpcode opc, InstructionAttr *attributes) {
8978
int dst_enc = dst->encoding();
8979
int src_enc = src->encoding();
8980
if (UseAVX > 0) {
8981
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
8982
return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, attributes);
8983
} else {
8984
assert((nds == dst) || (nds == src) || (nds == xnoreg), "wrong sse encoding");
8985
return rex_prefix_and_encode(dst_enc, src_enc, pre, opc, attributes->is_rex_vex_w());
8986
}
8987
}
8988
8989
void Assembler::vmaxss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
8990
assert(VM_Version::supports_avx(), "");
8991
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
8992
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
8993
emit_int16(0x5F, (0xC0 | encode));
8994
}
8995
8996
void Assembler::vmaxsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
8997
assert(VM_Version::supports_avx(), "");
8998
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
8999
attributes.set_rex_vex_w_reverted();
9000
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
9001
emit_int16(0x5F, (0xC0 | encode));
9002
}
9003
9004
void Assembler::vminss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
9005
assert(VM_Version::supports_avx(), "");
9006
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
9007
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
9008
emit_int16(0x5D, (0xC0 | encode));
9009
}
9010
9011
void Assembler::vminsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
9012
assert(VM_Version::supports_avx(), "");
9013
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
9014
attributes.set_rex_vex_w_reverted();
9015
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
9016
emit_int16(0x5D, (0xC0 | encode));
9017
}
9018
9019
void Assembler::vcmppd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len) {
9020
assert(VM_Version::supports_avx(), "");
9021
assert(vector_len <= AVX_256bit, "");
9022
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9023
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9024
emit_int24((unsigned char)0xC2, (0xC0 | encode), (0xF & cop));
9025
}
9026
9027
void Assembler::blendvpb(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
9028
assert(VM_Version::supports_avx(), "");
9029
assert(vector_len <= AVX_256bit, "");
9030
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9031
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9032
int src2_enc = src2->encoding();
9033
emit_int24(0x4C, (0xC0 | encode), (0xF0 & src2_enc << 4));
9034
}
9035
9036
void Assembler::vblendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
9037
assert(UseAVX > 0 && (vector_len == AVX_128bit || vector_len == AVX_256bit), "");
9038
assert(vector_len <= AVX_256bit, "");
9039
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9040
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9041
int src2_enc = src2->encoding();
9042
emit_int24(0x4B, (0xC0 | encode), (0xF0 & src2_enc << 4));
9043
}
9044
9045
void Assembler::vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
9046
assert(VM_Version::supports_avx2(), "");
9047
assert(vector_len <= AVX_256bit, "");
9048
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9049
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9050
emit_int24(0x02, (0xC0 | encode), (unsigned char)imm8);
9051
}
9052
9053
void Assembler::vcmpps(XMMRegister dst, XMMRegister nds, XMMRegister src, int comparison, int vector_len) {
9054
assert(VM_Version::supports_avx(), "");
9055
assert(vector_len <= AVX_256bit, "");
9056
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9057
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
9058
emit_int24((unsigned char)0xC2, (0xC0 | encode), (unsigned char)comparison);
9059
}
9060
9061
void Assembler::evcmpps(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9062
ComparisonPredicateFP comparison, int vector_len) {
9063
assert(VM_Version::supports_evex(), "");
9064
// Encoding: EVEX.NDS.XXX.0F.W0 C2 /r ib
9065
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9066
attributes.set_is_evex_instruction();
9067
attributes.set_embedded_opmask_register_specifier(mask);
9068
attributes.reset_is_clear_context();
9069
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
9070
emit_int24((unsigned char)0xC2, (0xC0 | encode), comparison);
9071
}
9072
9073
void Assembler::evcmppd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9074
ComparisonPredicateFP comparison, int vector_len) {
9075
assert(VM_Version::supports_evex(), "");
9076
// Encoding: EVEX.NDS.XXX.66.0F.W1 C2 /r ib
9077
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9078
attributes.set_is_evex_instruction();
9079
attributes.set_embedded_opmask_register_specifier(mask);
9080
attributes.reset_is_clear_context();
9081
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9082
emit_int24((unsigned char)0xC2, (0xC0 | encode), comparison);
9083
}
9084
9085
void Assembler::blendvps(XMMRegister dst, XMMRegister src) {
9086
assert(VM_Version::supports_sse4_1(), "");
9087
assert(UseAVX <= 0, "sse encoding is inconsistent with avx encoding");
9088
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9089
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9090
emit_int16(0x14, (0xC0 | encode));
9091
}
9092
9093
void Assembler::blendvpd(XMMRegister dst, XMMRegister src) {
9094
assert(VM_Version::supports_sse4_1(), "");
9095
assert(UseAVX <= 0, "sse encoding is inconsistent with avx encoding");
9096
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9097
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9098
emit_int16(0x15, (0xC0 | encode));
9099
}
9100
9101
void Assembler::pblendvb(XMMRegister dst, XMMRegister src) {
9102
assert(VM_Version::supports_sse4_1(), "");
9103
assert(UseAVX <= 0, "sse encoding is inconsistent with avx encoding");
9104
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9105
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9106
emit_int16(0x10, (0xC0 | encode));
9107
}
9108
9109
void Assembler::vblendvps(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
9110
assert(UseAVX > 0 && (vector_len == AVX_128bit || vector_len == AVX_256bit), "");
9111
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9112
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9113
int src2_enc = src2->encoding();
9114
emit_int24(0x4A, (0xC0 | encode), (0xF0 & src2_enc << 4));
9115
}
9116
9117
void Assembler::vblendps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
9118
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9119
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9120
emit_int24(0x0C, (0xC0 | encode), imm8);
9121
}
9122
9123
void Assembler::vpcmpgtb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9124
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9125
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9126
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9127
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9128
emit_int16(0x64, (0xC0 | encode));
9129
}
9130
9131
void Assembler::vpcmpgtw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9132
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9133
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9134
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9135
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9136
emit_int16(0x65, (0xC0 | encode));
9137
}
9138
9139
void Assembler::vpcmpgtd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9140
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9141
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9142
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9143
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9144
emit_int16(0x66, (0xC0 | encode));
9145
}
9146
9147
void Assembler::vpcmpgtq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9148
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9149
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9150
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9151
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9152
emit_int16(0x37, (0xC0 | encode));
9153
}
9154
9155
void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9156
int comparison, bool is_signed, int vector_len) {
9157
assert(VM_Version::supports_evex(), "");
9158
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9159
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 1F /r ib
9160
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9161
attributes.set_is_evex_instruction();
9162
attributes.set_embedded_opmask_register_specifier(mask);
9163
attributes.reset_is_clear_context();
9164
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9165
int opcode = is_signed ? 0x1F : 0x1E;
9166
emit_int24(opcode, (0xC0 | encode), comparison);
9167
}
9168
9169
void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9170
int comparison, bool is_signed, int vector_len) {
9171
assert(VM_Version::supports_evex(), "");
9172
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9173
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 1F /r ib
9174
InstructionMark im(this);
9175
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9176
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
9177
attributes.set_is_evex_instruction();
9178
attributes.set_embedded_opmask_register_specifier(mask);
9179
attributes.reset_is_clear_context();
9180
int dst_enc = kdst->encoding();
9181
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9182
int opcode = is_signed ? 0x1F : 0x1E;
9183
emit_int8((unsigned char)opcode);
9184
emit_operand(as_Register(dst_enc), src);
9185
emit_int8((unsigned char)comparison);
9186
}
9187
9188
void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9189
int comparison, bool is_signed, int vector_len) {
9190
assert(VM_Version::supports_evex(), "");
9191
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9192
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 1F /r ib
9193
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9194
attributes.set_is_evex_instruction();
9195
attributes.set_embedded_opmask_register_specifier(mask);
9196
attributes.reset_is_clear_context();
9197
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9198
int opcode = is_signed ? 0x1F : 0x1E;
9199
emit_int24(opcode, (0xC0 | encode), comparison);
9200
}
9201
9202
void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9203
int comparison, bool is_signed, int vector_len) {
9204
assert(VM_Version::supports_evex(), "");
9205
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9206
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 1F /r ib
9207
InstructionMark im(this);
9208
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9209
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
9210
attributes.set_is_evex_instruction();
9211
attributes.set_embedded_opmask_register_specifier(mask);
9212
attributes.reset_is_clear_context();
9213
int dst_enc = kdst->encoding();
9214
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9215
int opcode = is_signed ? 0x1F : 0x1E;
9216
emit_int8((unsigned char)opcode);
9217
emit_operand(as_Register(dst_enc), src);
9218
emit_int8((unsigned char)comparison);
9219
}
9220
9221
void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9222
int comparison, bool is_signed, int vector_len) {
9223
assert(VM_Version::supports_evex(), "");
9224
assert(VM_Version::supports_avx512bw(), "");
9225
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9226
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 3F /r ib
9227
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9228
attributes.set_is_evex_instruction();
9229
attributes.set_embedded_opmask_register_specifier(mask);
9230
attributes.reset_is_clear_context();
9231
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9232
int opcode = is_signed ? 0x3F : 0x3E;
9233
emit_int24(opcode, (0xC0 | encode), comparison);
9234
}
9235
9236
void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9237
int comparison, bool is_signed, int vector_len) {
9238
assert(VM_Version::supports_evex(), "");
9239
assert(VM_Version::supports_avx512bw(), "");
9240
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9241
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 3F /r ib
9242
InstructionMark im(this);
9243
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9244
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
9245
attributes.set_is_evex_instruction();
9246
attributes.set_embedded_opmask_register_specifier(mask);
9247
attributes.reset_is_clear_context();
9248
int dst_enc = kdst->encoding();
9249
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9250
int opcode = is_signed ? 0x3F : 0x3E;
9251
emit_int8((unsigned char)opcode);
9252
emit_operand(as_Register(dst_enc), src);
9253
emit_int8((unsigned char)comparison);
9254
}
9255
9256
void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9257
int comparison, bool is_signed, int vector_len) {
9258
assert(VM_Version::supports_evex(), "");
9259
assert(VM_Version::supports_avx512bw(), "");
9260
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9261
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 3F /r ib
9262
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9263
attributes.set_is_evex_instruction();
9264
attributes.set_embedded_opmask_register_specifier(mask);
9265
attributes.reset_is_clear_context();
9266
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9267
int opcode = is_signed ? 0x3F : 0x3E;
9268
emit_int24(opcode, (0xC0 | encode), comparison);
9269
}
9270
9271
void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9272
int comparison, bool is_signed, int vector_len) {
9273
assert(VM_Version::supports_evex(), "");
9274
assert(VM_Version::supports_avx512bw(), "");
9275
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9276
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 3F /r ib
9277
InstructionMark im(this);
9278
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9279
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
9280
attributes.set_is_evex_instruction();
9281
attributes.set_embedded_opmask_register_specifier(mask);
9282
attributes.reset_is_clear_context();
9283
int dst_enc = kdst->encoding();
9284
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9285
int opcode = is_signed ? 0x3F : 0x3E;
9286
emit_int8((unsigned char)opcode);
9287
emit_operand(as_Register(dst_enc), src);
9288
emit_int8((unsigned char)comparison);
9289
}
9290
9291
void Assembler::vpblendvb(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister mask, int vector_len) {
9292
assert(VM_Version::supports_avx(), "");
9293
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9294
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9295
int mask_enc = mask->encoding();
9296
emit_int24(0x4C, (0xC0 | encode), 0xF0 & mask_enc << 4);
9297
}
9298
9299
void Assembler::evblendmpd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9300
assert(VM_Version::supports_evex(), "");
9301
// Encoding: EVEX.NDS.XXX.66.0F38.W1 65 /r
9302
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9303
attributes.set_is_evex_instruction();
9304
attributes.set_embedded_opmask_register_specifier(mask);
9305
if (merge) {
9306
attributes.reset_is_clear_context();
9307
}
9308
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9309
emit_int16(0x65, (0xC0 | encode));
9310
}
9311
9312
void Assembler::evblendmps(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9313
assert(VM_Version::supports_evex(), "");
9314
// Encoding: EVEX.NDS.XXX.66.0F38.W0 65 /r
9315
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9316
attributes.set_is_evex_instruction();
9317
attributes.set_embedded_opmask_register_specifier(mask);
9318
if (merge) {
9319
attributes.reset_is_clear_context();
9320
}
9321
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9322
emit_int16(0x65, (0xC0 | encode));
9323
}
9324
9325
void Assembler::evpblendmb (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9326
assert(VM_Version::supports_evex(), "");
9327
assert(VM_Version::supports_avx512bw(), "");
9328
// Encoding: EVEX.NDS.512.66.0F38.W0 66 /r
9329
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9330
attributes.set_is_evex_instruction();
9331
attributes.set_embedded_opmask_register_specifier(mask);
9332
if (merge) {
9333
attributes.reset_is_clear_context();
9334
}
9335
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9336
emit_int16(0x66, (0xC0 | encode));
9337
}
9338
9339
void Assembler::evpblendmw (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9340
assert(VM_Version::supports_evex(), "");
9341
assert(VM_Version::supports_avx512bw(), "");
9342
// Encoding: EVEX.NDS.512.66.0F38.W1 66 /r
9343
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9344
attributes.set_is_evex_instruction();
9345
attributes.set_embedded_opmask_register_specifier(mask);
9346
if (merge) {
9347
attributes.reset_is_clear_context();
9348
}
9349
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9350
emit_int16(0x66, (0xC0 | encode));
9351
}
9352
9353
void Assembler::evpblendmd (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9354
assert(VM_Version::supports_evex(), "");
9355
//Encoding: EVEX.NDS.512.66.0F38.W0 64 /r
9356
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9357
attributes.set_is_evex_instruction();
9358
attributes.set_embedded_opmask_register_specifier(mask);
9359
if (merge) {
9360
attributes.reset_is_clear_context();
9361
}
9362
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9363
emit_int16(0x64, (0xC0 | encode));
9364
}
9365
9366
void Assembler::evpblendmq (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9367
assert(VM_Version::supports_evex(), "");
9368
//Encoding: EVEX.NDS.512.66.0F38.W1 64 /r
9369
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9370
attributes.set_is_evex_instruction();
9371
attributes.set_embedded_opmask_register_specifier(mask);
9372
if (merge) {
9373
attributes.reset_is_clear_context();
9374
}
9375
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9376
emit_int16(0x64, (0xC0 | encode));
9377
}
9378
9379
void Assembler::bzhiq(Register dst, Register src1, Register src2) {
9380
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
9381
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9382
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9383
emit_int16((unsigned char)0xF5, (0xC0 | encode));
9384
}
9385
9386
void Assembler::shlxl(Register dst, Register src1, Register src2) {
9387
assert(VM_Version::supports_bmi2(), "");
9388
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9389
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9390
emit_int16((unsigned char)0xF7, (0xC0 | encode));
9391
}
9392
9393
void Assembler::shlxq(Register dst, Register src1, Register src2) {
9394
assert(VM_Version::supports_bmi2(), "");
9395
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9396
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9397
emit_int16((unsigned char)0xF7, (0xC0 | encode));
9398
}
9399
9400
void Assembler::shrxq(Register dst, Register src1, Register src2) {
9401
assert(VM_Version::supports_bmi2(), "");
9402
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9403
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes);
9404
emit_int16((unsigned char)0xF7, (0xC0 | encode));
9405
}
9406
9407
void Assembler::evpmovb2m(KRegister dst, XMMRegister src, int vector_len) {
9408
assert(VM_Version::supports_avx512vlbw(), "");
9409
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
9410
attributes.set_is_evex_instruction();
9411
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
9412
emit_int16(0x29, (0xC0 | encode));
9413
}
9414
9415
#ifndef _LP64
9416
9417
void Assembler::incl(Register dst) {
9418
// Don't use it directly. Use MacroAssembler::incrementl() instead.
9419
emit_int8(0x40 | dst->encoding());
9420
}
9421
9422
void Assembler::lea(Register dst, Address src) {
9423
leal(dst, src);
9424
}
9425
9426
void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) {
9427
InstructionMark im(this);
9428
emit_int8((unsigned char)0xC7);
9429
emit_operand(rax, dst);
9430
emit_data((int)imm32, rspec, 0);
9431
}
9432
9433
void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) {
9434
InstructionMark im(this);
9435
int encode = prefix_and_encode(dst->encoding());
9436
emit_int8((0xB8 | encode));
9437
emit_data((int)imm32, rspec, 0);
9438
}
9439
9440
void Assembler::popa() { // 32bit
9441
emit_int8(0x61);
9442
}
9443
9444
void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) {
9445
InstructionMark im(this);
9446
emit_int8(0x68);
9447
emit_data(imm32, rspec, 0);
9448
}
9449
9450
void Assembler::pusha() { // 32bit
9451
emit_int8(0x60);
9452
}
9453
9454
void Assembler::set_byte_if_not_zero(Register dst) {
9455
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | dst->encoding()));
9456
}
9457
9458
#else // LP64
9459
9460
void Assembler::set_byte_if_not_zero(Register dst) {
9461
int enc = prefix_and_encode(dst->encoding(), true);
9462
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | enc));
9463
}
9464
9465
// 64bit only pieces of the assembler
9466
// This should only be used by 64bit instructions that can use rip-relative
9467
// it cannot be used by instructions that want an immediate value.
9468
9469
bool Assembler::reachable(AddressLiteral adr) {
9470
int64_t disp;
9471
relocInfo::relocType relocType = adr.reloc();
9472
9473
// None will force a 64bit literal to the code stream. Likely a placeholder
9474
// for something that will be patched later and we need to certain it will
9475
// always be reachable.
9476
if (relocType == relocInfo::none) {
9477
return false;
9478
}
9479
if (relocType == relocInfo::internal_word_type) {
9480
// This should be rip relative and easily reachable.
9481
return true;
9482
}
9483
if (relocType == relocInfo::virtual_call_type ||
9484
relocType == relocInfo::opt_virtual_call_type ||
9485
relocType == relocInfo::static_call_type ||
9486
relocType == relocInfo::static_stub_type ) {
9487
// This should be rip relative within the code cache and easily
9488
// reachable until we get huge code caches. (At which point
9489
// ic code is going to have issues).
9490
return true;
9491
}
9492
if (relocType != relocInfo::external_word_type &&
9493
relocType != relocInfo::poll_return_type && // these are really external_word but need special
9494
relocType != relocInfo::poll_type && // relocs to identify them
9495
relocType != relocInfo::runtime_call_type ) {
9496
return false;
9497
}
9498
9499
// Stress the correction code
9500
if (ForceUnreachable) {
9501
// Must be runtimecall reloc, see if it is in the codecache
9502
// Flipping stuff in the codecache to be unreachable causes issues
9503
// with things like inline caches where the additional instructions
9504
// are not handled.
9505
if (CodeCache::find_blob(adr._target) == NULL) {
9506
return false;
9507
}
9508
}
9509
// For external_word_type/runtime_call_type if it is reachable from where we
9510
// are now (possibly a temp buffer) and where we might end up
9511
// anywhere in the codeCache then we are always reachable.
9512
// This would have to change if we ever save/restore shared code
9513
// to be more pessimistic.
9514
disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
9515
if (!is_simm32(disp)) return false;
9516
disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
9517
if (!is_simm32(disp)) return false;
9518
9519
disp = (int64_t)adr._target - ((int64_t)pc() + sizeof(int));
9520
9521
// Because rip relative is a disp + address_of_next_instruction and we
9522
// don't know the value of address_of_next_instruction we apply a fudge factor
9523
// to make sure we will be ok no matter the size of the instruction we get placed into.
9524
// We don't have to fudge the checks above here because they are already worst case.
9525
9526
// 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal
9527
// + 4 because better safe than sorry.
9528
const int fudge = 12 + 4;
9529
if (disp < 0) {
9530
disp -= fudge;
9531
} else {
9532
disp += fudge;
9533
}
9534
return is_simm32(disp);
9535
}
9536
9537
void Assembler::emit_data64(jlong data,
9538
relocInfo::relocType rtype,
9539
int format) {
9540
if (rtype == relocInfo::none) {
9541
emit_int64(data);
9542
} else {
9543
emit_data64(data, Relocation::spec_simple(rtype), format);
9544
}
9545
}
9546
9547
void Assembler::emit_data64(jlong data,
9548
RelocationHolder const& rspec,
9549
int format) {
9550
assert(imm_operand == 0, "default format must be immediate in this file");
9551
assert(imm_operand == format, "must be immediate");
9552
assert(inst_mark() != NULL, "must be inside InstructionMark");
9553
// Do not use AbstractAssembler::relocate, which is not intended for
9554
// embedded words. Instead, relocate to the enclosing instruction.
9555
code_section()->relocate(inst_mark(), rspec, format);
9556
#ifdef ASSERT
9557
check_relocation(rspec, format);
9558
#endif
9559
emit_int64(data);
9560
}
9561
9562
void Assembler::prefix(Register reg) {
9563
if (reg->encoding() >= 8) {
9564
prefix(REX_B);
9565
}
9566
}
9567
9568
void Assembler::prefix(Register dst, Register src, Prefix p) {
9569
if (src->encoding() >= 8) {
9570
p = (Prefix)(p | REX_B);
9571
}
9572
if (dst->encoding() >= 8) {
9573
p = (Prefix)(p | REX_R);
9574
}
9575
if (p != Prefix_EMPTY) {
9576
// do not generate an empty prefix
9577
prefix(p);
9578
}
9579
}
9580
9581
void Assembler::prefix(Register dst, Address adr, Prefix p) {
9582
if (adr.base_needs_rex()) {
9583
if (adr.index_needs_rex()) {
9584
assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
9585
} else {
9586
prefix(REX_B);
9587
}
9588
} else {
9589
if (adr.index_needs_rex()) {
9590
assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
9591
}
9592
}
9593
if (dst->encoding() >= 8) {
9594
p = (Prefix)(p | REX_R);
9595
}
9596
if (p != Prefix_EMPTY) {
9597
// do not generate an empty prefix
9598
prefix(p);
9599
}
9600
}
9601
9602
void Assembler::prefix(Address adr) {
9603
if (adr.base_needs_rex()) {
9604
if (adr.index_needs_rex()) {
9605
prefix(REX_XB);
9606
} else {
9607
prefix(REX_B);
9608
}
9609
} else {
9610
if (adr.index_needs_rex()) {
9611
prefix(REX_X);
9612
}
9613
}
9614
}
9615
9616
void Assembler::prefix(Address adr, Register reg, bool byteinst) {
9617
if (reg->encoding() < 8) {
9618
if (adr.base_needs_rex()) {
9619
if (adr.index_needs_rex()) {
9620
prefix(REX_XB);
9621
} else {
9622
prefix(REX_B);
9623
}
9624
} else {
9625
if (adr.index_needs_rex()) {
9626
prefix(REX_X);
9627
} else if (byteinst && reg->encoding() >= 4) {
9628
prefix(REX);
9629
}
9630
}
9631
} else {
9632
if (adr.base_needs_rex()) {
9633
if (adr.index_needs_rex()) {
9634
prefix(REX_RXB);
9635
} else {
9636
prefix(REX_RB);
9637
}
9638
} else {
9639
if (adr.index_needs_rex()) {
9640
prefix(REX_RX);
9641
} else {
9642
prefix(REX_R);
9643
}
9644
}
9645
}
9646
}
9647
9648
void Assembler::prefix(Address adr, XMMRegister reg) {
9649
if (reg->encoding() < 8) {
9650
if (adr.base_needs_rex()) {
9651
if (adr.index_needs_rex()) {
9652
prefix(REX_XB);
9653
} else {
9654
prefix(REX_B);
9655
}
9656
} else {
9657
if (adr.index_needs_rex()) {
9658
prefix(REX_X);
9659
}
9660
}
9661
} else {
9662
if (adr.base_needs_rex()) {
9663
if (adr.index_needs_rex()) {
9664
prefix(REX_RXB);
9665
} else {
9666
prefix(REX_RB);
9667
}
9668
} else {
9669
if (adr.index_needs_rex()) {
9670
prefix(REX_RX);
9671
} else {
9672
prefix(REX_R);
9673
}
9674
}
9675
}
9676
}
9677
9678
int Assembler::prefix_and_encode(int reg_enc, bool byteinst) {
9679
if (reg_enc >= 8) {
9680
prefix(REX_B);
9681
reg_enc -= 8;
9682
} else if (byteinst && reg_enc >= 4) {
9683
prefix(REX);
9684
}
9685
return reg_enc;
9686
}
9687
9688
int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) {
9689
if (dst_enc < 8) {
9690
if (src_enc >= 8) {
9691
prefix(REX_B);
9692
src_enc -= 8;
9693
} else if ((src_is_byte && src_enc >= 4) || (dst_is_byte && dst_enc >= 4)) {
9694
prefix(REX);
9695
}
9696
} else {
9697
if (src_enc < 8) {
9698
prefix(REX_R);
9699
} else {
9700
prefix(REX_RB);
9701
src_enc -= 8;
9702
}
9703
dst_enc -= 8;
9704
}
9705
return dst_enc << 3 | src_enc;
9706
}
9707
9708
int8_t Assembler::get_prefixq(Address adr) {
9709
int8_t prfx = get_prefixq(adr, rax);
9710
assert(REX_W <= prfx && prfx <= REX_WXB, "must be");
9711
return prfx;
9712
}
9713
9714
int8_t Assembler::get_prefixq(Address adr, Register src) {
9715
int8_t prfx = (int8_t)(REX_W +
9716
((int)adr.base_needs_rex()) +
9717
((int)adr.index_needs_rex() << 1) +
9718
((int)(src->encoding() >= 8) << 2));
9719
#ifdef ASSERT
9720
if (src->encoding() < 8) {
9721
if (adr.base_needs_rex()) {
9722
if (adr.index_needs_rex()) {
9723
assert(prfx == REX_WXB, "must be");
9724
} else {
9725
assert(prfx == REX_WB, "must be");
9726
}
9727
} else {
9728
if (adr.index_needs_rex()) {
9729
assert(prfx == REX_WX, "must be");
9730
} else {
9731
assert(prfx == REX_W, "must be");
9732
}
9733
}
9734
} else {
9735
if (adr.base_needs_rex()) {
9736
if (adr.index_needs_rex()) {
9737
assert(prfx == REX_WRXB, "must be");
9738
} else {
9739
assert(prfx == REX_WRB, "must be");
9740
}
9741
} else {
9742
if (adr.index_needs_rex()) {
9743
assert(prfx == REX_WRX, "must be");
9744
} else {
9745
assert(prfx == REX_WR, "must be");
9746
}
9747
}
9748
}
9749
#endif
9750
return prfx;
9751
}
9752
9753
void Assembler::prefixq(Address adr) {
9754
emit_int8(get_prefixq(adr));
9755
}
9756
9757
void Assembler::prefixq(Address adr, Register src) {
9758
emit_int8(get_prefixq(adr, src));
9759
}
9760
9761
void Assembler::prefixq(Address adr, XMMRegister src) {
9762
if (src->encoding() < 8) {
9763
if (adr.base_needs_rex()) {
9764
if (adr.index_needs_rex()) {
9765
prefix(REX_WXB);
9766
} else {
9767
prefix(REX_WB);
9768
}
9769
} else {
9770
if (adr.index_needs_rex()) {
9771
prefix(REX_WX);
9772
} else {
9773
prefix(REX_W);
9774
}
9775
}
9776
} else {
9777
if (adr.base_needs_rex()) {
9778
if (adr.index_needs_rex()) {
9779
prefix(REX_WRXB);
9780
} else {
9781
prefix(REX_WRB);
9782
}
9783
} else {
9784
if (adr.index_needs_rex()) {
9785
prefix(REX_WRX);
9786
} else {
9787
prefix(REX_WR);
9788
}
9789
}
9790
}
9791
}
9792
9793
int Assembler::prefixq_and_encode(int reg_enc) {
9794
if (reg_enc < 8) {
9795
prefix(REX_W);
9796
} else {
9797
prefix(REX_WB);
9798
reg_enc -= 8;
9799
}
9800
return reg_enc;
9801
}
9802
9803
int Assembler::prefixq_and_encode(int dst_enc, int src_enc) {
9804
if (dst_enc < 8) {
9805
if (src_enc < 8) {
9806
prefix(REX_W);
9807
} else {
9808
prefix(REX_WB);
9809
src_enc -= 8;
9810
}
9811
} else {
9812
if (src_enc < 8) {
9813
prefix(REX_WR);
9814
} else {
9815
prefix(REX_WRB);
9816
src_enc -= 8;
9817
}
9818
dst_enc -= 8;
9819
}
9820
return dst_enc << 3 | src_enc;
9821
}
9822
9823
void Assembler::adcq(Register dst, int32_t imm32) {
9824
(void) prefixq_and_encode(dst->encoding());
9825
emit_arith(0x81, 0xD0, dst, imm32);
9826
}
9827
9828
void Assembler::adcq(Register dst, Address src) {
9829
InstructionMark im(this);
9830
emit_int16(get_prefixq(src, dst), 0x13);
9831
emit_operand(dst, src);
9832
}
9833
9834
void Assembler::adcq(Register dst, Register src) {
9835
(void) prefixq_and_encode(dst->encoding(), src->encoding());
9836
emit_arith(0x13, 0xC0, dst, src);
9837
}
9838
9839
void Assembler::addq(Address dst, int32_t imm32) {
9840
InstructionMark im(this);
9841
prefixq(dst);
9842
emit_arith_operand(0x81, rax, dst, imm32);
9843
}
9844
9845
void Assembler::addq(Address dst, Register src) {
9846
InstructionMark im(this);
9847
emit_int16(get_prefixq(dst, src), 0x01);
9848
emit_operand(src, dst);
9849
}
9850
9851
void Assembler::addq(Register dst, int32_t imm32) {
9852
(void) prefixq_and_encode(dst->encoding());
9853
emit_arith(0x81, 0xC0, dst, imm32);
9854
}
9855
9856
void Assembler::addq(Register dst, Address src) {
9857
InstructionMark im(this);
9858
emit_int16(get_prefixq(src, dst), 0x03);
9859
emit_operand(dst, src);
9860
}
9861
9862
void Assembler::addq(Register dst, Register src) {
9863
(void) prefixq_and_encode(dst->encoding(), src->encoding());
9864
emit_arith(0x03, 0xC0, dst, src);
9865
}
9866
9867
void Assembler::adcxq(Register dst, Register src) {
9868
//assert(VM_Version::supports_adx(), "adx instructions not supported");
9869
emit_int8(0x66);
9870
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9871
emit_int32(0x0F,
9872
0x38,
9873
(unsigned char)0xF6,
9874
(0xC0 | encode));
9875
}
9876
9877
void Assembler::adoxq(Register dst, Register src) {
9878
//assert(VM_Version::supports_adx(), "adx instructions not supported");
9879
emit_int8((unsigned char)0xF3);
9880
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9881
emit_int32(0x0F,
9882
0x38,
9883
(unsigned char)0xF6,
9884
(0xC0 | encode));
9885
}
9886
9887
void Assembler::andq(Address dst, int32_t imm32) {
9888
InstructionMark im(this);
9889
prefixq(dst);
9890
emit_arith_operand(0x81, as_Register(4), dst, imm32);
9891
}
9892
9893
void Assembler::andq(Register dst, int32_t imm32) {
9894
(void) prefixq_and_encode(dst->encoding());
9895
emit_arith(0x81, 0xE0, dst, imm32);
9896
}
9897
9898
void Assembler::andq(Register dst, Address src) {
9899
InstructionMark im(this);
9900
emit_int16(get_prefixq(src, dst), 0x23);
9901
emit_operand(dst, src);
9902
}
9903
9904
void Assembler::andq(Register dst, Register src) {
9905
(void) prefixq_and_encode(dst->encoding(), src->encoding());
9906
emit_arith(0x23, 0xC0, dst, src);
9907
}
9908
9909
void Assembler::andq(Address dst, Register src) {
9910
InstructionMark im(this);
9911
emit_int16(get_prefixq(dst, src), 0x21);
9912
emit_operand(src, dst);
9913
}
9914
9915
void Assembler::andnq(Register dst, Register src1, Register src2) {
9916
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9917
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9918
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9919
emit_int16((unsigned char)0xF2, (0xC0 | encode));
9920
}
9921
9922
void Assembler::andnq(Register dst, Register src1, Address src2) {
9923
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9924
InstructionMark im(this);
9925
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9926
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9927
emit_int8((unsigned char)0xF2);
9928
emit_operand(dst, src2);
9929
}
9930
9931
void Assembler::bsfq(Register dst, Register src) {
9932
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9933
emit_int24(0x0F, (unsigned char)0xBC, (0xC0 | encode));
9934
}
9935
9936
void Assembler::bsrq(Register dst, Register src) {
9937
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9938
emit_int24(0x0F, (unsigned char)0xBD, (0xC0 | encode));
9939
}
9940
9941
void Assembler::bswapq(Register reg) {
9942
int encode = prefixq_and_encode(reg->encoding());
9943
emit_int16(0x0F, (0xC8 | encode));
9944
}
9945
9946
void Assembler::blsiq(Register dst, Register src) {
9947
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9948
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9949
int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9950
emit_int16((unsigned char)0xF3, (0xC0 | encode));
9951
}
9952
9953
void Assembler::blsiq(Register dst, Address src) {
9954
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9955
InstructionMark im(this);
9956
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9957
vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9958
emit_int8((unsigned char)0xF3);
9959
emit_operand(rbx, src);
9960
}
9961
9962
void Assembler::blsmskq(Register dst, Register src) {
9963
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9964
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9965
int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9966
emit_int16((unsigned char)0xF3, (0xC0 | encode));
9967
}
9968
9969
void Assembler::blsmskq(Register dst, Address src) {
9970
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9971
InstructionMark im(this);
9972
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9973
vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9974
emit_int8((unsigned char)0xF3);
9975
emit_operand(rdx, src);
9976
}
9977
9978
void Assembler::blsrq(Register dst, Register src) {
9979
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9980
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9981
int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9982
emit_int16((unsigned char)0xF3, (0xC0 | encode));
9983
}
9984
9985
void Assembler::blsrq(Register dst, Address src) {
9986
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9987
InstructionMark im(this);
9988
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9989
vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9990
emit_int8((unsigned char)0xF3);
9991
emit_operand(rcx, src);
9992
}
9993
9994
void Assembler::cdqq() {
9995
emit_int16(REX_W, (unsigned char)0x99);
9996
}
9997
9998
void Assembler::clflush(Address adr) {
9999
assert(VM_Version::supports_clflush(), "should do");
10000
prefix(adr);
10001
emit_int16(0x0F, (unsigned char)0xAE);
10002
emit_operand(rdi, adr);
10003
}
10004
10005
void Assembler::clflushopt(Address adr) {
10006
assert(VM_Version::supports_clflushopt(), "should do!");
10007
// adr should be base reg only with no index or offset
10008
assert(adr.index() == noreg, "index should be noreg");
10009
assert(adr.scale() == Address::no_scale, "scale should be no_scale");
10010
assert(adr.disp() == 0, "displacement should be 0");
10011
// instruction prefix is 0x66
10012
emit_int8(0x66);
10013
prefix(adr);
10014
// opcode family is 0x0F 0xAE
10015
emit_int16(0x0F, (unsigned char)0xAE);
10016
// extended opcode byte is 7 == rdi
10017
emit_operand(rdi, adr);
10018
}
10019
10020
void Assembler::clwb(Address adr) {
10021
assert(VM_Version::supports_clwb(), "should do!");
10022
// adr should be base reg only with no index or offset
10023
assert(adr.index() == noreg, "index should be noreg");
10024
assert(adr.scale() == Address::no_scale, "scale should be no_scale");
10025
assert(adr.disp() == 0, "displacement should be 0");
10026
// instruction prefix is 0x66
10027
emit_int8(0x66);
10028
prefix(adr);
10029
// opcode family is 0x0f 0xAE
10030
emit_int16(0x0F, (unsigned char)0xAE);
10031
// extended opcode byte is 6 == rsi
10032
emit_operand(rsi, adr);
10033
}
10034
10035
void Assembler::cmovq(Condition cc, Register dst, Register src) {
10036
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10037
emit_int24(0x0F, (0x40 | cc), (0xC0 | encode));
10038
}
10039
10040
void Assembler::cmovq(Condition cc, Register dst, Address src) {
10041
InstructionMark im(this);
10042
emit_int24(get_prefixq(src, dst), 0x0F, (0x40 | cc));
10043
emit_operand(dst, src);
10044
}
10045
10046
void Assembler::cmpq(Address dst, int32_t imm32) {
10047
InstructionMark im(this);
10048
emit_int16(get_prefixq(dst), (unsigned char)0x81);
10049
emit_operand(rdi, dst, 4);
10050
emit_int32(imm32);
10051
}
10052
10053
void Assembler::cmpq(Register dst, int32_t imm32) {
10054
(void) prefixq_and_encode(dst->encoding());
10055
emit_arith(0x81, 0xF8, dst, imm32);
10056
}
10057
10058
void Assembler::cmpq(Address dst, Register src) {
10059
InstructionMark im(this);
10060
emit_int16(get_prefixq(dst, src), 0x39);
10061
emit_operand(src, dst);
10062
}
10063
10064
void Assembler::cmpq(Register dst, Register src) {
10065
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10066
emit_arith(0x3B, 0xC0, dst, src);
10067
}
10068
10069
void Assembler::cmpq(Register dst, Address src) {
10070
InstructionMark im(this);
10071
emit_int16(get_prefixq(src, dst), 0x3B);
10072
emit_operand(dst, src);
10073
}
10074
10075
void Assembler::cmpxchgq(Register reg, Address adr) {
10076
InstructionMark im(this);
10077
emit_int24(get_prefixq(adr, reg), 0x0F, (unsigned char)0xB1);
10078
emit_operand(reg, adr);
10079
}
10080
10081
void Assembler::cvtsi2sdq(XMMRegister dst, Register src) {
10082
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10083
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10084
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
10085
emit_int16(0x2A, (0xC0 | encode));
10086
}
10087
10088
void Assembler::cvtsi2sdq(XMMRegister dst, Address src) {
10089
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10090
InstructionMark im(this);
10091
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10092
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
10093
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
10094
emit_int8(0x2A);
10095
emit_operand(dst, src);
10096
}
10097
10098
void Assembler::cvtsi2ssq(XMMRegister dst, Address src) {
10099
NOT_LP64(assert(VM_Version::supports_sse(), ""));
10100
InstructionMark im(this);
10101
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10102
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
10103
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
10104
emit_int8(0x2A);
10105
emit_operand(dst, src);
10106
}
10107
10108
void Assembler::cvttsd2siq(Register dst, Address src) {
10109
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10110
// F2 REX.W 0F 2C /r
10111
// CVTTSD2SI r64, xmm1/m64
10112
InstructionMark im(this);
10113
emit_int32((unsigned char)0xF2, REX_W, 0x0F, 0x2C);
10114
emit_operand(dst, src);
10115
}
10116
10117
void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
10118
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10119
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10120
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
10121
emit_int16(0x2C, (0xC0 | encode));
10122
}
10123
10124
void Assembler::cvttss2siq(Register dst, XMMRegister src) {
10125
NOT_LP64(assert(VM_Version::supports_sse(), ""));
10126
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10127
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
10128
emit_int16(0x2C, (0xC0 | encode));
10129
}
10130
10131
void Assembler::decl(Register dst) {
10132
// Don't use it directly. Use MacroAssembler::decrementl() instead.
10133
// Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
10134
int encode = prefix_and_encode(dst->encoding());
10135
emit_int16((unsigned char)0xFF, (0xC8 | encode));
10136
}
10137
10138
void Assembler::decq(Register dst) {
10139
// Don't use it directly. Use MacroAssembler::decrementq() instead.
10140
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
10141
int encode = prefixq_and_encode(dst->encoding());
10142
emit_int16((unsigned char)0xFF, 0xC8 | encode);
10143
}
10144
10145
void Assembler::decq(Address dst) {
10146
// Don't use it directly. Use MacroAssembler::decrementq() instead.
10147
InstructionMark im(this);
10148
emit_int16(get_prefixq(dst), (unsigned char)0xFF);
10149
emit_operand(rcx, dst);
10150
}
10151
10152
void Assembler::fxrstor(Address src) {
10153
emit_int24(get_prefixq(src), 0x0F, (unsigned char)0xAE);
10154
emit_operand(as_Register(1), src);
10155
}
10156
10157
void Assembler::xrstor(Address src) {
10158
emit_int24(get_prefixq(src), 0x0F, (unsigned char)0xAE);
10159
emit_operand(as_Register(5), src);
10160
}
10161
10162
void Assembler::fxsave(Address dst) {
10163
emit_int24(get_prefixq(dst), 0x0F, (unsigned char)0xAE);
10164
emit_operand(as_Register(0), dst);
10165
}
10166
10167
void Assembler::xsave(Address dst) {
10168
emit_int24(get_prefixq(dst), 0x0F, (unsigned char)0xAE);
10169
emit_operand(as_Register(4), dst);
10170
}
10171
10172
void Assembler::idivq(Register src) {
10173
int encode = prefixq_and_encode(src->encoding());
10174
emit_int16((unsigned char)0xF7, (0xF8 | encode));
10175
}
10176
10177
void Assembler::imulq(Register dst, Register src) {
10178
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10179
emit_int24(0x0F, (unsigned char)0xAF, (0xC0 | encode));
10180
}
10181
10182
void Assembler::imulq(Register src) {
10183
int encode = prefixq_and_encode(src->encoding());
10184
emit_int16((unsigned char)0xF7, (0xE8 | encode));
10185
}
10186
10187
void Assembler::imulq(Register dst, Address src, int32_t value) {
10188
InstructionMark im(this);
10189
prefixq(src, dst);
10190
if (is8bit(value)) {
10191
emit_int8((unsigned char)0x6B);
10192
emit_operand(dst, src);
10193
emit_int8(value);
10194
} else {
10195
emit_int8((unsigned char)0x69);
10196
emit_operand(dst, src);
10197
emit_int32(value);
10198
}
10199
}
10200
10201
void Assembler::imulq(Register dst, Register src, int value) {
10202
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10203
if (is8bit(value)) {
10204
emit_int24(0x6B, (0xC0 | encode), (value & 0xFF));
10205
} else {
10206
emit_int16(0x69, (0xC0 | encode));
10207
emit_int32(value);
10208
}
10209
}
10210
10211
void Assembler::imulq(Register dst, Address src) {
10212
InstructionMark im(this);
10213
emit_int24(get_prefixq(src, dst), 0x0F, (unsigned char)0xAF);
10214
emit_operand(dst, src);
10215
}
10216
10217
void Assembler::incl(Register dst) {
10218
// Don't use it directly. Use MacroAssembler::incrementl() instead.
10219
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
10220
int encode = prefix_and_encode(dst->encoding());
10221
emit_int16((unsigned char)0xFF, (0xC0 | encode));
10222
}
10223
10224
void Assembler::incq(Register dst) {
10225
// Don't use it directly. Use MacroAssembler::incrementq() instead.
10226
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
10227
int encode = prefixq_and_encode(dst->encoding());
10228
emit_int16((unsigned char)0xFF, (0xC0 | encode));
10229
}
10230
10231
void Assembler::incq(Address dst) {
10232
// Don't use it directly. Use MacroAssembler::incrementq() instead.
10233
InstructionMark im(this);
10234
emit_int16(get_prefixq(dst), (unsigned char)0xFF);
10235
emit_operand(rax, dst);
10236
}
10237
10238
void Assembler::lea(Register dst, Address src) {
10239
leaq(dst, src);
10240
}
10241
10242
void Assembler::leaq(Register dst, Address src) {
10243
InstructionMark im(this);
10244
emit_int16(get_prefixq(src, dst), (unsigned char)0x8D);
10245
emit_operand(dst, src);
10246
}
10247
10248
void Assembler::mov64(Register dst, int64_t imm64) {
10249
InstructionMark im(this);
10250
int encode = prefixq_and_encode(dst->encoding());
10251
emit_int8(0xB8 | encode);
10252
emit_int64(imm64);
10253
}
10254
10255
void Assembler::mov64(Register dst, int64_t imm64, relocInfo::relocType rtype, int format) {
10256
InstructionMark im(this);
10257
int encode = prefixq_and_encode(dst->encoding());
10258
emit_int8(0xB8 | encode);
10259
emit_data64(imm64, rtype, format);
10260
}
10261
10262
void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) {
10263
InstructionMark im(this);
10264
int encode = prefixq_and_encode(dst->encoding());
10265
emit_int8(0xB8 | encode);
10266
emit_data64(imm64, rspec);
10267
}
10268
10269
void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) {
10270
InstructionMark im(this);
10271
int encode = prefix_and_encode(dst->encoding());
10272
emit_int8(0xB8 | encode);
10273
emit_data((int)imm32, rspec, narrow_oop_operand);
10274
}
10275
10276
void Assembler::mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec) {
10277
InstructionMark im(this);
10278
prefix(dst);
10279
emit_int8((unsigned char)0xC7);
10280
emit_operand(rax, dst, 4);
10281
emit_data((int)imm32, rspec, narrow_oop_operand);
10282
}
10283
10284
void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) {
10285
InstructionMark im(this);
10286
int encode = prefix_and_encode(src1->encoding());
10287
emit_int16((unsigned char)0x81, (0xF8 | encode));
10288
emit_data((int)imm32, rspec, narrow_oop_operand);
10289
}
10290
10291
void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) {
10292
InstructionMark im(this);
10293
prefix(src1);
10294
emit_int8((unsigned char)0x81);
10295
emit_operand(rax, src1, 4);
10296
emit_data((int)imm32, rspec, narrow_oop_operand);
10297
}
10298
10299
void Assembler::lzcntq(Register dst, Register src) {
10300
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
10301
emit_int8((unsigned char)0xF3);
10302
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10303
emit_int24(0x0F, (unsigned char)0xBD, (0xC0 | encode));
10304
}
10305
10306
void Assembler::movdq(XMMRegister dst, Register src) {
10307
// table D-1 says MMX/SSE2
10308
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10309
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10310
int encode = simd_prefix_and_encode(dst, xnoreg, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
10311
emit_int16(0x6E, (0xC0 | encode));
10312
}
10313
10314
void Assembler::movdq(Register dst, XMMRegister src) {
10315
// table D-1 says MMX/SSE2
10316
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10317
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10318
// swap src/dst to get correct prefix
10319
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
10320
emit_int16(0x7E,
10321
(0xC0 | encode));
10322
}
10323
10324
void Assembler::movq(Register dst, Register src) {
10325
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10326
emit_int16((unsigned char)0x8B,
10327
(0xC0 | encode));
10328
}
10329
10330
void Assembler::movq(Register dst, Address src) {
10331
InstructionMark im(this);
10332
emit_int16(get_prefixq(src, dst), (unsigned char)0x8B);
10333
emit_operand(dst, src);
10334
}
10335
10336
void Assembler::movq(Address dst, Register src) {
10337
InstructionMark im(this);
10338
emit_int16(get_prefixq(dst, src), (unsigned char)0x89);
10339
emit_operand(src, dst);
10340
}
10341
10342
void Assembler::movq(Address dst, int32_t imm32) {
10343
InstructionMark im(this);
10344
emit_int16(get_prefixq(dst), (unsigned char)0xC7);
10345
emit_operand(as_Register(0), dst);
10346
emit_int32(imm32);
10347
}
10348
10349
void Assembler::movq(Register dst, int32_t imm32) {
10350
int encode = prefixq_and_encode(dst->encoding());
10351
emit_int16((unsigned char)0xC7, (0xC0 | encode));
10352
emit_int32(imm32);
10353
}
10354
10355
void Assembler::movsbq(Register dst, Address src) {
10356
InstructionMark im(this);
10357
emit_int24(get_prefixq(src, dst),
10358
0x0F,
10359
(unsigned char)0xBE);
10360
emit_operand(dst, src);
10361
}
10362
10363
void Assembler::movsbq(Register dst, Register src) {
10364
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10365
emit_int24(0x0F, (unsigned char)0xBE, (0xC0 | encode));
10366
}
10367
10368
void Assembler::movslq(Register dst, int32_t imm32) {
10369
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
10370
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
10371
// as a result we shouldn't use until tested at runtime...
10372
ShouldNotReachHere();
10373
InstructionMark im(this);
10374
int encode = prefixq_and_encode(dst->encoding());
10375
emit_int8(0xC7 | encode);
10376
emit_int32(imm32);
10377
}
10378
10379
void Assembler::movslq(Address dst, int32_t imm32) {
10380
assert(is_simm32(imm32), "lost bits");
10381
InstructionMark im(this);
10382
emit_int16(get_prefixq(dst), (unsigned char)0xC7);
10383
emit_operand(rax, dst, 4);
10384
emit_int32(imm32);
10385
}
10386
10387
void Assembler::movslq(Register dst, Address src) {
10388
InstructionMark im(this);
10389
emit_int16(get_prefixq(src, dst), 0x63);
10390
emit_operand(dst, src);
10391
}
10392
10393
void Assembler::movslq(Register dst, Register src) {
10394
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10395
emit_int16(0x63, (0xC0 | encode));
10396
}
10397
10398
void Assembler::movswq(Register dst, Address src) {
10399
InstructionMark im(this);
10400
emit_int24(get_prefixq(src, dst),
10401
0x0F,
10402
(unsigned char)0xBF);
10403
emit_operand(dst, src);
10404
}
10405
10406
void Assembler::movswq(Register dst, Register src) {
10407
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10408
emit_int24(0x0F, (unsigned char)0xBF, (0xC0 | encode));
10409
}
10410
10411
void Assembler::movzbq(Register dst, Address src) {
10412
InstructionMark im(this);
10413
emit_int24(get_prefixq(src, dst),
10414
0x0F,
10415
(unsigned char)0xB6);
10416
emit_operand(dst, src);
10417
}
10418
10419
void Assembler::movzbq(Register dst, Register src) {
10420
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10421
emit_int24(0x0F, (unsigned char)0xB6, (0xC0 | encode));
10422
}
10423
10424
void Assembler::movzwq(Register dst, Address src) {
10425
InstructionMark im(this);
10426
emit_int24(get_prefixq(src, dst),
10427
0x0F,
10428
(unsigned char)0xB7);
10429
emit_operand(dst, src);
10430
}
10431
10432
void Assembler::movzwq(Register dst, Register src) {
10433
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10434
emit_int24(0x0F, (unsigned char)0xB7, (0xC0 | encode));
10435
}
10436
10437
void Assembler::mulq(Address src) {
10438
InstructionMark im(this);
10439
emit_int16(get_prefixq(src), (unsigned char)0xF7);
10440
emit_operand(rsp, src);
10441
}
10442
10443
void Assembler::mulq(Register src) {
10444
int encode = prefixq_and_encode(src->encoding());
10445
emit_int16((unsigned char)0xF7, (0xE0 | encode));
10446
}
10447
10448
void Assembler::mulxq(Register dst1, Register dst2, Register src) {
10449
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
10450
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10451
int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes);
10452
emit_int16((unsigned char)0xF6, (0xC0 | encode));
10453
}
10454
10455
void Assembler::negq(Register dst) {
10456
int encode = prefixq_and_encode(dst->encoding());
10457
emit_int16((unsigned char)0xF7, (0xD8 | encode));
10458
}
10459
10460
void Assembler::negq(Address dst) {
10461
InstructionMark im(this);
10462
emit_int16(get_prefixq(dst), (unsigned char)0xF7);
10463
emit_operand(as_Register(3), dst);
10464
}
10465
10466
void Assembler::notq(Register dst) {
10467
int encode = prefixq_and_encode(dst->encoding());
10468
emit_int16((unsigned char)0xF7, (0xD0 | encode));
10469
}
10470
10471
void Assembler::btsq(Address dst, int imm8) {
10472
assert(isByte(imm8), "not a byte");
10473
InstructionMark im(this);
10474
emit_int24(get_prefixq(dst),
10475
0x0F,
10476
(unsigned char)0xBA);
10477
emit_operand(rbp /* 5 */, dst, 1);
10478
emit_int8(imm8);
10479
}
10480
10481
void Assembler::btrq(Address dst, int imm8) {
10482
assert(isByte(imm8), "not a byte");
10483
InstructionMark im(this);
10484
emit_int24(get_prefixq(dst),
10485
0x0F,
10486
(unsigned char)0xBA);
10487
emit_operand(rsi /* 6 */, dst, 1);
10488
emit_int8(imm8);
10489
}
10490
10491
void Assembler::orq(Address dst, int32_t imm32) {
10492
InstructionMark im(this);
10493
prefixq(dst);
10494
emit_arith_operand(0x81, as_Register(1), dst, imm32);
10495
}
10496
10497
void Assembler::orq(Address dst, Register src) {
10498
InstructionMark im(this);
10499
emit_int16(get_prefixq(dst, src), (unsigned char)0x09);
10500
emit_operand(src, dst);
10501
}
10502
10503
void Assembler::orq(Register dst, int32_t imm32) {
10504
(void) prefixq_and_encode(dst->encoding());
10505
emit_arith(0x81, 0xC8, dst, imm32);
10506
}
10507
10508
void Assembler::orq(Register dst, Address src) {
10509
InstructionMark im(this);
10510
emit_int16(get_prefixq(src, dst), 0x0B);
10511
emit_operand(dst, src);
10512
}
10513
10514
void Assembler::orq(Register dst, Register src) {
10515
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10516
emit_arith(0x0B, 0xC0, dst, src);
10517
}
10518
10519
void Assembler::popcntq(Register dst, Address src) {
10520
assert(VM_Version::supports_popcnt(), "must support");
10521
InstructionMark im(this);
10522
emit_int32((unsigned char)0xF3,
10523
get_prefixq(src, dst),
10524
0x0F,
10525
(unsigned char)0xB8);
10526
emit_operand(dst, src);
10527
}
10528
10529
void Assembler::popcntq(Register dst, Register src) {
10530
assert(VM_Version::supports_popcnt(), "must support");
10531
emit_int8((unsigned char)0xF3);
10532
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10533
emit_int24(0x0F, (unsigned char)0xB8, (0xC0 | encode));
10534
}
10535
10536
void Assembler::popq(Address dst) {
10537
InstructionMark im(this);
10538
emit_int16(get_prefixq(dst), (unsigned char)0x8F);
10539
emit_operand(rax, dst);
10540
}
10541
10542
void Assembler::popq(Register dst) {
10543
emit_int8((unsigned char)0x58 | dst->encoding());
10544
}
10545
10546
// Precomputable: popa, pusha, vzeroupper
10547
10548
// The result of these routines are invariant from one invocation to another
10549
// invocation for the duration of a run. Caching the result on bootstrap
10550
// and copying it out on subsequent invocations can thus be beneficial
10551
static bool precomputed = false;
10552
10553
static u_char* popa_code = NULL;
10554
static int popa_len = 0;
10555
10556
static u_char* pusha_code = NULL;
10557
static int pusha_len = 0;
10558
10559
static u_char* vzup_code = NULL;
10560
static int vzup_len = 0;
10561
10562
void Assembler::precompute_instructions() {
10563
assert(!Universe::is_fully_initialized(), "must still be single threaded");
10564
guarantee(!precomputed, "only once");
10565
precomputed = true;
10566
ResourceMark rm;
10567
10568
// Make a temporary buffer big enough for the routines we're capturing
10569
int size = 256;
10570
char* tmp_code = NEW_RESOURCE_ARRAY(char, size);
10571
CodeBuffer buffer((address)tmp_code, size);
10572
MacroAssembler masm(&buffer);
10573
10574
address begin_popa = masm.code_section()->end();
10575
masm.popa_uncached();
10576
address end_popa = masm.code_section()->end();
10577
masm.pusha_uncached();
10578
address end_pusha = masm.code_section()->end();
10579
masm.vzeroupper_uncached();
10580
address end_vzup = masm.code_section()->end();
10581
10582
// Save the instructions to permanent buffers.
10583
popa_len = (int)(end_popa - begin_popa);
10584
popa_code = NEW_C_HEAP_ARRAY(u_char, popa_len, mtInternal);
10585
memcpy(popa_code, begin_popa, popa_len);
10586
10587
pusha_len = (int)(end_pusha - end_popa);
10588
pusha_code = NEW_C_HEAP_ARRAY(u_char, pusha_len, mtInternal);
10589
memcpy(pusha_code, end_popa, pusha_len);
10590
10591
vzup_len = (int)(end_vzup - end_pusha);
10592
if (vzup_len > 0) {
10593
vzup_code = NEW_C_HEAP_ARRAY(u_char, vzup_len, mtInternal);
10594
memcpy(vzup_code, end_pusha, vzup_len);
10595
} else {
10596
vzup_code = pusha_code; // dummy
10597
}
10598
10599
assert(masm.code()->total_oop_size() == 0 &&
10600
masm.code()->total_metadata_size() == 0 &&
10601
masm.code()->total_relocation_size() == 0,
10602
"pre-computed code can't reference oops, metadata or contain relocations");
10603
}
10604
10605
static void emit_copy(CodeSection* code_section, u_char* src, int src_len) {
10606
assert(src != NULL, "code to copy must have been pre-computed");
10607
assert(code_section->limit() - code_section->end() > src_len, "code buffer not large enough");
10608
address end = code_section->end();
10609
memcpy(end, src, src_len);
10610
code_section->set_end(end + src_len);
10611
}
10612
10613
void Assembler::popa() { // 64bit
10614
emit_copy(code_section(), popa_code, popa_len);
10615
}
10616
10617
void Assembler::popa_uncached() { // 64bit
10618
movq(r15, Address(rsp, 0));
10619
movq(r14, Address(rsp, wordSize));
10620
movq(r13, Address(rsp, 2 * wordSize));
10621
movq(r12, Address(rsp, 3 * wordSize));
10622
movq(r11, Address(rsp, 4 * wordSize));
10623
movq(r10, Address(rsp, 5 * wordSize));
10624
movq(r9, Address(rsp, 6 * wordSize));
10625
movq(r8, Address(rsp, 7 * wordSize));
10626
movq(rdi, Address(rsp, 8 * wordSize));
10627
movq(rsi, Address(rsp, 9 * wordSize));
10628
movq(rbp, Address(rsp, 10 * wordSize));
10629
// Skip rsp as it is restored automatically to the value
10630
// before the corresponding pusha when popa is done.
10631
movq(rbx, Address(rsp, 12 * wordSize));
10632
movq(rdx, Address(rsp, 13 * wordSize));
10633
movq(rcx, Address(rsp, 14 * wordSize));
10634
movq(rax, Address(rsp, 15 * wordSize));
10635
10636
addq(rsp, 16 * wordSize);
10637
}
10638
10639
// Does not actually store the value of rsp on the stack.
10640
// The slot for rsp just contains an arbitrary value.
10641
void Assembler::pusha() { // 64bit
10642
emit_copy(code_section(), pusha_code, pusha_len);
10643
}
10644
10645
// Does not actually store the value of rsp on the stack.
10646
// The slot for rsp just contains an arbitrary value.
10647
void Assembler::pusha_uncached() { // 64bit
10648
subq(rsp, 16 * wordSize);
10649
10650
movq(Address(rsp, 15 * wordSize), rax);
10651
movq(Address(rsp, 14 * wordSize), rcx);
10652
movq(Address(rsp, 13 * wordSize), rdx);
10653
movq(Address(rsp, 12 * wordSize), rbx);
10654
// Skip rsp as the value is normally not used. There are a few places where
10655
// the original value of rsp needs to be known but that can be computed
10656
// from the value of rsp immediately after pusha (rsp + 16 * wordSize).
10657
movq(Address(rsp, 10 * wordSize), rbp);
10658
movq(Address(rsp, 9 * wordSize), rsi);
10659
movq(Address(rsp, 8 * wordSize), rdi);
10660
movq(Address(rsp, 7 * wordSize), r8);
10661
movq(Address(rsp, 6 * wordSize), r9);
10662
movq(Address(rsp, 5 * wordSize), r10);
10663
movq(Address(rsp, 4 * wordSize), r11);
10664
movq(Address(rsp, 3 * wordSize), r12);
10665
movq(Address(rsp, 2 * wordSize), r13);
10666
movq(Address(rsp, wordSize), r14);
10667
movq(Address(rsp, 0), r15);
10668
}
10669
10670
void Assembler::vzeroupper() {
10671
emit_copy(code_section(), vzup_code, vzup_len);
10672
}
10673
10674
void Assembler::pushq(Address src) {
10675
InstructionMark im(this);
10676
emit_int16(get_prefixq(src), (unsigned char)0xFF);
10677
emit_operand(rsi, src);
10678
}
10679
10680
void Assembler::rclq(Register dst, int imm8) {
10681
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10682
int encode = prefixq_and_encode(dst->encoding());
10683
if (imm8 == 1) {
10684
emit_int16((unsigned char)0xD1, (0xD0 | encode));
10685
} else {
10686
emit_int24((unsigned char)0xC1, (0xD0 | encode), imm8);
10687
}
10688
}
10689
10690
void Assembler::rcrq(Register dst, int imm8) {
10691
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10692
int encode = prefixq_and_encode(dst->encoding());
10693
if (imm8 == 1) {
10694
emit_int16((unsigned char)0xD1, (0xD8 | encode));
10695
} else {
10696
emit_int24((unsigned char)0xC1, (0xD8 | encode), imm8);
10697
}
10698
}
10699
10700
10701
void Assembler::rorxq(Register dst, Register src, int imm8) {
10702
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
10703
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10704
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
10705
emit_int24((unsigned char)0xF0, (0xC0 | encode), imm8);
10706
}
10707
10708
void Assembler::rorxd(Register dst, Register src, int imm8) {
10709
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
10710
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10711
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
10712
emit_int24((unsigned char)0xF0, (0xC0 | encode), imm8);
10713
}
10714
10715
#ifdef _LP64
10716
void Assembler::salq(Address dst, int imm8) {
10717
InstructionMark im(this);
10718
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10719
if (imm8 == 1) {
10720
emit_int16(get_prefixq(dst), (unsigned char)0xD1);
10721
emit_operand(as_Register(4), dst);
10722
}
10723
else {
10724
emit_int16(get_prefixq(dst), (unsigned char)0xC1);
10725
emit_operand(as_Register(4), dst);
10726
emit_int8(imm8);
10727
}
10728
}
10729
10730
void Assembler::salq(Address dst) {
10731
InstructionMark im(this);
10732
emit_int16(get_prefixq(dst), (unsigned char)0xD3);
10733
emit_operand(as_Register(4), dst);
10734
}
10735
10736
void Assembler::salq(Register dst, int imm8) {
10737
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10738
int encode = prefixq_and_encode(dst->encoding());
10739
if (imm8 == 1) {
10740
emit_int16((unsigned char)0xD1, (0xE0 | encode));
10741
} else {
10742
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
10743
}
10744
}
10745
10746
void Assembler::salq(Register dst) {
10747
int encode = prefixq_and_encode(dst->encoding());
10748
emit_int16((unsigned char)0xD3, (0xE0 | encode));
10749
}
10750
10751
void Assembler::sarq(Address dst, int imm8) {
10752
InstructionMark im(this);
10753
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10754
if (imm8 == 1) {
10755
emit_int16(get_prefixq(dst), (unsigned char)0xD1);
10756
emit_operand(as_Register(7), dst);
10757
}
10758
else {
10759
emit_int16(get_prefixq(dst), (unsigned char)0xC1);
10760
emit_operand(as_Register(7), dst);
10761
emit_int8(imm8);
10762
}
10763
}
10764
10765
void Assembler::sarq(Address dst) {
10766
InstructionMark im(this);
10767
emit_int16(get_prefixq(dst), (unsigned char)0xD3);
10768
emit_operand(as_Register(7), dst);
10769
}
10770
10771
void Assembler::sarq(Register dst, int imm8) {
10772
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10773
int encode = prefixq_and_encode(dst->encoding());
10774
if (imm8 == 1) {
10775
emit_int16((unsigned char)0xD1, (0xF8 | encode));
10776
} else {
10777
emit_int24((unsigned char)0xC1, (0xF8 | encode), imm8);
10778
}
10779
}
10780
10781
void Assembler::sarq(Register dst) {
10782
int encode = prefixq_and_encode(dst->encoding());
10783
emit_int16((unsigned char)0xD3, (0xF8 | encode));
10784
}
10785
#endif
10786
10787
void Assembler::sbbq(Address dst, int32_t imm32) {
10788
InstructionMark im(this);
10789
prefixq(dst);
10790
emit_arith_operand(0x81, rbx, dst, imm32);
10791
}
10792
10793
void Assembler::sbbq(Register dst, int32_t imm32) {
10794
(void) prefixq_and_encode(dst->encoding());
10795
emit_arith(0x81, 0xD8, dst, imm32);
10796
}
10797
10798
void Assembler::sbbq(Register dst, Address src) {
10799
InstructionMark im(this);
10800
emit_int16(get_prefixq(src, dst), 0x1B);
10801
emit_operand(dst, src);
10802
}
10803
10804
void Assembler::sbbq(Register dst, Register src) {
10805
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10806
emit_arith(0x1B, 0xC0, dst, src);
10807
}
10808
10809
void Assembler::shlq(Register dst, int imm8) {
10810
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10811
int encode = prefixq_and_encode(dst->encoding());
10812
if (imm8 == 1) {
10813
emit_int16((unsigned char)0xD1, (0xE0 | encode));
10814
} else {
10815
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
10816
}
10817
}
10818
10819
void Assembler::shlq(Register dst) {
10820
int encode = prefixq_and_encode(dst->encoding());
10821
emit_int16((unsigned char)0xD3, (0xE0 | encode));
10822
}
10823
10824
void Assembler::shrq(Register dst, int imm8) {
10825
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10826
int encode = prefixq_and_encode(dst->encoding());
10827
if (imm8 == 1) {
10828
emit_int16((unsigned char)0xD1, (0xE8 | encode));
10829
}
10830
else {
10831
emit_int24((unsigned char)0xC1, (0xE8 | encode), imm8);
10832
}
10833
}
10834
10835
void Assembler::shrq(Register dst) {
10836
int encode = prefixq_and_encode(dst->encoding());
10837
emit_int16((unsigned char)0xD3, 0xE8 | encode);
10838
}
10839
10840
void Assembler::shrq(Address dst) {
10841
InstructionMark im(this);
10842
emit_int16(get_prefixq(dst), (unsigned char)0xD3);
10843
emit_operand(as_Register(5), dst);
10844
}
10845
10846
void Assembler::shrq(Address dst, int imm8) {
10847
InstructionMark im(this);
10848
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10849
if (imm8 == 1) {
10850
emit_int16(get_prefixq(dst), (unsigned char)0xD1);
10851
emit_operand(as_Register(5), dst);
10852
}
10853
else {
10854
emit_int16(get_prefixq(dst), (unsigned char)0xC1);
10855
emit_operand(as_Register(5), dst);
10856
emit_int8(imm8);
10857
}
10858
}
10859
10860
void Assembler::subq(Address dst, int32_t imm32) {
10861
InstructionMark im(this);
10862
prefixq(dst);
10863
emit_arith_operand(0x81, rbp, dst, imm32);
10864
}
10865
10866
void Assembler::subq(Address dst, Register src) {
10867
InstructionMark im(this);
10868
emit_int16(get_prefixq(dst, src), 0x29);
10869
emit_operand(src, dst);
10870
}
10871
10872
void Assembler::subq(Register dst, int32_t imm32) {
10873
(void) prefixq_and_encode(dst->encoding());
10874
emit_arith(0x81, 0xE8, dst, imm32);
10875
}
10876
10877
// Force generation of a 4 byte immediate value even if it fits into 8bit
10878
void Assembler::subq_imm32(Register dst, int32_t imm32) {
10879
(void) prefixq_and_encode(dst->encoding());
10880
emit_arith_imm32(0x81, 0xE8, dst, imm32);
10881
}
10882
10883
void Assembler::subq(Register dst, Address src) {
10884
InstructionMark im(this);
10885
emit_int16(get_prefixq(src, dst), 0x2B);
10886
emit_operand(dst, src);
10887
}
10888
10889
void Assembler::subq(Register dst, Register src) {
10890
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10891
emit_arith(0x2B, 0xC0, dst, src);
10892
}
10893
10894
void Assembler::testq(Address dst, int32_t imm32) {
10895
InstructionMark im(this);
10896
emit_int16(get_prefixq(dst), (unsigned char)0xF7);
10897
emit_operand(as_Register(0), dst);
10898
emit_int32(imm32);
10899
}
10900
10901
void Assembler::testq(Register dst, int32_t imm32) {
10902
// not using emit_arith because test
10903
// doesn't support sign-extension of
10904
// 8bit operands
10905
int encode = dst->encoding();
10906
encode = prefixq_and_encode(encode);
10907
emit_int16((unsigned char)0xF7, (0xC0 | encode));
10908
emit_int32(imm32);
10909
}
10910
10911
void Assembler::testq(Register dst, Register src) {
10912
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10913
emit_arith(0x85, 0xC0, dst, src);
10914
}
10915
10916
void Assembler::testq(Register dst, Address src) {
10917
InstructionMark im(this);
10918
emit_int16(get_prefixq(src, dst), (unsigned char)0x85);
10919
emit_operand(dst, src);
10920
}
10921
10922
void Assembler::xaddq(Address dst, Register src) {
10923
InstructionMark im(this);
10924
emit_int24(get_prefixq(dst, src), 0x0F, (unsigned char)0xC1);
10925
emit_operand(src, dst);
10926
}
10927
10928
void Assembler::xchgq(Register dst, Address src) {
10929
InstructionMark im(this);
10930
emit_int16(get_prefixq(src, dst), (unsigned char)0x87);
10931
emit_operand(dst, src);
10932
}
10933
10934
void Assembler::xchgq(Register dst, Register src) {
10935
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10936
emit_int16((unsigned char)0x87, (0xc0 | encode));
10937
}
10938
10939
void Assembler::xorq(Register dst, Register src) {
10940
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10941
emit_arith(0x33, 0xC0, dst, src);
10942
}
10943
10944
void Assembler::xorq(Register dst, Address src) {
10945
InstructionMark im(this);
10946
emit_int16(get_prefixq(src, dst), 0x33);
10947
emit_operand(dst, src);
10948
}
10949
10950
void Assembler::xorq(Register dst, int32_t imm32) {
10951
(void) prefixq_and_encode(dst->encoding());
10952
emit_arith(0x81, 0xF0, dst, imm32);
10953
}
10954
10955
void Assembler::xorq(Address dst, int32_t imm32) {
10956
InstructionMark im(this);
10957
prefixq(dst);
10958
emit_arith_operand(0x81, as_Register(6), dst, imm32);
10959
}
10960
10961
void Assembler::xorq(Address dst, Register src) {
10962
InstructionMark im(this);
10963
emit_int16(get_prefixq(dst, src), 0x31);
10964
emit_operand(src, dst);
10965
}
10966
10967
#endif // !LP64
10968
10969
void InstructionAttr::set_address_attributes(int tuple_type, int input_size_in_bits) {
10970
if (VM_Version::supports_evex()) {
10971
_tuple_type = tuple_type;
10972
_input_size_in_bits = input_size_in_bits;
10973
}
10974
}
10975
10976