Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/cpu/x86/assembler_x86.cpp
64440 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 = RelocationHolder::none;
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
void Assembler::knotql(KRegister dst, KRegister src) {
2576
assert(VM_Version::supports_avx512bw(), "");
2577
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2578
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2579
emit_int16(0x44, (0xC0 | encode));
2580
}
2581
2582
// This instruction produces ZF or CF flags
2583
void Assembler::kortestbl(KRegister src1, KRegister src2) {
2584
assert(VM_Version::supports_avx512dq(), "");
2585
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2586
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2587
emit_int16((unsigned char)0x98, (0xC0 | encode));
2588
}
2589
2590
// This instruction produces ZF or CF flags
2591
void Assembler::kortestwl(KRegister src1, KRegister src2) {
2592
assert(VM_Version::supports_evex(), "");
2593
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2594
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2595
emit_int16((unsigned char)0x98, (0xC0 | encode));
2596
}
2597
2598
// This instruction produces ZF or CF flags
2599
void Assembler::kortestdl(KRegister src1, KRegister src2) {
2600
assert(VM_Version::supports_avx512bw(), "");
2601
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2602
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2603
emit_int16((unsigned char)0x98, (0xC0 | encode));
2604
}
2605
2606
// This instruction produces ZF or CF flags
2607
void Assembler::kortestql(KRegister src1, KRegister src2) {
2608
assert(VM_Version::supports_avx512bw(), "");
2609
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2610
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
2611
emit_int16((unsigned char)0x98, (0xC0 | encode));
2612
}
2613
2614
// This instruction produces ZF or CF flags
2615
void Assembler::ktestql(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::ktestq(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_NONE, VEX_OPCODE_0F, &attributes);
2626
emit_int16((unsigned char)0x99, (0xC0 | encode));
2627
}
2628
2629
void Assembler::ktestd(KRegister src1, KRegister src2) {
2630
assert(VM_Version::supports_avx512bw(), "");
2631
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
2632
int encode = vex_prefix_and_encode(src1->encoding(), 0, src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2633
emit_int16((unsigned char)0x99, (0xC0 | encode));
2634
}
2635
2636
void Assembler::movb(Address dst, int imm8) {
2637
InstructionMark im(this);
2638
prefix(dst);
2639
emit_int8((unsigned char)0xC6);
2640
emit_operand(rax, dst, 1);
2641
emit_int8(imm8);
2642
}
2643
2644
2645
void Assembler::movb(Address dst, Register src) {
2646
assert(src->has_byte_register(), "must have byte register");
2647
InstructionMark im(this);
2648
prefix(dst, src, true);
2649
emit_int8((unsigned char)0x88);
2650
emit_operand(src, dst);
2651
}
2652
2653
void Assembler::movdl(XMMRegister dst, Register 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
int encode = simd_prefix_and_encode(dst, xnoreg, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2657
emit_int16(0x6E, (0xC0 | encode));
2658
}
2659
2660
void Assembler::movdl(Register dst, XMMRegister src) {
2661
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2662
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2663
// swap src/dst to get correct prefix
2664
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2665
emit_int16(0x7E, (0xC0 | encode));
2666
}
2667
2668
void Assembler::movdl(XMMRegister dst, Address src) {
2669
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2670
InstructionMark im(this);
2671
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2672
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
2673
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2674
emit_int8(0x6E);
2675
emit_operand(dst, src);
2676
}
2677
2678
void Assembler::movdl(Address dst, XMMRegister src) {
2679
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2680
InstructionMark im(this);
2681
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
2682
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
2683
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2684
emit_int8(0x7E);
2685
emit_operand(src, dst);
2686
}
2687
2688
void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
2689
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2690
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2691
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2692
emit_int16(0x6F, (0xC0 | encode));
2693
}
2694
2695
void Assembler::movdqa(XMMRegister dst, Address src) {
2696
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2697
InstructionMark im(this);
2698
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2699
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2700
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
2701
emit_int8(0x6F);
2702
emit_operand(dst, src);
2703
}
2704
2705
void Assembler::movdqu(XMMRegister dst, Address src) {
2706
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2707
InstructionMark im(this);
2708
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2709
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2710
simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2711
emit_int8(0x6F);
2712
emit_operand(dst, src);
2713
}
2714
2715
void Assembler::movdqu(XMMRegister dst, XMMRegister src) {
2716
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2717
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2718
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2719
emit_int16(0x6F, (0xC0 | encode));
2720
}
2721
2722
void Assembler::movdqu(Address dst, XMMRegister src) {
2723
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2724
InstructionMark im(this);
2725
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2726
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2727
attributes.reset_is_clear_context();
2728
simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2729
emit_int8(0x7F);
2730
emit_operand(src, dst);
2731
}
2732
2733
// Move Unaligned 256bit Vector
2734
void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
2735
assert(UseAVX > 0, "");
2736
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2737
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2738
emit_int16(0x6F, (0xC0 | encode));
2739
}
2740
2741
void Assembler::vmovdqu(XMMRegister dst, Address src) {
2742
assert(UseAVX > 0, "");
2743
InstructionMark im(this);
2744
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2745
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2746
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2747
emit_int8(0x6F);
2748
emit_operand(dst, src);
2749
}
2750
2751
void Assembler::vmovdqu(Address dst, XMMRegister src) {
2752
assert(UseAVX > 0, "");
2753
InstructionMark im(this);
2754
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
2755
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2756
attributes.reset_is_clear_context();
2757
// swap src<->dst for encoding
2758
assert(src != xnoreg, "sanity");
2759
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2760
emit_int8(0x7F);
2761
emit_operand(src, dst);
2762
}
2763
2764
// Move Unaligned EVEX enabled Vector (programmable : 8,16,32,64)
2765
void Assembler::evmovdqub(XMMRegister dst, XMMRegister src, bool merge, int vector_len) {
2766
assert(VM_Version::supports_evex(), "");
2767
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2768
attributes.set_is_evex_instruction();
2769
if (merge) {
2770
attributes.reset_is_clear_context();
2771
}
2772
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2773
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2774
emit_int16(0x6F, (0xC0 | encode));
2775
}
2776
2777
void Assembler::evmovdqub(XMMRegister dst, Address src, bool merge, int vector_len) {
2778
assert(VM_Version::supports_evex(), "");
2779
InstructionMark im(this);
2780
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2781
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2782
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2783
attributes.set_is_evex_instruction();
2784
if (merge) {
2785
attributes.reset_is_clear_context();
2786
}
2787
vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2788
emit_int8(0x6F);
2789
emit_operand(dst, src);
2790
}
2791
2792
void Assembler::evmovdqub(Address dst, XMMRegister src, bool merge, int vector_len) {
2793
assert(VM_Version::supports_evex(), "");
2794
assert(src != xnoreg, "sanity");
2795
InstructionMark im(this);
2796
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2797
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2798
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2799
attributes.set_is_evex_instruction();
2800
if (merge) {
2801
attributes.reset_is_clear_context();
2802
}
2803
vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2804
emit_int8(0x7F);
2805
emit_operand(src, dst);
2806
}
2807
2808
void Assembler::evmovdqub(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2809
assert(VM_Version::supports_avx512vlbw(), "");
2810
InstructionMark im(this);
2811
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2812
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2813
attributes.set_embedded_opmask_register_specifier(mask);
2814
attributes.set_is_evex_instruction();
2815
if (merge) {
2816
attributes.reset_is_clear_context();
2817
}
2818
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2819
emit_int8(0x6F);
2820
emit_operand(dst, src);
2821
}
2822
2823
void Assembler::evmovdqub(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2824
assert(VM_Version::supports_avx512vlbw(), "");
2825
assert(src != xnoreg, "sanity");
2826
InstructionMark im(this);
2827
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2828
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2829
attributes.set_embedded_opmask_register_specifier(mask);
2830
attributes.set_is_evex_instruction();
2831
if (merge) {
2832
attributes.reset_is_clear_context();
2833
}
2834
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2835
emit_int8(0x7F);
2836
emit_operand(src, dst);
2837
}
2838
2839
void Assembler::evmovdquw(XMMRegister dst, Address src, bool merge, int vector_len) {
2840
assert(VM_Version::supports_evex(), "");
2841
InstructionMark im(this);
2842
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2843
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2844
attributes.set_is_evex_instruction();
2845
if (merge) {
2846
attributes.reset_is_clear_context();
2847
}
2848
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2849
vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2850
emit_int8(0x6F);
2851
emit_operand(dst, src);
2852
}
2853
2854
void Assembler::evmovdquw(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2855
assert(VM_Version::supports_avx512vlbw(), "");
2856
InstructionMark im(this);
2857
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2858
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2859
attributes.set_embedded_opmask_register_specifier(mask);
2860
attributes.set_is_evex_instruction();
2861
if (merge) {
2862
attributes.reset_is_clear_context();
2863
}
2864
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2865
emit_int8(0x6F);
2866
emit_operand(dst, src);
2867
}
2868
2869
void Assembler::evmovdquw(Address dst, XMMRegister src, bool merge, int vector_len) {
2870
assert(VM_Version::supports_evex(), "");
2871
assert(src != xnoreg, "sanity");
2872
InstructionMark im(this);
2873
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
2874
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2875
attributes.set_is_evex_instruction();
2876
if (merge) {
2877
attributes.reset_is_clear_context();
2878
}
2879
int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3;
2880
vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes);
2881
emit_int8(0x7F);
2882
emit_operand(src, dst);
2883
}
2884
2885
void Assembler::evmovdquw(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2886
assert(VM_Version::supports_avx512vlbw(), "");
2887
assert(src != xnoreg, "sanity");
2888
InstructionMark im(this);
2889
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2890
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2891
attributes.set_embedded_opmask_register_specifier(mask);
2892
attributes.set_is_evex_instruction();
2893
if (merge) {
2894
attributes.reset_is_clear_context();
2895
}
2896
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
2897
emit_int8(0x7F);
2898
emit_operand(src, dst);
2899
}
2900
2901
void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) {
2902
// Unmasked instruction
2903
evmovdqul(dst, k0, src, /*merge*/ false, vector_len);
2904
}
2905
2906
void Assembler::evmovdqul(XMMRegister dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2907
assert(VM_Version::supports_evex(), "");
2908
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2909
attributes.set_embedded_opmask_register_specifier(mask);
2910
attributes.set_is_evex_instruction();
2911
if (merge) {
2912
attributes.reset_is_clear_context();
2913
}
2914
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2915
emit_int16(0x6F, (0xC0 | encode));
2916
}
2917
2918
void Assembler::evmovdqul(XMMRegister dst, Address src, int vector_len) {
2919
// Unmasked instruction
2920
evmovdqul(dst, k0, src, /*merge*/ false, vector_len);
2921
}
2922
2923
void Assembler::evmovdqul(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2924
assert(VM_Version::supports_evex(), "");
2925
InstructionMark im(this);
2926
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false , /* uses_vl */ true);
2927
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2928
attributes.set_embedded_opmask_register_specifier(mask);
2929
attributes.set_is_evex_instruction();
2930
if (merge) {
2931
attributes.reset_is_clear_context();
2932
}
2933
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2934
emit_int8(0x6F);
2935
emit_operand(dst, src);
2936
}
2937
2938
void Assembler::evmovdqul(Address dst, XMMRegister src, int vector_len) {
2939
// Unmasked isntruction
2940
evmovdqul(dst, k0, src, /*merge*/ true, vector_len);
2941
}
2942
2943
void Assembler::evmovdqul(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2944
assert(VM_Version::supports_evex(), "");
2945
assert(src != xnoreg, "sanity");
2946
InstructionMark im(this);
2947
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2948
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2949
attributes.set_embedded_opmask_register_specifier(mask);
2950
attributes.set_is_evex_instruction();
2951
if (merge) {
2952
attributes.reset_is_clear_context();
2953
}
2954
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2955
emit_int8(0x7F);
2956
emit_operand(src, dst);
2957
}
2958
2959
void Assembler::evmovdquq(XMMRegister dst, XMMRegister src, int vector_len) {
2960
// Unmasked instruction
2961
if (dst->encoding() == src->encoding()) return;
2962
evmovdquq(dst, k0, src, /*merge*/ false, vector_len);
2963
}
2964
2965
void Assembler::evmovdquq(XMMRegister dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
2966
assert(VM_Version::supports_evex(), "");
2967
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2968
attributes.set_embedded_opmask_register_specifier(mask);
2969
attributes.set_is_evex_instruction();
2970
if (merge) {
2971
attributes.reset_is_clear_context();
2972
}
2973
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2974
emit_int16(0x6F, (0xC0 | encode));
2975
}
2976
2977
void Assembler::evmovdquq(XMMRegister dst, Address src, int vector_len) {
2978
// Unmasked instruction
2979
evmovdquq(dst, k0, src, /*merge*/ false, vector_len);
2980
}
2981
2982
void Assembler::evmovdquq(XMMRegister dst, KRegister mask, Address src, bool merge, int vector_len) {
2983
assert(VM_Version::supports_evex(), "");
2984
InstructionMark im(this);
2985
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
2986
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
2987
attributes.set_embedded_opmask_register_specifier(mask);
2988
attributes.set_is_evex_instruction();
2989
if (merge) {
2990
attributes.reset_is_clear_context();
2991
}
2992
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
2993
emit_int8(0x6F);
2994
emit_operand(dst, src);
2995
}
2996
2997
void Assembler::evmovdquq(Address dst, XMMRegister src, int vector_len) {
2998
// Unmasked instruction
2999
evmovdquq(dst, k0, src, /*merge*/ true, vector_len);
3000
}
3001
3002
void Assembler::evmovdquq(Address dst, KRegister mask, XMMRegister src, bool merge, int vector_len) {
3003
assert(VM_Version::supports_evex(), "");
3004
assert(src != xnoreg, "sanity");
3005
InstructionMark im(this);
3006
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
3007
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3008
attributes.set_embedded_opmask_register_specifier(mask);
3009
if (merge) {
3010
attributes.reset_is_clear_context();
3011
}
3012
attributes.set_is_evex_instruction();
3013
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3014
emit_int8(0x7F);
3015
emit_operand(src, dst);
3016
}
3017
3018
// Uses zero extension on 64bit
3019
3020
void Assembler::movl(Register dst, int32_t imm32) {
3021
int encode = prefix_and_encode(dst->encoding());
3022
emit_int8(0xB8 | encode);
3023
emit_int32(imm32);
3024
}
3025
3026
void Assembler::movl(Register dst, Register src) {
3027
int encode = prefix_and_encode(dst->encoding(), src->encoding());
3028
emit_int16((unsigned char)0x8B, (0xC0 | encode));
3029
}
3030
3031
void Assembler::movl(Register dst, Address src) {
3032
InstructionMark im(this);
3033
prefix(src, dst);
3034
emit_int8((unsigned char)0x8B);
3035
emit_operand(dst, src);
3036
}
3037
3038
void Assembler::movl(Address dst, int32_t imm32) {
3039
InstructionMark im(this);
3040
prefix(dst);
3041
emit_int8((unsigned char)0xC7);
3042
emit_operand(rax, dst, 4);
3043
emit_int32(imm32);
3044
}
3045
3046
void Assembler::movl(Address dst, Register src) {
3047
InstructionMark im(this);
3048
prefix(dst, src);
3049
emit_int8((unsigned char)0x89);
3050
emit_operand(src, dst);
3051
}
3052
3053
// New cpus require to use movsd and movss to avoid partial register stall
3054
// when loading from memory. But for old Opteron use movlpd instead of movsd.
3055
// The selection is done in MacroAssembler::movdbl() and movflt().
3056
void Assembler::movlpd(XMMRegister dst, Address src) {
3057
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3058
InstructionMark im(this);
3059
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3060
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3061
attributes.set_rex_vex_w_reverted();
3062
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3063
emit_int8(0x12);
3064
emit_operand(dst, src);
3065
}
3066
3067
void Assembler::movq(XMMRegister dst, Address src) {
3068
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3069
InstructionMark im(this);
3070
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3071
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3072
attributes.set_rex_vex_w_reverted();
3073
simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3074
emit_int8(0x7E);
3075
emit_operand(dst, src);
3076
}
3077
3078
void Assembler::movq(Address dst, XMMRegister src) {
3079
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3080
InstructionMark im(this);
3081
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3082
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3083
attributes.set_rex_vex_w_reverted();
3084
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3085
emit_int8((unsigned char)0xD6);
3086
emit_operand(src, dst);
3087
}
3088
3089
void Assembler::movq(XMMRegister dst, XMMRegister src) {
3090
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3091
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3092
attributes.set_rex_vex_w_reverted();
3093
int encode = simd_prefix_and_encode(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3094
emit_int16((unsigned char)0xD6, (0xC0 | encode));
3095
}
3096
3097
void Assembler::movq(Register dst, XMMRegister src) {
3098
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3099
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3100
// swap src/dst to get correct prefix
3101
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3102
emit_int16(0x7E, (0xC0 | encode));
3103
}
3104
3105
void Assembler::movq(XMMRegister dst, Register src) {
3106
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3107
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3108
int encode = simd_prefix_and_encode(dst, xnoreg, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3109
emit_int16(0x6E, (0xC0 | encode));
3110
}
3111
3112
void Assembler::movsbl(Register dst, Address src) { // movsxb
3113
InstructionMark im(this);
3114
prefix(src, dst);
3115
emit_int16(0x0F, (unsigned char)0xBE);
3116
emit_operand(dst, src);
3117
}
3118
3119
void Assembler::movsbl(Register dst, Register src) { // movsxb
3120
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
3121
int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
3122
emit_int24(0x0F, (unsigned char)0xBE, (0xC0 | encode));
3123
}
3124
3125
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
3126
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3127
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3128
attributes.set_rex_vex_w_reverted();
3129
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3130
emit_int16(0x10, (0xC0 | encode));
3131
}
3132
3133
void Assembler::movsd(XMMRegister dst, Address src) {
3134
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3135
InstructionMark im(this);
3136
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3137
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3138
attributes.set_rex_vex_w_reverted();
3139
simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3140
emit_int8(0x10);
3141
emit_operand(dst, src);
3142
}
3143
3144
void Assembler::movsd(Address dst, XMMRegister src) {
3145
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3146
InstructionMark im(this);
3147
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3148
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3149
attributes.reset_is_clear_context();
3150
attributes.set_rex_vex_w_reverted();
3151
simd_prefix(src, xnoreg, dst, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3152
emit_int8(0x11);
3153
emit_operand(src, dst);
3154
}
3155
3156
void Assembler::movss(XMMRegister dst, XMMRegister src) {
3157
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3158
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3159
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3160
emit_int16(0x10, (0xC0 | encode));
3161
}
3162
3163
void Assembler::movss(XMMRegister dst, Address src) {
3164
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3165
InstructionMark im(this);
3166
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3167
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
3168
simd_prefix(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3169
emit_int8(0x10);
3170
emit_operand(dst, src);
3171
}
3172
3173
void Assembler::movss(Address dst, XMMRegister src) {
3174
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3175
InstructionMark im(this);
3176
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3177
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
3178
attributes.reset_is_clear_context();
3179
simd_prefix(src, xnoreg, dst, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3180
emit_int8(0x11);
3181
emit_operand(src, dst);
3182
}
3183
3184
void Assembler::movswl(Register dst, Address src) { // movsxw
3185
InstructionMark im(this);
3186
prefix(src, dst);
3187
emit_int16(0x0F, (unsigned char)0xBF);
3188
emit_operand(dst, src);
3189
}
3190
3191
void Assembler::movswl(Register dst, Register src) { // movsxw
3192
int encode = prefix_and_encode(dst->encoding(), src->encoding());
3193
emit_int24(0x0F, (unsigned char)0xBF, (0xC0 | encode));
3194
}
3195
3196
void Assembler::movw(Address dst, int imm16) {
3197
InstructionMark im(this);
3198
3199
emit_int8(0x66); // switch to 16-bit mode
3200
prefix(dst);
3201
emit_int8((unsigned char)0xC7);
3202
emit_operand(rax, dst, 2);
3203
emit_int16(imm16);
3204
}
3205
3206
void Assembler::movw(Register dst, Address src) {
3207
InstructionMark im(this);
3208
emit_int8(0x66);
3209
prefix(src, dst);
3210
emit_int8((unsigned char)0x8B);
3211
emit_operand(dst, src);
3212
}
3213
3214
void Assembler::movw(Address dst, Register src) {
3215
InstructionMark im(this);
3216
emit_int8(0x66);
3217
prefix(dst, src);
3218
emit_int8((unsigned char)0x89);
3219
emit_operand(src, dst);
3220
}
3221
3222
void Assembler::movzbl(Register dst, Address src) { // movzxb
3223
InstructionMark im(this);
3224
prefix(src, dst);
3225
emit_int16(0x0F, (unsigned char)0xB6);
3226
emit_operand(dst, src);
3227
}
3228
3229
void Assembler::movzbl(Register dst, Register src) { // movzxb
3230
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
3231
int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
3232
emit_int24(0x0F, (unsigned char)0xB6, 0xC0 | encode);
3233
}
3234
3235
void Assembler::movzwl(Register dst, Address src) { // movzxw
3236
InstructionMark im(this);
3237
prefix(src, dst);
3238
emit_int16(0x0F, (unsigned char)0xB7);
3239
emit_operand(dst, src);
3240
}
3241
3242
void Assembler::movzwl(Register dst, Register src) { // movzxw
3243
int encode = prefix_and_encode(dst->encoding(), src->encoding());
3244
emit_int24(0x0F, (unsigned char)0xB7, 0xC0 | encode);
3245
}
3246
3247
void Assembler::mull(Address src) {
3248
InstructionMark im(this);
3249
prefix(src);
3250
emit_int8((unsigned char)0xF7);
3251
emit_operand(rsp, src);
3252
}
3253
3254
void Assembler::mull(Register src) {
3255
int encode = prefix_and_encode(src->encoding());
3256
emit_int16((unsigned char)0xF7, (0xE0 | encode));
3257
}
3258
3259
void Assembler::mulsd(XMMRegister dst, Address src) {
3260
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3261
InstructionMark im(this);
3262
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3263
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
3264
attributes.set_rex_vex_w_reverted();
3265
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3266
emit_int8(0x59);
3267
emit_operand(dst, src);
3268
}
3269
3270
void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
3271
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3272
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3273
attributes.set_rex_vex_w_reverted();
3274
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
3275
emit_int16(0x59, (0xC0 | encode));
3276
}
3277
3278
void Assembler::mulss(XMMRegister dst, Address src) {
3279
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3280
InstructionMark im(this);
3281
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3282
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
3283
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3284
emit_int8(0x59);
3285
emit_operand(dst, src);
3286
}
3287
3288
void Assembler::mulss(XMMRegister dst, XMMRegister src) {
3289
NOT_LP64(assert(VM_Version::supports_sse(), ""));
3290
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3291
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
3292
emit_int16(0x59, (0xC0 | encode));
3293
}
3294
3295
void Assembler::negl(Register dst) {
3296
int encode = prefix_and_encode(dst->encoding());
3297
emit_int16((unsigned char)0xF7, (0xD8 | encode));
3298
}
3299
3300
void Assembler::negl(Address dst) {
3301
InstructionMark im(this);
3302
prefix(dst);
3303
emit_int8((unsigned char)0xF7);
3304
emit_operand(as_Register(3), dst);
3305
}
3306
3307
void Assembler::nop(int i) {
3308
#ifdef ASSERT
3309
assert(i > 0, " ");
3310
// The fancy nops aren't currently recognized by debuggers making it a
3311
// pain to disassemble code while debugging. If asserts are on clearly
3312
// speed is not an issue so simply use the single byte traditional nop
3313
// to do alignment.
3314
3315
for (; i > 0 ; i--) emit_int8((unsigned char)0x90);
3316
return;
3317
3318
#endif // ASSERT
3319
3320
if (UseAddressNop && VM_Version::is_intel()) {
3321
//
3322
// Using multi-bytes nops "0x0F 0x1F [address]" for Intel
3323
// 1: 0x90
3324
// 2: 0x66 0x90
3325
// 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
3326
// 4: 0x0F 0x1F 0x40 0x00
3327
// 5: 0x0F 0x1F 0x44 0x00 0x00
3328
// 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
3329
// 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3330
// 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3331
// 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3332
// 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3333
// 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3334
3335
// The rest coding is Intel specific - don't use consecutive address nops
3336
3337
// 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3338
// 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3339
// 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3340
// 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3341
3342
while(i >= 15) {
3343
// For Intel don't generate consecutive addess nops (mix with regular nops)
3344
i -= 15;
3345
emit_int24(0x66, 0x66, 0x66);
3346
addr_nop_8();
3347
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3348
}
3349
switch (i) {
3350
case 14:
3351
emit_int8(0x66); // size prefix
3352
case 13:
3353
emit_int8(0x66); // size prefix
3354
case 12:
3355
addr_nop_8();
3356
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3357
break;
3358
case 11:
3359
emit_int8(0x66); // size prefix
3360
case 10:
3361
emit_int8(0x66); // size prefix
3362
case 9:
3363
emit_int8(0x66); // size prefix
3364
case 8:
3365
addr_nop_8();
3366
break;
3367
case 7:
3368
addr_nop_7();
3369
break;
3370
case 6:
3371
emit_int8(0x66); // size prefix
3372
case 5:
3373
addr_nop_5();
3374
break;
3375
case 4:
3376
addr_nop_4();
3377
break;
3378
case 3:
3379
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
3380
emit_int8(0x66); // size prefix
3381
case 2:
3382
emit_int8(0x66); // size prefix
3383
case 1:
3384
emit_int8((unsigned char)0x90);
3385
// nop
3386
break;
3387
default:
3388
assert(i == 0, " ");
3389
}
3390
return;
3391
}
3392
if (UseAddressNop && VM_Version::is_amd_family()) {
3393
//
3394
// Using multi-bytes nops "0x0F 0x1F [address]" for AMD.
3395
// 1: 0x90
3396
// 2: 0x66 0x90
3397
// 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
3398
// 4: 0x0F 0x1F 0x40 0x00
3399
// 5: 0x0F 0x1F 0x44 0x00 0x00
3400
// 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
3401
// 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3402
// 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3403
// 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3404
// 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3405
// 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3406
3407
// The rest coding is AMD specific - use consecutive address nops
3408
3409
// 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
3410
// 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
3411
// 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3412
// 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3413
// 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3414
// Size prefixes (0x66) are added for larger sizes
3415
3416
while(i >= 22) {
3417
i -= 11;
3418
emit_int24(0x66, 0x66, 0x66);
3419
addr_nop_8();
3420
}
3421
// Generate first nop for size between 21-12
3422
switch (i) {
3423
case 21:
3424
i -= 1;
3425
emit_int8(0x66); // size prefix
3426
case 20:
3427
case 19:
3428
i -= 1;
3429
emit_int8(0x66); // size prefix
3430
case 18:
3431
case 17:
3432
i -= 1;
3433
emit_int8(0x66); // size prefix
3434
case 16:
3435
case 15:
3436
i -= 8;
3437
addr_nop_8();
3438
break;
3439
case 14:
3440
case 13:
3441
i -= 7;
3442
addr_nop_7();
3443
break;
3444
case 12:
3445
i -= 6;
3446
emit_int8(0x66); // size prefix
3447
addr_nop_5();
3448
break;
3449
default:
3450
assert(i < 12, " ");
3451
}
3452
3453
// Generate second nop for size between 11-1
3454
switch (i) {
3455
case 11:
3456
emit_int8(0x66); // size prefix
3457
case 10:
3458
emit_int8(0x66); // size prefix
3459
case 9:
3460
emit_int8(0x66); // size prefix
3461
case 8:
3462
addr_nop_8();
3463
break;
3464
case 7:
3465
addr_nop_7();
3466
break;
3467
case 6:
3468
emit_int8(0x66); // size prefix
3469
case 5:
3470
addr_nop_5();
3471
break;
3472
case 4:
3473
addr_nop_4();
3474
break;
3475
case 3:
3476
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
3477
emit_int8(0x66); // size prefix
3478
case 2:
3479
emit_int8(0x66); // size prefix
3480
case 1:
3481
emit_int8((unsigned char)0x90);
3482
// nop
3483
break;
3484
default:
3485
assert(i == 0, " ");
3486
}
3487
return;
3488
}
3489
3490
if (UseAddressNop && VM_Version::is_zx()) {
3491
//
3492
// Using multi-bytes nops "0x0F 0x1F [address]" for ZX
3493
// 1: 0x90
3494
// 2: 0x66 0x90
3495
// 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
3496
// 4: 0x0F 0x1F 0x40 0x00
3497
// 5: 0x0F 0x1F 0x44 0x00 0x00
3498
// 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
3499
// 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
3500
// 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3501
// 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3502
// 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3503
// 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
3504
3505
// The rest coding is ZX specific - don't use consecutive address nops
3506
3507
// 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3508
// 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3509
// 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3510
// 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
3511
3512
while (i >= 15) {
3513
// For ZX don't generate consecutive addess nops (mix with regular nops)
3514
i -= 15;
3515
emit_int24(0x66, 0x66, 0x66);
3516
addr_nop_8();
3517
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3518
}
3519
switch (i) {
3520
case 14:
3521
emit_int8(0x66); // size prefix
3522
case 13:
3523
emit_int8(0x66); // size prefix
3524
case 12:
3525
addr_nop_8();
3526
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3527
break;
3528
case 11:
3529
emit_int8(0x66); // size prefix
3530
case 10:
3531
emit_int8(0x66); // size prefix
3532
case 9:
3533
emit_int8(0x66); // size prefix
3534
case 8:
3535
addr_nop_8();
3536
break;
3537
case 7:
3538
addr_nop_7();
3539
break;
3540
case 6:
3541
emit_int8(0x66); // size prefix
3542
case 5:
3543
addr_nop_5();
3544
break;
3545
case 4:
3546
addr_nop_4();
3547
break;
3548
case 3:
3549
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
3550
emit_int8(0x66); // size prefix
3551
case 2:
3552
emit_int8(0x66); // size prefix
3553
case 1:
3554
emit_int8((unsigned char)0x90);
3555
// nop
3556
break;
3557
default:
3558
assert(i == 0, " ");
3559
}
3560
return;
3561
}
3562
3563
// Using nops with size prefixes "0x66 0x90".
3564
// From AMD Optimization Guide:
3565
// 1: 0x90
3566
// 2: 0x66 0x90
3567
// 3: 0x66 0x66 0x90
3568
// 4: 0x66 0x66 0x66 0x90
3569
// 5: 0x66 0x66 0x90 0x66 0x90
3570
// 6: 0x66 0x66 0x90 0x66 0x66 0x90
3571
// 7: 0x66 0x66 0x66 0x90 0x66 0x66 0x90
3572
// 8: 0x66 0x66 0x66 0x90 0x66 0x66 0x66 0x90
3573
// 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
3574
// 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
3575
//
3576
while (i > 12) {
3577
i -= 4;
3578
emit_int32(0x66, 0x66, 0x66, (unsigned char)0x90);
3579
}
3580
// 1 - 12 nops
3581
if (i > 8) {
3582
if (i > 9) {
3583
i -= 1;
3584
emit_int8(0x66);
3585
}
3586
i -= 3;
3587
emit_int24(0x66, 0x66, (unsigned char)0x90);
3588
}
3589
// 1 - 8 nops
3590
if (i > 4) {
3591
if (i > 6) {
3592
i -= 1;
3593
emit_int8(0x66);
3594
}
3595
i -= 3;
3596
emit_int24(0x66, 0x66, (unsigned char)0x90);
3597
}
3598
switch (i) {
3599
case 4:
3600
emit_int8(0x66);
3601
case 3:
3602
emit_int8(0x66);
3603
case 2:
3604
emit_int8(0x66);
3605
case 1:
3606
emit_int8((unsigned char)0x90);
3607
break;
3608
default:
3609
assert(i == 0, " ");
3610
}
3611
}
3612
3613
void Assembler::notl(Register dst) {
3614
int encode = prefix_and_encode(dst->encoding());
3615
emit_int16((unsigned char)0xF7, (0xD0 | encode));
3616
}
3617
3618
void Assembler::orw(Register dst, Register src) {
3619
(void)prefix_and_encode(dst->encoding(), src->encoding());
3620
emit_arith(0x0B, 0xC0, dst, src);
3621
}
3622
3623
void Assembler::orl(Address dst, int32_t imm32) {
3624
InstructionMark im(this);
3625
prefix(dst);
3626
emit_arith_operand(0x81, rcx, dst, imm32);
3627
}
3628
3629
void Assembler::orl(Register dst, int32_t imm32) {
3630
prefix(dst);
3631
emit_arith(0x81, 0xC8, dst, imm32);
3632
}
3633
3634
void Assembler::orl(Register dst, Address src) {
3635
InstructionMark im(this);
3636
prefix(src, dst);
3637
emit_int8(0x0B);
3638
emit_operand(dst, src);
3639
}
3640
3641
void Assembler::orl(Register dst, Register src) {
3642
(void) prefix_and_encode(dst->encoding(), src->encoding());
3643
emit_arith(0x0B, 0xC0, dst, src);
3644
}
3645
3646
void Assembler::orl(Address dst, Register src) {
3647
InstructionMark im(this);
3648
prefix(dst, src);
3649
emit_int8(0x09);
3650
emit_operand(src, dst);
3651
}
3652
3653
void Assembler::orb(Address dst, int imm8) {
3654
InstructionMark im(this);
3655
prefix(dst);
3656
emit_int8((unsigned char)0x80);
3657
emit_operand(rcx, dst, 1);
3658
emit_int8(imm8);
3659
}
3660
3661
void Assembler::orb(Address dst, Register src) {
3662
InstructionMark im(this);
3663
prefix(dst, src, true);
3664
emit_int8(0x08);
3665
emit_operand(src, dst);
3666
}
3667
3668
void Assembler::packsswb(XMMRegister dst, XMMRegister src) {
3669
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3670
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3671
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3672
emit_int16(0x63, (0xC0 | encode));
3673
}
3674
3675
void Assembler::vpacksswb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3676
assert(UseAVX > 0, "some form of AVX must be enabled");
3677
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3678
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3679
emit_int16(0x63, (0xC0 | encode));
3680
}
3681
3682
void Assembler::packssdw(XMMRegister dst, XMMRegister src) {
3683
assert(VM_Version::supports_sse2(), "");
3684
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3685
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3686
emit_int16(0x6B, (0xC0 | encode));
3687
}
3688
3689
void Assembler::vpackssdw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3690
assert(UseAVX > 0, "some form of AVX must be enabled");
3691
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3692
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3693
emit_int16(0x6B, (0xC0 | encode));
3694
}
3695
3696
void Assembler::packuswb(XMMRegister dst, Address src) {
3697
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3698
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
3699
InstructionMark im(this);
3700
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3701
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
3702
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3703
emit_int8(0x67);
3704
emit_operand(dst, src);
3705
}
3706
3707
void Assembler::packuswb(XMMRegister dst, XMMRegister src) {
3708
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
3709
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3710
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3711
emit_int16(0x67, (0xC0 | encode));
3712
}
3713
3714
void Assembler::vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3715
assert(UseAVX > 0, "some form of AVX must be enabled");
3716
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3717
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3718
emit_int16(0x67, (0xC0 | encode));
3719
}
3720
3721
void Assembler::packusdw(XMMRegister dst, XMMRegister src) {
3722
assert(VM_Version::supports_sse4_1(), "");
3723
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3724
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3725
emit_int16(0x2B, (0xC0 | encode));
3726
}
3727
3728
void Assembler::vpackusdw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3729
assert(UseAVX > 0, "some form of AVX must be enabled");
3730
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3731
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3732
emit_int16(0x2B, (0xC0 | encode));
3733
}
3734
3735
void Assembler::vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3736
assert(VM_Version::supports_avx2(), "");
3737
assert(vector_len != AVX_128bit, "");
3738
// VEX.256.66.0F3A.W1 00 /r ib
3739
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3740
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3741
emit_int24(0x00, (0xC0 | encode), imm8);
3742
}
3743
3744
void Assembler::vpermq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3745
assert(vector_len == AVX_256bit ? VM_Version::supports_avx512vl() :
3746
vector_len == AVX_512bit ? VM_Version::supports_evex() : false, "not supported");
3747
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3748
attributes.set_is_evex_instruction();
3749
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3750
emit_int16(0x36, (0xC0 | encode));
3751
}
3752
3753
void Assembler::vpermb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3754
assert(VM_Version::supports_avx512_vbmi(), "");
3755
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3756
attributes.set_is_evex_instruction();
3757
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3758
emit_int16((unsigned char)0x8D, (0xC0 | encode));
3759
}
3760
3761
void Assembler::vpermw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3762
assert(vector_len == AVX_128bit ? VM_Version::supports_avx512vlbw() :
3763
vector_len == AVX_256bit ? VM_Version::supports_avx512vlbw() :
3764
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : false, "not supported");
3765
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
3766
attributes.set_is_evex_instruction();
3767
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3768
emit_int16((unsigned char)0x8D, (0xC0 | encode));
3769
}
3770
3771
void Assembler::vpermd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3772
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex(), "");
3773
// VEX.NDS.256.66.0F38.W0 36 /r
3774
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3775
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3776
emit_int16(0x36, (0xC0 | encode));
3777
}
3778
3779
void Assembler::vpermd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
3780
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex(), "");
3781
// VEX.NDS.256.66.0F38.W0 36 /r
3782
InstructionMark im(this);
3783
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3784
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3785
emit_int8(0x36);
3786
emit_operand(dst, src);
3787
}
3788
3789
void Assembler::vperm2i128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
3790
assert(VM_Version::supports_avx2(), "");
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(0x46, (0xC0 | encode), imm8);
3794
}
3795
3796
void Assembler::vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
3797
assert(VM_Version::supports_avx(), "");
3798
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3799
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3800
emit_int24(0x06, (0xC0 | encode), imm8);
3801
}
3802
3803
void Assembler::vpermilps(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 */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
3806
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3807
emit_int24(0x04, (0xC0 | encode), imm8);
3808
}
3809
3810
void Assembler::vpermilpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3811
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
3812
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(),/* legacy_mode */ false,/* no_mask_reg */ true, /* uses_vl */ false);
3813
attributes.set_rex_vex_w_reverted();
3814
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3815
emit_int24(0x05, (0xC0 | encode), imm8);
3816
}
3817
3818
void Assembler::vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len) {
3819
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex(), "");
3820
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */false, /* no_mask_reg */ true, /* uses_vl */ false);
3821
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3822
emit_int24(0x01, (0xC0 | encode), imm8);
3823
}
3824
3825
void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3826
assert(VM_Version::supports_evex(), "");
3827
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3828
attributes.set_is_evex_instruction();
3829
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
3830
emit_int16(0x76, (0xC0 | encode));
3831
}
3832
3833
void Assembler::pause() {
3834
emit_int16((unsigned char)0xF3, (unsigned char)0x90);
3835
}
3836
3837
void Assembler::ud2() {
3838
emit_int16(0x0F, 0x0B);
3839
}
3840
3841
void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
3842
assert(VM_Version::supports_sse4_2(), "");
3843
InstructionMark im(this);
3844
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3845
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3846
emit_int8(0x61);
3847
emit_operand(dst, src);
3848
emit_int8(imm8);
3849
}
3850
3851
void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
3852
assert(VM_Version::supports_sse4_2(), "");
3853
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3854
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3855
emit_int24(0x61, (0xC0 | encode), imm8);
3856
}
3857
3858
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3859
void Assembler::pcmpeqb(XMMRegister dst, XMMRegister src) {
3860
assert(VM_Version::supports_sse2(), "");
3861
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3862
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3863
emit_int16(0x74, (0xC0 | encode));
3864
}
3865
3866
void Assembler::vpcmpCCbwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cond_encoding, int vector_len) {
3867
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
3868
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
3869
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3870
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3871
emit_int16(cond_encoding, (0xC0 | encode));
3872
}
3873
3874
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3875
void Assembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3876
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
3877
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
3878
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3879
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3880
emit_int16(0x74, (0xC0 | encode));
3881
}
3882
3883
// In this context, kdst is written the mask used to process the equal components
3884
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
3885
assert(VM_Version::supports_avx512bw(), "");
3886
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3887
attributes.set_is_evex_instruction();
3888
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3889
emit_int16(0x74, (0xC0 | encode));
3890
}
3891
3892
void Assembler::evpcmpgtb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
3893
assert(VM_Version::supports_avx512vlbw(), "");
3894
InstructionMark im(this);
3895
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3896
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3897
attributes.set_is_evex_instruction();
3898
int dst_enc = kdst->encoding();
3899
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3900
emit_int8(0x64);
3901
emit_operand(as_Register(dst_enc), src);
3902
}
3903
3904
void Assembler::evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
3905
assert(VM_Version::supports_avx512vlbw(), "");
3906
InstructionMark im(this);
3907
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
3908
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3909
attributes.reset_is_clear_context();
3910
attributes.set_embedded_opmask_register_specifier(mask);
3911
attributes.set_is_evex_instruction();
3912
int dst_enc = kdst->encoding();
3913
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3914
emit_int8(0x64);
3915
emit_operand(as_Register(dst_enc), src);
3916
}
3917
3918
void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) {
3919
assert(VM_Version::supports_avx512vlbw(), "");
3920
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3921
attributes.set_is_evex_instruction();
3922
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3923
emit_int24(0x3E, (0xC0 | encode), vcc);
3924
}
3925
3926
void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len) {
3927
assert(VM_Version::supports_avx512vlbw(), "");
3928
InstructionMark im(this);
3929
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3930
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3931
attributes.set_is_evex_instruction();
3932
int dst_enc = kdst->encoding();
3933
vex_prefix(src, nds->encoding(), kdst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
3934
emit_int8(0x3E);
3935
emit_operand(as_Register(dst_enc), src);
3936
emit_int8(vcc);
3937
}
3938
3939
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
3940
assert(VM_Version::supports_avx512bw(), "");
3941
InstructionMark im(this);
3942
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3943
attributes.set_is_evex_instruction();
3944
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3945
int dst_enc = kdst->encoding();
3946
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3947
emit_int8(0x74);
3948
emit_operand(as_Register(dst_enc), src);
3949
}
3950
3951
void Assembler::evpcmpeqb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
3952
assert(VM_Version::supports_avx512vlbw(), "");
3953
InstructionMark im(this);
3954
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
3955
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3956
attributes.reset_is_clear_context();
3957
attributes.set_embedded_opmask_register_specifier(mask);
3958
attributes.set_is_evex_instruction();
3959
vex_prefix(src, nds->encoding(), kdst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3960
emit_int8(0x74);
3961
emit_operand(as_Register(kdst->encoding()), src);
3962
}
3963
3964
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3965
void Assembler::pcmpeqw(XMMRegister dst, XMMRegister src) {
3966
assert(VM_Version::supports_sse2(), "");
3967
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3968
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3969
emit_int16(0x75, (0xC0 | encode));
3970
}
3971
3972
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
3973
void Assembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
3974
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
3975
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
3976
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
3977
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3978
emit_int16(0x75, (0xC0 | encode));
3979
}
3980
3981
// In this context, kdst is written the mask used to process the equal components
3982
void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
3983
assert(VM_Version::supports_avx512bw(), "");
3984
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3985
attributes.set_is_evex_instruction();
3986
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3987
emit_int16(0x75, (0xC0 | encode));
3988
}
3989
3990
void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
3991
assert(VM_Version::supports_avx512bw(), "");
3992
InstructionMark im(this);
3993
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
3994
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
3995
attributes.set_is_evex_instruction();
3996
int dst_enc = kdst->encoding();
3997
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
3998
emit_int8(0x75);
3999
emit_operand(as_Register(dst_enc), src);
4000
}
4001
4002
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4003
void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
4004
assert(VM_Version::supports_sse2(), "");
4005
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4006
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4007
emit_int16(0x76, (0xC0 | encode));
4008
}
4009
4010
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4011
void Assembler::vpcmpeqd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4012
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
4013
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
4014
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4015
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4016
emit_int16(0x76, (0xC0 | encode));
4017
}
4018
4019
// In this context, kdst is written the mask used to process the equal components
4020
void Assembler::evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, int vector_len) {
4021
assert(VM_Version::supports_evex(), "");
4022
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4023
attributes.set_is_evex_instruction();
4024
attributes.reset_is_clear_context();
4025
attributes.set_embedded_opmask_register_specifier(mask);
4026
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4027
emit_int16(0x76, (0xC0 | encode));
4028
}
4029
4030
void Assembler::evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len) {
4031
assert(VM_Version::supports_evex(), "");
4032
InstructionMark im(this);
4033
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4034
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
4035
attributes.set_is_evex_instruction();
4036
attributes.reset_is_clear_context();
4037
attributes.set_embedded_opmask_register_specifier(mask);
4038
int dst_enc = kdst->encoding();
4039
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4040
emit_int8(0x76);
4041
emit_operand(as_Register(dst_enc), src);
4042
}
4043
4044
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4045
void Assembler::pcmpeqq(XMMRegister dst, XMMRegister src) {
4046
assert(VM_Version::supports_sse4_1(), "");
4047
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4048
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4049
emit_int16(0x29, (0xC0 | encode));
4050
}
4051
4052
void Assembler::vpcmpCCq(XMMRegister dst, XMMRegister nds, XMMRegister src, int cond_encoding, int vector_len) {
4053
assert(VM_Version::supports_avx(), "");
4054
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4055
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4056
emit_int16(cond_encoding, (0xC0 | encode));
4057
}
4058
4059
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
4060
void Assembler::vpcmpeqq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4061
assert(VM_Version::supports_avx(), "");
4062
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4063
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4064
emit_int16(0x29, (0xC0 | encode));
4065
}
4066
4067
// In this context, kdst is written the mask used to process the equal components
4068
void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
4069
assert(VM_Version::supports_evex(), "");
4070
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4071
attributes.reset_is_clear_context();
4072
attributes.set_is_evex_instruction();
4073
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4074
emit_int16(0x29, (0xC0 | encode));
4075
}
4076
4077
// In this context, kdst is written the mask used to process the equal components
4078
void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, Address src, int vector_len) {
4079
assert(VM_Version::supports_evex(), "");
4080
InstructionMark im(this);
4081
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4082
attributes.reset_is_clear_context();
4083
attributes.set_is_evex_instruction();
4084
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
4085
int dst_enc = kdst->encoding();
4086
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4087
emit_int8(0x29);
4088
emit_operand(as_Register(dst_enc), src);
4089
}
4090
4091
void Assembler::evpmovd2m(KRegister kdst, XMMRegister src, int vector_len) {
4092
assert(UseAVX > 2 && VM_Version::supports_avx512dq(), "");
4093
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
4094
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4095
attributes.set_is_evex_instruction();
4096
int encode = vex_prefix_and_encode(kdst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4097
emit_int16(0x39, (0xC0 | encode));
4098
}
4099
4100
void Assembler::evpmovq2m(KRegister kdst, XMMRegister src, int vector_len) {
4101
assert(UseAVX > 2 && VM_Version::supports_avx512dq(), "");
4102
assert(vector_len == AVX_512bit || VM_Version::supports_avx512vl(), "");
4103
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4104
attributes.set_is_evex_instruction();
4105
int encode = vex_prefix_and_encode(kdst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4106
emit_int16(0x39, (0xC0 | encode));
4107
}
4108
4109
void Assembler::pcmpgtq(XMMRegister dst, XMMRegister src) {
4110
assert(VM_Version::supports_sse4_1(), "");
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(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4113
emit_int16(0x37, (0xC0 | encode));
4114
}
4115
4116
void Assembler::pmovmskb(Register dst, XMMRegister src) {
4117
assert(VM_Version::supports_sse2(), "");
4118
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4119
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4120
emit_int16((unsigned char)0xD7, (0xC0 | encode));
4121
}
4122
4123
void Assembler::vpmovmskb(Register dst, XMMRegister src, int vec_enc) {
4124
assert((VM_Version::supports_avx() && vec_enc == AVX_128bit) ||
4125
(VM_Version::supports_avx2() && vec_enc == AVX_256bit), "");
4126
InstructionAttr attributes(vec_enc, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4127
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4128
emit_int16((unsigned char)0xD7, (0xC0 | encode));
4129
}
4130
4131
void Assembler::pextrd(Register 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
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4135
emit_int24(0x16, (0xC0 | encode), imm8);
4136
}
4137
4138
void Assembler::pextrd(Address dst, XMMRegister src, int imm8) {
4139
assert(VM_Version::supports_sse4_1(), "");
4140
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4141
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
4142
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4143
emit_int8(0x16);
4144
emit_operand(src, dst);
4145
emit_int8(imm8);
4146
}
4147
4148
void Assembler::pextrq(Register 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
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4152
emit_int24(0x16, (0xC0 | encode), imm8);
4153
}
4154
4155
void Assembler::pextrq(Address dst, XMMRegister src, int imm8) {
4156
assert(VM_Version::supports_sse4_1(), "");
4157
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4158
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
4159
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4160
emit_int8(0x16);
4161
emit_operand(src, dst);
4162
emit_int8(imm8);
4163
}
4164
4165
void Assembler::pextrw(Register dst, XMMRegister src, int imm8) {
4166
assert(VM_Version::supports_sse2(), "");
4167
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4168
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4169
emit_int24((unsigned char)0xC5, (0xC0 | encode), imm8);
4170
}
4171
4172
void Assembler::pextrw(Address dst, XMMRegister src, int imm8) {
4173
assert(VM_Version::supports_sse4_1(), "");
4174
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4175
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_16bit);
4176
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4177
emit_int8(0x15);
4178
emit_operand(src, dst);
4179
emit_int8(imm8);
4180
}
4181
4182
void Assembler::pextrb(Register 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
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4186
emit_int24(0x14, (0xC0 | encode), imm8);
4187
}
4188
4189
void Assembler::pextrb(Address dst, XMMRegister src, int imm8) {
4190
assert(VM_Version::supports_sse4_1(), "");
4191
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4192
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_8bit);
4193
simd_prefix(src, xnoreg, dst, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4194
emit_int8(0x14);
4195
emit_operand(src, dst);
4196
emit_int8(imm8);
4197
}
4198
4199
void Assembler::pinsrd(XMMRegister dst, Register 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
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4203
emit_int24(0x22, (0xC0 | encode), imm8);
4204
}
4205
4206
void Assembler::pinsrd(XMMRegister dst, Address src, int imm8) {
4207
assert(VM_Version::supports_sse4_1(), "");
4208
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4209
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
4210
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4211
emit_int8(0x22);
4212
emit_operand(dst,src);
4213
emit_int8(imm8);
4214
}
4215
4216
void Assembler::vpinsrd(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4217
assert(VM_Version::supports_avx(), "");
4218
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4219
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), 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, Register 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
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4227
emit_int24(0x22, (0xC0 | encode), imm8);
4228
}
4229
4230
void Assembler::pinsrq(XMMRegister dst, Address src, int imm8) {
4231
assert(VM_Version::supports_sse4_1(), "");
4232
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4233
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
4234
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4235
emit_int8(0x22);
4236
emit_operand(dst, src);
4237
emit_int8(imm8);
4238
}
4239
4240
void Assembler::vpinsrq(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4241
assert(VM_Version::supports_avx(), "");
4242
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false);
4243
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4244
emit_int24(0x22, (0xC0 | encode), imm8);
4245
}
4246
4247
void Assembler::pinsrw(XMMRegister dst, Register 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
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4251
emit_int24((unsigned char)0xC4, (0xC0 | encode), imm8);
4252
}
4253
4254
void Assembler::pinsrw(XMMRegister dst, Address src, int imm8) {
4255
assert(VM_Version::supports_sse2(), "");
4256
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4257
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_16bit);
4258
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4259
emit_int8((unsigned char)0xC4);
4260
emit_operand(dst, src);
4261
emit_int8(imm8);
4262
}
4263
4264
void Assembler::vpinsrw(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4265
assert(VM_Version::supports_avx(), "");
4266
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4267
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4268
emit_int24((unsigned char)0xC4, (0xC0 | encode), imm8);
4269
}
4270
4271
void Assembler::pinsrb(XMMRegister dst, Address src, int imm8) {
4272
assert(VM_Version::supports_sse4_1(), "");
4273
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4274
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_8bit);
4275
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4276
emit_int8(0x20);
4277
emit_operand(dst, src);
4278
emit_int8(imm8);
4279
}
4280
4281
void Assembler::pinsrb(XMMRegister dst, Register src, int imm8) {
4282
assert(VM_Version::supports_sse4_1(), "");
4283
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4284
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4285
emit_int24(0x20, (0xC0 | encode), imm8);
4286
}
4287
4288
void Assembler::vpinsrb(XMMRegister dst, XMMRegister nds, Register src, int imm8) {
4289
assert(VM_Version::supports_avx(), "");
4290
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false);
4291
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4292
emit_int24(0x20, (0xC0 | encode), imm8);
4293
}
4294
4295
void Assembler::insertps(XMMRegister dst, XMMRegister src, int imm8) {
4296
assert(VM_Version::supports_sse4_1(), "");
4297
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
4298
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4299
emit_int24(0x21, (0xC0 | encode), imm8);
4300
}
4301
4302
void Assembler::vinsertps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
4303
assert(VM_Version::supports_avx(), "");
4304
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
4305
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4306
emit_int24(0x21, (0xC0 | encode), imm8);
4307
}
4308
4309
void Assembler::pmovzxbw(XMMRegister dst, Address src) {
4310
assert(VM_Version::supports_sse4_1(), "");
4311
InstructionMark im(this);
4312
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4313
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4314
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4315
emit_int8(0x30);
4316
emit_operand(dst, src);
4317
}
4318
4319
void Assembler::pmovzxbw(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(0x30, (0xC0 | encode));
4324
}
4325
4326
void Assembler::pmovsxbw(XMMRegister dst, XMMRegister src) {
4327
assert(VM_Version::supports_sse4_1(), "");
4328
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* 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(0x20, (0xC0 | encode));
4331
}
4332
4333
void Assembler::pmovzxdq(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(0x35, (0xC0 | encode));
4338
}
4339
4340
void Assembler::pmovsxbd(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(0x21, (0xC0 | encode));
4345
}
4346
4347
void Assembler::pmovzxbd(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(0x31, (0xC0 | encode));
4352
}
4353
4354
void Assembler::pmovsxbq(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(0x22, (0xC0 | encode));
4359
}
4360
4361
void Assembler::pmovsxwd(XMMRegister dst, XMMRegister src) {
4362
assert(VM_Version::supports_sse4_1(), "");
4363
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4364
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4365
emit_int16(0x23, (0xC0 | encode));
4366
}
4367
4368
void Assembler::vpmovzxbw(XMMRegister dst, Address src, int vector_len) {
4369
assert(VM_Version::supports_avx(), "");
4370
InstructionMark im(this);
4371
assert(dst != xnoreg, "sanity");
4372
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4373
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4374
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4375
emit_int8(0x30);
4376
emit_operand(dst, src);
4377
}
4378
4379
void Assembler::vpmovzxbw(XMMRegister dst, XMMRegister src, int vector_len) {
4380
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4381
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4382
vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
4383
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4384
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4385
emit_int16(0x30, (unsigned char) (0xC0 | encode));
4386
}
4387
4388
void Assembler::vpmovsxbw(XMMRegister dst, XMMRegister src, int vector_len) {
4389
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4390
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4391
vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
4392
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4393
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4394
emit_int16(0x20, (0xC0 | encode));
4395
}
4396
4397
void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len) {
4398
assert(VM_Version::supports_avx512vlbw(), "");
4399
assert(dst != xnoreg, "sanity");
4400
InstructionMark im(this);
4401
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
4402
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4403
attributes.set_embedded_opmask_register_specifier(mask);
4404
attributes.set_is_evex_instruction();
4405
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4406
emit_int8(0x30);
4407
emit_operand(dst, src);
4408
}
4409
4410
void Assembler::evpandd(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
4411
assert(VM_Version::supports_evex(), "");
4412
// Encoding: EVEX.NDS.XXX.66.0F.W0 DB /r
4413
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4414
attributes.set_is_evex_instruction();
4415
attributes.set_embedded_opmask_register_specifier(mask);
4416
if (merge) {
4417
attributes.reset_is_clear_context();
4418
}
4419
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4420
emit_int16((unsigned char)0xDB, (0xC0 | encode));
4421
}
4422
4423
void Assembler::vpmovzxdq(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(0x35, (0xC0 | encode));
4428
}
4429
4430
void Assembler::vpmovzxbd(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(0x31, (0xC0 | encode));
4435
}
4436
4437
void Assembler::vpmovzxbq(XMMRegister dst, XMMRegister src, int vector_len) {
4438
assert(vector_len > AVX_128bit ? VM_Version::supports_avx2() : VM_Version::supports_avx(), "");
4439
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4440
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4441
emit_int16(0x32, (0xC0 | encode));
4442
}
4443
4444
void Assembler::vpmovsxbd(XMMRegister dst, XMMRegister src, int vector_len) {
4445
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4446
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4447
VM_Version::supports_evex(), "");
4448
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4449
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4450
emit_int16(0x21, (0xC0 | encode));
4451
}
4452
4453
void Assembler::vpmovsxbq(XMMRegister dst, XMMRegister src, int vector_len) {
4454
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4455
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4456
VM_Version::supports_evex(), "");
4457
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4458
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4459
emit_int16(0x22, (0xC0 | encode));
4460
}
4461
4462
void Assembler::vpmovsxwd(XMMRegister dst, XMMRegister src, int vector_len) {
4463
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4464
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4465
VM_Version::supports_evex(), "");
4466
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4467
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4468
emit_int16(0x23, (0xC0 | encode));
4469
}
4470
4471
void Assembler::vpmovsxwq(XMMRegister dst, XMMRegister src, int vector_len) {
4472
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4473
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4474
VM_Version::supports_evex(), "");
4475
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4476
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4477
emit_int16(0x24, (0xC0 | encode));
4478
}
4479
4480
void Assembler::vpmovsxdq(XMMRegister dst, XMMRegister src, int vector_len) {
4481
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4482
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4483
VM_Version::supports_evex(), "");
4484
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4485
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4486
emit_int16(0x25, (0xC0 | encode));
4487
}
4488
4489
void Assembler::evpmovwb(Address dst, XMMRegister src, int vector_len) {
4490
assert(VM_Version::supports_avx512vlbw(), "");
4491
assert(src != xnoreg, "sanity");
4492
InstructionMark im(this);
4493
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4494
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4495
attributes.set_is_evex_instruction();
4496
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4497
emit_int8(0x30);
4498
emit_operand(src, dst);
4499
}
4500
4501
void Assembler::evpmovwb(Address dst, KRegister mask, XMMRegister src, int vector_len) {
4502
assert(VM_Version::supports_avx512vlbw(), "");
4503
assert(src != xnoreg, "sanity");
4504
InstructionMark im(this);
4505
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
4506
attributes.set_address_attributes(/* tuple_type */ EVEX_HVM, /* input_size_in_bits */ EVEX_NObit);
4507
attributes.reset_is_clear_context();
4508
attributes.set_embedded_opmask_register_specifier(mask);
4509
attributes.set_is_evex_instruction();
4510
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4511
emit_int8(0x30);
4512
emit_operand(src, dst);
4513
}
4514
4515
void Assembler::evpmovdb(Address dst, XMMRegister src, int vector_len) {
4516
assert(VM_Version::supports_evex(), "");
4517
assert(src != xnoreg, "sanity");
4518
InstructionMark im(this);
4519
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4520
attributes.set_address_attributes(/* tuple_type */ EVEX_QVM, /* input_size_in_bits */ EVEX_NObit);
4521
attributes.set_is_evex_instruction();
4522
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
4523
emit_int8(0x31);
4524
emit_operand(src, dst);
4525
}
4526
4527
void Assembler::vpmovzxwd(XMMRegister dst, XMMRegister src, int vector_len) {
4528
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4529
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4530
vector_len == AVX_512bit? VM_Version::supports_evex() : 0, " ");
4531
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4532
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4533
emit_int16(0x33, (0xC0 | encode));
4534
}
4535
4536
void Assembler::pmaddwd(XMMRegister dst, XMMRegister src) {
4537
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4538
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4539
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4540
emit_int16((unsigned char)0xF5, (0xC0 | encode));
4541
}
4542
4543
void Assembler::vpmaddwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4544
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4545
(vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4546
(vector_len == AVX_512bit ? VM_Version::supports_evex() : 0)), "");
4547
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4548
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4549
emit_int16((unsigned char)0xF5, (0xC0 | encode));
4550
}
4551
4552
void Assembler::evpdpwssd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4553
assert(VM_Version::supports_evex(), "");
4554
assert(VM_Version::supports_avx512_vnni(), "must support vnni");
4555
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4556
attributes.set_is_evex_instruction();
4557
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4558
emit_int16(0x52, (0xC0 | encode));
4559
}
4560
4561
// generic
4562
void Assembler::pop(Register dst) {
4563
int encode = prefix_and_encode(dst->encoding());
4564
emit_int8(0x58 | encode);
4565
}
4566
4567
void Assembler::popcntl(Register dst, Address src) {
4568
assert(VM_Version::supports_popcnt(), "must support");
4569
InstructionMark im(this);
4570
emit_int8((unsigned char)0xF3);
4571
prefix(src, dst);
4572
emit_int16(0x0F, (unsigned char)0xB8);
4573
emit_operand(dst, src);
4574
}
4575
4576
void Assembler::popcntl(Register dst, Register src) {
4577
assert(VM_Version::supports_popcnt(), "must support");
4578
emit_int8((unsigned char)0xF3);
4579
int encode = prefix_and_encode(dst->encoding(), src->encoding());
4580
emit_int24(0x0F, (unsigned char)0xB8, (0xC0 | encode));
4581
}
4582
4583
void Assembler::vpopcntd(XMMRegister dst, XMMRegister src, int vector_len) {
4584
assert(VM_Version::supports_avx512_vpopcntdq(), "must support vpopcntdq feature");
4585
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4586
attributes.set_is_evex_instruction();
4587
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4588
emit_int16(0x55, (0xC0 | encode));
4589
}
4590
4591
void Assembler::popf() {
4592
emit_int8((unsigned char)0x9D);
4593
}
4594
4595
#ifndef _LP64 // no 32bit push/pop on amd64
4596
void Assembler::popl(Address dst) {
4597
// NOTE: this will adjust stack by 8byte on 64bits
4598
InstructionMark im(this);
4599
prefix(dst);
4600
emit_int8((unsigned char)0x8F);
4601
emit_operand(rax, dst);
4602
}
4603
#endif
4604
4605
void Assembler::prefetchnta(Address src) {
4606
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4607
InstructionMark im(this);
4608
prefix(src);
4609
emit_int16(0x0F, 0x18);
4610
emit_operand(rax, src); // 0, src
4611
}
4612
4613
void Assembler::prefetchr(Address src) {
4614
assert(VM_Version::supports_3dnow_prefetch(), "must support");
4615
InstructionMark im(this);
4616
prefix(src);
4617
emit_int16(0x0F, 0x0D);
4618
emit_operand(rax, src); // 0, src
4619
}
4620
4621
void Assembler::prefetcht0(Address src) {
4622
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4623
InstructionMark im(this);
4624
prefix(src);
4625
emit_int16(0x0F, 0x18);
4626
emit_operand(rcx, src); // 1, src
4627
}
4628
4629
void Assembler::prefetcht1(Address src) {
4630
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4631
InstructionMark im(this);
4632
prefix(src);
4633
emit_int16(0x0F, 0x18);
4634
emit_operand(rdx, src); // 2, src
4635
}
4636
4637
void Assembler::prefetcht2(Address src) {
4638
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
4639
InstructionMark im(this);
4640
prefix(src);
4641
emit_int16(0x0F, 0x18);
4642
emit_operand(rbx, src); // 3, src
4643
}
4644
4645
void Assembler::prefetchw(Address src) {
4646
assert(VM_Version::supports_3dnow_prefetch(), "must support");
4647
InstructionMark im(this);
4648
prefix(src);
4649
emit_int16(0x0F, 0x0D);
4650
emit_operand(rcx, src); // 1, src
4651
}
4652
4653
void Assembler::prefix(Prefix p) {
4654
emit_int8(p);
4655
}
4656
4657
void Assembler::pshufb(XMMRegister dst, XMMRegister src) {
4658
assert(VM_Version::supports_ssse3(), "");
4659
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4660
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4661
emit_int16(0x00, (0xC0 | encode));
4662
}
4663
4664
void Assembler::vpshufb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
4665
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4666
vector_len == AVX_256bit? VM_Version::supports_avx2() :
4667
vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
4668
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4669
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4670
emit_int16(0x00, (0xC0 | encode));
4671
}
4672
4673
void Assembler::pshufb(XMMRegister dst, Address src) {
4674
assert(VM_Version::supports_ssse3(), "");
4675
InstructionMark im(this);
4676
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4677
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
4678
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4679
emit_int8(0x00);
4680
emit_operand(dst, src);
4681
}
4682
4683
void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) {
4684
assert(isByte(mode), "invalid value");
4685
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4686
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
4687
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4688
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4689
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4690
}
4691
4692
void Assembler::vpshufd(XMMRegister dst, XMMRegister src, int mode, int vector_len) {
4693
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
4694
(vector_len == AVX_256bit? VM_Version::supports_avx2() :
4695
(vector_len == AVX_512bit? VM_Version::supports_evex() : 0)), "");
4696
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4697
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4698
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4699
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4700
}
4701
4702
void Assembler::pshufd(XMMRegister dst, Address src, int mode) {
4703
assert(isByte(mode), "invalid value");
4704
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4705
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4706
InstructionMark im(this);
4707
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4708
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
4709
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4710
emit_int8(0x70);
4711
emit_operand(dst, src);
4712
emit_int8(mode & 0xFF);
4713
}
4714
4715
void Assembler::pshufhw(XMMRegister dst, XMMRegister src, int mode) {
4716
assert(isByte(mode), "invalid value");
4717
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4718
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4719
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
4720
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4721
}
4722
4723
void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) {
4724
assert(isByte(mode), "invalid value");
4725
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4726
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4727
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
4728
emit_int24(0x70, (0xC0 | encode), mode & 0xFF);
4729
}
4730
4731
void Assembler::pshuflw(XMMRegister dst, Address src, int mode) {
4732
assert(isByte(mode), "invalid value");
4733
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4734
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4735
InstructionMark im(this);
4736
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4737
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
4738
simd_prefix(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
4739
emit_int8(0x70);
4740
emit_operand(dst, src);
4741
emit_int8(mode & 0xFF);
4742
}
4743
4744
void Assembler::evshufi64x2(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
4745
assert(VM_Version::supports_evex(), "requires EVEX support");
4746
assert(vector_len == Assembler::AVX_256bit || vector_len == Assembler::AVX_512bit, "");
4747
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4748
attributes.set_is_evex_instruction();
4749
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
4750
emit_int24(0x43, (0xC0 | encode), imm8 & 0xFF);
4751
}
4752
4753
void Assembler::pshufpd(XMMRegister dst, XMMRegister src, int imm8) {
4754
assert(isByte(imm8), "invalid value");
4755
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4756
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4757
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4758
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4759
}
4760
4761
void Assembler::vpshufpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
4762
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4763
attributes.set_rex_vex_w_reverted();
4764
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4765
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4766
}
4767
4768
void Assembler::pshufps(XMMRegister dst, XMMRegister src, int imm8) {
4769
assert(isByte(imm8), "invalid value");
4770
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4771
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4772
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
4773
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4774
}
4775
4776
void Assembler::vpshufps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
4777
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4778
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
4779
emit_int24((unsigned char)0xC6, (0xC0 | encode), imm8 & 0xFF);
4780
}
4781
4782
void Assembler::psrldq(XMMRegister dst, int shift) {
4783
// Shift left 128 bit value in dst XMMRegister by shift number of bytes.
4784
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4785
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4786
int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4787
emit_int24(0x73, (0xC0 | encode), shift);
4788
}
4789
4790
void Assembler::vpsrldq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
4791
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4792
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4793
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : 0, "");
4794
InstructionAttr attributes(vector_len, /*vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4795
int encode = vex_prefix_and_encode(xmm3->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4796
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
4797
}
4798
4799
void Assembler::pslldq(XMMRegister dst, int shift) {
4800
// Shift left 128 bit value in dst XMMRegister by shift number of bytes.
4801
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4802
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4803
// XMM7 is for /7 encoding: 66 0F 73 /7 ib
4804
int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4805
emit_int24(0x73, (0xC0 | encode), shift);
4806
}
4807
4808
void Assembler::vpslldq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
4809
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
4810
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
4811
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : 0, "");
4812
InstructionAttr attributes(vector_len, /*vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
4813
int encode = vex_prefix_and_encode(xmm7->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4814
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
4815
}
4816
4817
void Assembler::ptest(XMMRegister dst, Address src) {
4818
assert(VM_Version::supports_sse4_1(), "");
4819
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4820
InstructionMark im(this);
4821
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4822
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4823
emit_int8(0x17);
4824
emit_operand(dst, src);
4825
}
4826
4827
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
4828
assert(VM_Version::supports_sse4_1() || VM_Version::supports_avx(), "");
4829
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4830
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4831
emit_int8(0x17);
4832
emit_int8((0xC0 | encode));
4833
}
4834
4835
void Assembler::vptest(XMMRegister dst, Address src) {
4836
assert(VM_Version::supports_avx(), "");
4837
InstructionMark im(this);
4838
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4839
assert(dst != xnoreg, "sanity");
4840
// swap src<->dst for encoding
4841
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4842
emit_int8(0x17);
4843
emit_operand(dst, src);
4844
}
4845
4846
void Assembler::vptest(XMMRegister dst, XMMRegister src) {
4847
assert(VM_Version::supports_avx(), "");
4848
InstructionAttr attributes(AVX_256bit, /* 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::vptest(XMMRegister dst, XMMRegister src, int vector_len) {
4854
assert(VM_Version::supports_avx(), "");
4855
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4856
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
4857
emit_int16(0x17, (0xC0 | encode));
4858
}
4859
4860
void Assembler::punpcklbw(XMMRegister dst, Address src) {
4861
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4862
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4863
InstructionMark im(this);
4864
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_vlbw, /* no_mask_reg */ true, /* uses_vl */ true);
4865
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
4866
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4867
emit_int8(0x60);
4868
emit_operand(dst, src);
4869
}
4870
4871
void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
4872
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4873
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_vlbw, /* no_mask_reg */ true, /* uses_vl */ true);
4874
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4875
emit_int16(0x60, (0xC0 | encode));
4876
}
4877
4878
void Assembler::punpckldq(XMMRegister dst, Address src) {
4879
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4880
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
4881
InstructionMark im(this);
4882
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4883
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
4884
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4885
emit_int8(0x62);
4886
emit_operand(dst, src);
4887
}
4888
4889
void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
4890
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4891
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4892
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4893
emit_int16(0x62, (0xC0 | encode));
4894
}
4895
4896
void Assembler::punpcklqdq(XMMRegister dst, XMMRegister src) {
4897
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
4898
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
4899
attributes.set_rex_vex_w_reverted();
4900
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
4901
emit_int16(0x6C, (0xC0 | encode));
4902
}
4903
4904
void Assembler::push(int32_t imm32) {
4905
// in 64bits we push 64bits onto the stack but only
4906
// take a 32bit immediate
4907
emit_int8(0x68);
4908
emit_int32(imm32);
4909
}
4910
4911
void Assembler::push(Register src) {
4912
int encode = prefix_and_encode(src->encoding());
4913
emit_int8(0x50 | encode);
4914
}
4915
4916
void Assembler::pushf() {
4917
emit_int8((unsigned char)0x9C);
4918
}
4919
4920
#ifndef _LP64 // no 32bit push/pop on amd64
4921
void Assembler::pushl(Address src) {
4922
// Note this will push 64bit on 64bit
4923
InstructionMark im(this);
4924
prefix(src);
4925
emit_int8((unsigned char)0xFF);
4926
emit_operand(rsi, src);
4927
}
4928
#endif
4929
4930
void Assembler::rcll(Register dst, int imm8) {
4931
assert(isShiftCount(imm8), "illegal shift count");
4932
int encode = prefix_and_encode(dst->encoding());
4933
if (imm8 == 1) {
4934
emit_int16((unsigned char)0xD1, (0xD0 | encode));
4935
} else {
4936
emit_int24((unsigned char)0xC1, (0xD0 | encode), imm8);
4937
}
4938
}
4939
4940
void Assembler::rcpps(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, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
4944
emit_int16(0x53, (0xC0 | encode));
4945
}
4946
4947
void Assembler::rcpss(XMMRegister dst, XMMRegister src) {
4948
NOT_LP64(assert(VM_Version::supports_sse(), ""));
4949
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
4950
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
4951
emit_int16(0x53, (0xC0 | encode));
4952
}
4953
4954
void Assembler::rdtsc() {
4955
emit_int16(0x0F, 0x31);
4956
}
4957
4958
// copies data from [esi] to [edi] using rcx pointer sized words
4959
// generic
4960
void Assembler::rep_mov() {
4961
// REP
4962
// MOVSQ
4963
LP64_ONLY(emit_int24((unsigned char)0xF3, REX_W, (unsigned char)0xA5);)
4964
NOT_LP64( emit_int16((unsigned char)0xF3, (unsigned char)0xA5);)
4965
}
4966
4967
// sets rcx bytes with rax, value at [edi]
4968
void Assembler::rep_stosb() {
4969
// REP
4970
// STOSB
4971
LP64_ONLY(emit_int24((unsigned char)0xF3, REX_W, (unsigned char)0xAA);)
4972
NOT_LP64( emit_int16((unsigned char)0xF3, (unsigned char)0xAA);)
4973
}
4974
4975
// sets rcx pointer sized words with rax, value at [edi]
4976
// generic
4977
void Assembler::rep_stos() {
4978
// REP
4979
// LP64:STOSQ, LP32:STOSD
4980
LP64_ONLY(emit_int24((unsigned char)0xF3, REX_W, (unsigned char)0xAB);)
4981
NOT_LP64( emit_int16((unsigned char)0xF3, (unsigned char)0xAB);)
4982
}
4983
4984
// scans rcx pointer sized words at [edi] for occurance of rax,
4985
// generic
4986
void Assembler::repne_scan() { // repne_scan
4987
// SCASQ
4988
LP64_ONLY(emit_int24((unsigned char)0xF2, REX_W, (unsigned char)0xAF);)
4989
NOT_LP64( emit_int16((unsigned char)0xF2, (unsigned char)0xAF);)
4990
}
4991
4992
#ifdef _LP64
4993
// scans rcx 4 byte words at [edi] for occurance of rax,
4994
// generic
4995
void Assembler::repne_scanl() { // repne_scan
4996
// SCASL
4997
emit_int16((unsigned char)0xF2, (unsigned char)0xAF);
4998
}
4999
#endif
5000
5001
void Assembler::ret(int imm16) {
5002
if (imm16 == 0) {
5003
emit_int8((unsigned char)0xC3);
5004
} else {
5005
emit_int8((unsigned char)0xC2);
5006
emit_int16(imm16);
5007
}
5008
}
5009
5010
void Assembler::roll(Register dst, int imm8) {
5011
assert(isShiftCount(imm8), "illegal shift count");
5012
int encode = prefix_and_encode(dst->encoding());
5013
if (imm8 == 1) {
5014
emit_int16((unsigned char)0xD1, (0xC0 | encode));
5015
} else {
5016
emit_int24((unsigned char)0xC1, (0xc0 | encode), imm8);
5017
}
5018
}
5019
5020
void Assembler::roll(Register dst) {
5021
int encode = prefix_and_encode(dst->encoding());
5022
emit_int16((unsigned char)0xD3, (0xC0 | encode));
5023
}
5024
5025
void Assembler::rorl(Register dst, int imm8) {
5026
assert(isShiftCount(imm8), "illegal shift count");
5027
int encode = prefix_and_encode(dst->encoding());
5028
if (imm8 == 1) {
5029
emit_int16((unsigned char)0xD1, (0xC8 | encode));
5030
} else {
5031
emit_int24((unsigned char)0xC1, (0xc8 | encode), imm8);
5032
}
5033
}
5034
5035
void Assembler::rorl(Register dst) {
5036
int encode = prefix_and_encode(dst->encoding());
5037
emit_int16((unsigned char)0xD3, (0xC8 | encode));
5038
}
5039
5040
#ifdef _LP64
5041
void Assembler::rorq(Register dst) {
5042
int encode = prefixq_and_encode(dst->encoding());
5043
emit_int16((unsigned char)0xD3, (0xC8 | encode));
5044
}
5045
5046
void Assembler::rorq(Register dst, int imm8) {
5047
assert(isShiftCount(imm8 >> 1), "illegal shift count");
5048
int encode = prefixq_and_encode(dst->encoding());
5049
if (imm8 == 1) {
5050
emit_int16((unsigned char)0xD1, (0xC8 | encode));
5051
} else {
5052
emit_int24((unsigned char)0xC1, (0xc8 | encode), imm8);
5053
}
5054
}
5055
5056
void Assembler::rolq(Register dst) {
5057
int encode = prefixq_and_encode(dst->encoding());
5058
emit_int16((unsigned char)0xD3, (0xC0 | encode));
5059
}
5060
5061
void Assembler::rolq(Register dst, int imm8) {
5062
assert(isShiftCount(imm8 >> 1), "illegal shift count");
5063
int encode = prefixq_and_encode(dst->encoding());
5064
if (imm8 == 1) {
5065
emit_int16((unsigned char)0xD1, (0xC0 | encode));
5066
} else {
5067
emit_int24((unsigned char)0xC1, (0xc0 | encode), imm8);
5068
}
5069
}
5070
#endif
5071
5072
void Assembler::sahf() {
5073
#ifdef _LP64
5074
// Not supported in 64bit mode
5075
ShouldNotReachHere();
5076
#endif
5077
emit_int8((unsigned char)0x9E);
5078
}
5079
5080
void Assembler::sall(Address dst, int imm8) {
5081
InstructionMark im(this);
5082
assert(isShiftCount(imm8), "illegal shift count");
5083
prefix(dst);
5084
if (imm8 == 1) {
5085
emit_int8((unsigned char)0xD1);
5086
emit_operand(as_Register(4), dst);
5087
}
5088
else {
5089
emit_int8((unsigned char)0xC1);
5090
emit_operand(as_Register(4), dst);
5091
emit_int8(imm8);
5092
}
5093
}
5094
5095
void Assembler::sall(Address dst) {
5096
InstructionMark im(this);
5097
prefix(dst);
5098
emit_int8((unsigned char)0xD3);
5099
emit_operand(as_Register(4), dst);
5100
}
5101
5102
void Assembler::sall(Register dst, int imm8) {
5103
assert(isShiftCount(imm8), "illegal shift count");
5104
int encode = prefix_and_encode(dst->encoding());
5105
if (imm8 == 1) {
5106
emit_int16((unsigned char)0xD1, (0xE0 | encode));
5107
} else {
5108
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
5109
}
5110
}
5111
5112
void Assembler::sall(Register dst) {
5113
int encode = prefix_and_encode(dst->encoding());
5114
emit_int16((unsigned char)0xD3, (0xE0 | encode));
5115
}
5116
5117
void Assembler::sarl(Address dst, int imm8) {
5118
assert(isShiftCount(imm8), "illegal shift count");
5119
InstructionMark im(this);
5120
prefix(dst);
5121
if (imm8 == 1) {
5122
emit_int8((unsigned char)0xD1);
5123
emit_operand(as_Register(7), dst);
5124
}
5125
else {
5126
emit_int8((unsigned char)0xC1);
5127
emit_operand(as_Register(7), dst);
5128
emit_int8(imm8);
5129
}
5130
}
5131
5132
void Assembler::sarl(Address dst) {
5133
InstructionMark im(this);
5134
prefix(dst);
5135
emit_int8((unsigned char)0xD3);
5136
emit_operand(as_Register(7), dst);
5137
}
5138
5139
void Assembler::sarl(Register dst, int imm8) {
5140
int encode = prefix_and_encode(dst->encoding());
5141
assert(isShiftCount(imm8), "illegal shift count");
5142
if (imm8 == 1) {
5143
emit_int16((unsigned char)0xD1, (0xF8 | encode));
5144
} else {
5145
emit_int24((unsigned char)0xC1, (0xF8 | encode), imm8);
5146
}
5147
}
5148
5149
void Assembler::sarl(Register dst) {
5150
int encode = prefix_and_encode(dst->encoding());
5151
emit_int16((unsigned char)0xD3, (0xF8 | encode));
5152
}
5153
5154
void Assembler::sbbl(Address dst, int32_t imm32) {
5155
InstructionMark im(this);
5156
prefix(dst);
5157
emit_arith_operand(0x81, rbx, dst, imm32);
5158
}
5159
5160
void Assembler::sbbl(Register dst, int32_t imm32) {
5161
prefix(dst);
5162
emit_arith(0x81, 0xD8, dst, imm32);
5163
}
5164
5165
5166
void Assembler::sbbl(Register dst, Address src) {
5167
InstructionMark im(this);
5168
prefix(src, dst);
5169
emit_int8(0x1B);
5170
emit_operand(dst, src);
5171
}
5172
5173
void Assembler::sbbl(Register dst, Register src) {
5174
(void) prefix_and_encode(dst->encoding(), src->encoding());
5175
emit_arith(0x1B, 0xC0, dst, src);
5176
}
5177
5178
void Assembler::setb(Condition cc, Register dst) {
5179
assert(0 <= cc && cc < 16, "illegal cc");
5180
int encode = prefix_and_encode(dst->encoding(), true);
5181
emit_int24(0x0F, (unsigned char)0x90 | cc, (0xC0 | encode));
5182
}
5183
5184
void Assembler::sete(Register dst) {
5185
int encode = prefix_and_encode(dst->encoding(), true);
5186
emit_int24(0x0F, (unsigned char)0x94, (0xC0 | encode));
5187
}
5188
5189
void Assembler::setl(Register dst) {
5190
int encode = prefix_and_encode(dst->encoding(), true);
5191
emit_int24(0x0F, (unsigned char)0x9C, (0xC0 | encode));
5192
}
5193
5194
void Assembler::setne(Register dst) {
5195
int encode = prefix_and_encode(dst->encoding(), true);
5196
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | encode));
5197
}
5198
5199
void Assembler::palignr(XMMRegister dst, XMMRegister src, int imm8) {
5200
assert(VM_Version::supports_ssse3(), "");
5201
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
5202
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5203
emit_int24(0x0F, (0xC0 | encode), imm8);
5204
}
5205
5206
void Assembler::vpalignr(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
5207
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
5208
vector_len == AVX_256bit? VM_Version::supports_avx2() :
5209
0, "");
5210
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
5211
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5212
emit_int24(0x0F, (0xC0 | encode), imm8);
5213
}
5214
5215
void Assembler::evalignq(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
5216
assert(VM_Version::supports_evex(), "");
5217
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5218
attributes.set_is_evex_instruction();
5219
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5220
emit_int24(0x3, (0xC0 | encode), imm8);
5221
}
5222
5223
void Assembler::pblendw(XMMRegister dst, XMMRegister src, int imm8) {
5224
assert(VM_Version::supports_sse4_1(), "");
5225
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5226
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5227
emit_int24(0x0E, (0xC0 | encode), imm8);
5228
}
5229
5230
void Assembler::sha1rnds4(XMMRegister dst, XMMRegister src, int imm8) {
5231
assert(VM_Version::supports_sha(), "");
5232
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3A, /* rex_w */ false);
5233
emit_int24((unsigned char)0xCC, (0xC0 | encode), (unsigned char)imm8);
5234
}
5235
5236
void Assembler::sha1nexte(XMMRegister dst, XMMRegister src) {
5237
assert(VM_Version::supports_sha(), "");
5238
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5239
emit_int16((unsigned char)0xC8, (0xC0 | encode));
5240
}
5241
5242
void Assembler::sha1msg1(XMMRegister dst, XMMRegister src) {
5243
assert(VM_Version::supports_sha(), "");
5244
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5245
emit_int16((unsigned char)0xC9, (0xC0 | encode));
5246
}
5247
5248
void Assembler::sha1msg2(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)0xCA, (0xC0 | encode));
5252
}
5253
5254
// xmm0 is implicit additional source to this instruction.
5255
void Assembler::sha256rnds2(XMMRegister dst, XMMRegister src) {
5256
assert(VM_Version::supports_sha(), "");
5257
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5258
emit_int16((unsigned char)0xCB, (0xC0 | encode));
5259
}
5260
5261
void Assembler::sha256msg1(XMMRegister dst, XMMRegister src) {
5262
assert(VM_Version::supports_sha(), "");
5263
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5264
emit_int16((unsigned char)0xCC, (0xC0 | encode));
5265
}
5266
5267
void Assembler::sha256msg2(XMMRegister dst, XMMRegister src) {
5268
assert(VM_Version::supports_sha(), "");
5269
int encode = rex_prefix_and_encode(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, /* rex_w */ false);
5270
emit_int16((unsigned char)0xCD, (0xC0 | encode));
5271
}
5272
5273
5274
void Assembler::shll(Register dst, int imm8) {
5275
assert(isShiftCount(imm8), "illegal shift count");
5276
int encode = prefix_and_encode(dst->encoding());
5277
if (imm8 == 1 ) {
5278
emit_int16((unsigned char)0xD1, (0xE0 | encode));
5279
} else {
5280
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
5281
}
5282
}
5283
5284
void Assembler::shll(Register dst) {
5285
int encode = prefix_and_encode(dst->encoding());
5286
emit_int16((unsigned char)0xD3, (0xE0 | encode));
5287
}
5288
5289
void Assembler::shrl(Register dst, int imm8) {
5290
assert(isShiftCount(imm8), "illegal shift count");
5291
int encode = prefix_and_encode(dst->encoding());
5292
if (imm8 == 1) {
5293
emit_int16((unsigned char)0xD1, (0xE8 | encode));
5294
}
5295
else {
5296
emit_int24((unsigned char)0xC1, (0xE8 | encode), imm8);
5297
}
5298
}
5299
5300
void Assembler::shrl(Register dst) {
5301
int encode = prefix_and_encode(dst->encoding());
5302
emit_int16((unsigned char)0xD3, (0xE8 | encode));
5303
}
5304
5305
void Assembler::shrl(Address dst) {
5306
InstructionMark im(this);
5307
prefix(dst);
5308
emit_int8((unsigned char)0xD3);
5309
emit_operand(as_Register(5), dst);
5310
}
5311
5312
void Assembler::shrl(Address dst, int imm8) {
5313
InstructionMark im(this);
5314
assert(isShiftCount(imm8), "illegal shift count");
5315
prefix(dst);
5316
if (imm8 == 1) {
5317
emit_int8((unsigned char)0xD1);
5318
emit_operand(as_Register(5), dst);
5319
}
5320
else {
5321
emit_int8((unsigned char)0xC1);
5322
emit_operand(as_Register(5), dst);
5323
emit_int8(imm8);
5324
}
5325
}
5326
5327
5328
void Assembler::shldl(Register dst, Register src) {
5329
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5330
emit_int24(0x0F, (unsigned char)0xA5, (0xC0 | encode));
5331
}
5332
5333
void Assembler::shldl(Register dst, Register src, int8_t imm8) {
5334
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5335
emit_int32(0x0F, (unsigned char)0xA4, (0xC0 | encode), imm8);
5336
}
5337
5338
void Assembler::shrdl(Register dst, Register src) {
5339
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5340
emit_int24(0x0F, (unsigned char)0xAD, (0xC0 | encode));
5341
}
5342
5343
void Assembler::shrdl(Register dst, Register src, int8_t imm8) {
5344
int encode = prefix_and_encode(src->encoding(), dst->encoding());
5345
emit_int32(0x0F, (unsigned char)0xAC, (0xC0 | encode), imm8);
5346
}
5347
5348
// copies a single word from [esi] to [edi]
5349
void Assembler::smovl() {
5350
emit_int8((unsigned char)0xA5);
5351
}
5352
5353
void Assembler::roundsd(XMMRegister dst, XMMRegister src, int32_t rmode) {
5354
assert(VM_Version::supports_sse4_1(), "");
5355
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5356
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5357
emit_int24(0x0B, (0xC0 | encode), (unsigned char)rmode);
5358
}
5359
5360
void Assembler::roundsd(XMMRegister dst, Address src, int32_t rmode) {
5361
assert(VM_Version::supports_sse4_1(), "");
5362
InstructionMark im(this);
5363
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5364
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
5365
emit_int8(0x0B);
5366
emit_operand(dst, src);
5367
emit_int8((unsigned char)rmode);
5368
}
5369
5370
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
5371
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5372
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5373
attributes.set_rex_vex_w_reverted();
5374
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5375
emit_int16(0x51, (0xC0 | encode));
5376
}
5377
5378
void Assembler::sqrtsd(XMMRegister dst, Address src) {
5379
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5380
InstructionMark im(this);
5381
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5382
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5383
attributes.set_rex_vex_w_reverted();
5384
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5385
emit_int8(0x51);
5386
emit_operand(dst, src);
5387
}
5388
5389
void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
5390
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5391
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5392
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5393
emit_int16(0x51, (0xC0 | encode));
5394
}
5395
5396
void Assembler::std() {
5397
emit_int8((unsigned char)0xFD);
5398
}
5399
5400
void Assembler::sqrtss(XMMRegister dst, Address src) {
5401
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5402
InstructionMark im(this);
5403
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5404
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5405
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5406
emit_int8(0x51);
5407
emit_operand(dst, src);
5408
}
5409
5410
void Assembler::stmxcsr( Address dst) {
5411
if (UseAVX > 0 ) {
5412
assert(VM_Version::supports_avx(), "");
5413
InstructionMark im(this);
5414
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
5415
vex_prefix(dst, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5416
emit_int8((unsigned char)0xAE);
5417
emit_operand(as_Register(3), dst);
5418
} else {
5419
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5420
InstructionMark im(this);
5421
prefix(dst);
5422
emit_int16(0x0F, (unsigned char)0xAE);
5423
emit_operand(as_Register(3), dst);
5424
}
5425
}
5426
5427
void Assembler::subl(Address dst, int32_t imm32) {
5428
InstructionMark im(this);
5429
prefix(dst);
5430
emit_arith_operand(0x81, rbp, dst, imm32);
5431
}
5432
5433
void Assembler::subl(Address dst, Register src) {
5434
InstructionMark im(this);
5435
prefix(dst, src);
5436
emit_int8(0x29);
5437
emit_operand(src, dst);
5438
}
5439
5440
void Assembler::subl(Register dst, int32_t imm32) {
5441
prefix(dst);
5442
emit_arith(0x81, 0xE8, dst, imm32);
5443
}
5444
5445
// Force generation of a 4 byte immediate value even if it fits into 8bit
5446
void Assembler::subl_imm32(Register dst, int32_t imm32) {
5447
prefix(dst);
5448
emit_arith_imm32(0x81, 0xE8, dst, imm32);
5449
}
5450
5451
void Assembler::subl(Register dst, Address src) {
5452
InstructionMark im(this);
5453
prefix(src, dst);
5454
emit_int8(0x2B);
5455
emit_operand(dst, src);
5456
}
5457
5458
void Assembler::subl(Register dst, Register src) {
5459
(void) prefix_and_encode(dst->encoding(), src->encoding());
5460
emit_arith(0x2B, 0xC0, dst, src);
5461
}
5462
5463
void Assembler::subsd(XMMRegister dst, XMMRegister src) {
5464
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5465
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5466
attributes.set_rex_vex_w_reverted();
5467
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5468
emit_int16(0x5C, (0xC0 | encode));
5469
}
5470
5471
void Assembler::subsd(XMMRegister dst, Address src) {
5472
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5473
InstructionMark im(this);
5474
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5475
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5476
attributes.set_rex_vex_w_reverted();
5477
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5478
emit_int8(0x5C);
5479
emit_operand(dst, src);
5480
}
5481
5482
void Assembler::subss(XMMRegister dst, XMMRegister src) {
5483
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5484
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true , /* uses_vl */ false);
5485
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5486
emit_int16(0x5C, (0xC0 | encode));
5487
}
5488
5489
void Assembler::subss(XMMRegister dst, Address src) {
5490
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5491
InstructionMark im(this);
5492
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5493
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5494
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5495
emit_int8(0x5C);
5496
emit_operand(dst, src);
5497
}
5498
5499
void Assembler::testb(Register dst, int imm8) {
5500
NOT_LP64(assert(dst->has_byte_register(), "must have byte register"));
5501
(void) prefix_and_encode(dst->encoding(), true);
5502
emit_arith_b(0xF6, 0xC0, dst, imm8);
5503
}
5504
5505
void Assembler::testb(Address dst, int imm8) {
5506
InstructionMark im(this);
5507
prefix(dst);
5508
emit_int8((unsigned char)0xF6);
5509
emit_operand(rax, dst, 1);
5510
emit_int8(imm8);
5511
}
5512
5513
void Assembler::testl(Register dst, int32_t imm32) {
5514
// not using emit_arith because test
5515
// doesn't support sign-extension of
5516
// 8bit operands
5517
int encode = dst->encoding();
5518
encode = prefix_and_encode(encode);
5519
emit_int16((unsigned char)0xF7, (0xC0 | encode));
5520
emit_int32(imm32);
5521
}
5522
5523
void Assembler::testl(Register dst, Register src) {
5524
(void) prefix_and_encode(dst->encoding(), src->encoding());
5525
emit_arith(0x85, 0xC0, dst, src);
5526
}
5527
5528
void Assembler::testl(Register dst, Address src) {
5529
InstructionMark im(this);
5530
prefix(src, dst);
5531
emit_int8((unsigned char)0x85);
5532
emit_operand(dst, src);
5533
}
5534
5535
void Assembler::tzcntl(Register dst, Register src) {
5536
assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported");
5537
emit_int8((unsigned char)0xF3);
5538
int encode = prefix_and_encode(dst->encoding(), src->encoding());
5539
emit_int24(0x0F,
5540
(unsigned char)0xBC,
5541
0xC0 | encode);
5542
}
5543
5544
void Assembler::tzcntq(Register dst, Register src) {
5545
assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported");
5546
emit_int8((unsigned char)0xF3);
5547
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
5548
emit_int24(0x0F, (unsigned char)0xBC, (0xC0 | encode));
5549
}
5550
5551
void Assembler::ucomisd(XMMRegister dst, Address src) {
5552
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5553
InstructionMark im(this);
5554
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5555
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5556
attributes.set_rex_vex_w_reverted();
5557
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5558
emit_int8(0x2E);
5559
emit_operand(dst, src);
5560
}
5561
5562
void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
5563
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5564
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5565
attributes.set_rex_vex_w_reverted();
5566
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5567
emit_int16(0x2E, (0xC0 | encode));
5568
}
5569
5570
void Assembler::ucomiss(XMMRegister dst, Address src) {
5571
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5572
InstructionMark im(this);
5573
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5574
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5575
simd_prefix(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5576
emit_int8(0x2E);
5577
emit_operand(dst, src);
5578
}
5579
5580
void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
5581
NOT_LP64(assert(VM_Version::supports_sse(), ""));
5582
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5583
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5584
emit_int16(0x2E, (0xC0 | encode));
5585
}
5586
5587
void Assembler::xabort(int8_t imm8) {
5588
emit_int24((unsigned char)0xC6, (unsigned char)0xF8, (imm8 & 0xFF));
5589
}
5590
5591
void Assembler::xaddb(Address dst, Register src) {
5592
InstructionMark im(this);
5593
prefix(dst, src, true);
5594
emit_int16(0x0F, (unsigned char)0xC0);
5595
emit_operand(src, dst);
5596
}
5597
5598
void Assembler::xaddw(Address dst, Register src) {
5599
InstructionMark im(this);
5600
emit_int8(0x66);
5601
prefix(dst, src);
5602
emit_int16(0x0F, (unsigned char)0xC1);
5603
emit_operand(src, dst);
5604
}
5605
5606
void Assembler::xaddl(Address dst, Register src) {
5607
InstructionMark im(this);
5608
prefix(dst, src);
5609
emit_int16(0x0F, (unsigned char)0xC1);
5610
emit_operand(src, dst);
5611
}
5612
5613
void Assembler::xbegin(Label& abort, relocInfo::relocType rtype) {
5614
InstructionMark im(this);
5615
relocate(rtype);
5616
if (abort.is_bound()) {
5617
address entry = target(abort);
5618
assert(entry != NULL, "abort entry NULL");
5619
intptr_t offset = entry - pc();
5620
emit_int16((unsigned char)0xC7, (unsigned char)0xF8);
5621
emit_int32(offset - 6); // 2 opcode + 4 address
5622
} else {
5623
abort.add_patch_at(code(), locator());
5624
emit_int16((unsigned char)0xC7, (unsigned char)0xF8);
5625
emit_int32(0);
5626
}
5627
}
5628
5629
void Assembler::xchgb(Register dst, Address src) { // xchg
5630
InstructionMark im(this);
5631
prefix(src, dst, true);
5632
emit_int8((unsigned char)0x86);
5633
emit_operand(dst, src);
5634
}
5635
5636
void Assembler::xchgw(Register dst, Address src) { // xchg
5637
InstructionMark im(this);
5638
emit_int8(0x66);
5639
prefix(src, dst);
5640
emit_int8((unsigned char)0x87);
5641
emit_operand(dst, src);
5642
}
5643
5644
void Assembler::xchgl(Register dst, Address src) { // xchg
5645
InstructionMark im(this);
5646
prefix(src, dst);
5647
emit_int8((unsigned char)0x87);
5648
emit_operand(dst, src);
5649
}
5650
5651
void Assembler::xchgl(Register dst, Register src) {
5652
int encode = prefix_and_encode(dst->encoding(), src->encoding());
5653
emit_int16((unsigned char)0x87, (0xC0 | encode));
5654
}
5655
5656
void Assembler::xend() {
5657
emit_int24(0x0F, 0x01, (unsigned char)0xD5);
5658
}
5659
5660
void Assembler::xgetbv() {
5661
emit_int24(0x0F, 0x01, (unsigned char)0xD0);
5662
}
5663
5664
void Assembler::xorl(Address dst, int32_t imm32) {
5665
InstructionMark im(this);
5666
prefix(dst);
5667
emit_arith_operand(0x81, as_Register(6), dst, imm32);
5668
}
5669
5670
void Assembler::xorl(Register dst, int32_t imm32) {
5671
prefix(dst);
5672
emit_arith(0x81, 0xF0, dst, imm32);
5673
}
5674
5675
void Assembler::xorl(Register dst, Address src) {
5676
InstructionMark im(this);
5677
prefix(src, dst);
5678
emit_int8(0x33);
5679
emit_operand(dst, src);
5680
}
5681
5682
void Assembler::xorl(Register dst, Register src) {
5683
(void) prefix_and_encode(dst->encoding(), src->encoding());
5684
emit_arith(0x33, 0xC0, dst, src);
5685
}
5686
5687
void Assembler::xorl(Address dst, Register src) {
5688
InstructionMark im(this);
5689
prefix(dst, src);
5690
emit_int8(0x31);
5691
emit_operand(src, dst);
5692
}
5693
5694
void Assembler::xorb(Register dst, Address src) {
5695
InstructionMark im(this);
5696
prefix(src, dst);
5697
emit_int8(0x32);
5698
emit_operand(dst, src);
5699
}
5700
5701
void Assembler::xorb(Address dst, Register src) {
5702
InstructionMark im(this);
5703
prefix(dst, src, true);
5704
emit_int8(0x30);
5705
emit_operand(src, dst);
5706
}
5707
5708
void Assembler::xorw(Register dst, Register src) {
5709
(void)prefix_and_encode(dst->encoding(), src->encoding());
5710
emit_arith(0x33, 0xC0, dst, src);
5711
}
5712
5713
// AVX 3-operands scalar float-point arithmetic instructions
5714
5715
void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
5716
assert(VM_Version::supports_avx(), "");
5717
InstructionMark im(this);
5718
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5719
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5720
attributes.set_rex_vex_w_reverted();
5721
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5722
emit_int8(0x58);
5723
emit_operand(dst, src);
5724
}
5725
5726
void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5727
assert(VM_Version::supports_avx(), "");
5728
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5729
attributes.set_rex_vex_w_reverted();
5730
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5731
emit_int16(0x58, (0xC0 | encode));
5732
}
5733
5734
void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
5735
assert(VM_Version::supports_avx(), "");
5736
InstructionMark im(this);
5737
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5738
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5739
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5740
emit_int8(0x58);
5741
emit_operand(dst, src);
5742
}
5743
5744
void Assembler::vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5745
assert(VM_Version::supports_avx(), "");
5746
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5747
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5748
emit_int16(0x58, (0xC0 | encode));
5749
}
5750
5751
void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
5752
assert(VM_Version::supports_avx(), "");
5753
InstructionMark im(this);
5754
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5755
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5756
attributes.set_rex_vex_w_reverted();
5757
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5758
emit_int8(0x5E);
5759
emit_operand(dst, src);
5760
}
5761
5762
void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5763
assert(VM_Version::supports_avx(), "");
5764
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5765
attributes.set_rex_vex_w_reverted();
5766
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5767
emit_int16(0x5E, (0xC0 | encode));
5768
}
5769
5770
void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
5771
assert(VM_Version::supports_avx(), "");
5772
InstructionMark im(this);
5773
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5774
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5775
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5776
emit_int8(0x5E);
5777
emit_operand(dst, src);
5778
}
5779
5780
void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5781
assert(VM_Version::supports_avx(), "");
5782
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5783
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5784
emit_int16(0x5E, (0xC0 | encode));
5785
}
5786
5787
void Assembler::vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
5788
assert(VM_Version::supports_fma(), "");
5789
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* 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::vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
5795
assert(VM_Version::supports_fma(), "");
5796
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5797
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
5798
emit_int16((unsigned char)0xB9, (0xC0 | encode));
5799
}
5800
5801
void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
5802
assert(VM_Version::supports_avx(), "");
5803
InstructionMark im(this);
5804
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5805
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5806
attributes.set_rex_vex_w_reverted();
5807
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5808
emit_int8(0x59);
5809
emit_operand(dst, src);
5810
}
5811
5812
void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5813
assert(VM_Version::supports_avx(), "");
5814
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5815
attributes.set_rex_vex_w_reverted();
5816
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5817
emit_int16(0x59, (0xC0 | encode));
5818
}
5819
5820
void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
5821
assert(VM_Version::supports_avx(), "");
5822
InstructionMark im(this);
5823
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5824
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5825
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5826
emit_int8(0x59);
5827
emit_operand(dst, src);
5828
}
5829
5830
void Assembler::vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5831
assert(VM_Version::supports_avx(), "");
5832
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5833
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5834
emit_int16(0x59, (0xC0 | encode));
5835
}
5836
5837
void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
5838
assert(VM_Version::supports_avx(), "");
5839
InstructionMark im(this);
5840
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5841
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
5842
attributes.set_rex_vex_w_reverted();
5843
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5844
emit_int8(0x5C);
5845
emit_operand(dst, src);
5846
}
5847
5848
void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5849
assert(VM_Version::supports_avx(), "");
5850
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5851
attributes.set_rex_vex_w_reverted();
5852
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
5853
emit_int16(0x5C, (0xC0 | encode));
5854
}
5855
5856
void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
5857
assert(VM_Version::supports_avx(), "");
5858
InstructionMark im(this);
5859
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5860
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
5861
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5862
emit_int8(0x5C);
5863
emit_operand(dst, src);
5864
}
5865
5866
void Assembler::vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
5867
assert(VM_Version::supports_avx(), "");
5868
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
5869
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
5870
emit_int16(0x5C, (0xC0 | encode));
5871
}
5872
5873
//====================VECTOR ARITHMETIC=====================================
5874
5875
// Float-point vector arithmetic
5876
5877
void Assembler::addpd(XMMRegister dst, XMMRegister src) {
5878
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5879
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5880
attributes.set_rex_vex_w_reverted();
5881
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5882
emit_int16(0x58, (0xC0 | encode));
5883
}
5884
5885
void Assembler::addpd(XMMRegister dst, Address src) {
5886
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5887
InstructionMark im(this);
5888
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5889
attributes.set_rex_vex_w_reverted();
5890
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5891
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5892
emit_int8(0x58);
5893
emit_operand(dst, src);
5894
}
5895
5896
5897
void Assembler::addps(XMMRegister dst, XMMRegister src) {
5898
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5899
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5900
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5901
emit_int16(0x58, (0xC0 | encode));
5902
}
5903
5904
void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5905
assert(VM_Version::supports_avx(), "");
5906
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5907
attributes.set_rex_vex_w_reverted();
5908
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5909
emit_int16(0x58, (0xC0 | encode));
5910
}
5911
5912
void Assembler::vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5913
assert(VM_Version::supports_avx(), "");
5914
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5915
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5916
emit_int16(0x58, (0xC0 | encode));
5917
}
5918
5919
void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5920
assert(VM_Version::supports_avx(), "");
5921
InstructionMark im(this);
5922
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5923
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5924
attributes.set_rex_vex_w_reverted();
5925
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5926
emit_int8(0x58);
5927
emit_operand(dst, src);
5928
}
5929
5930
void Assembler::vaddps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5931
assert(VM_Version::supports_avx(), "");
5932
InstructionMark im(this);
5933
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5934
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
5935
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5936
emit_int8(0x58);
5937
emit_operand(dst, src);
5938
}
5939
5940
void Assembler::subpd(XMMRegister dst, XMMRegister src) {
5941
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5942
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5943
attributes.set_rex_vex_w_reverted();
5944
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5945
emit_int16(0x5C, (0xC0 | encode));
5946
}
5947
5948
void Assembler::subps(XMMRegister dst, XMMRegister src) {
5949
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5950
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5951
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5952
emit_int16(0x5C, (0xC0 | encode));
5953
}
5954
5955
void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5956
assert(VM_Version::supports_avx(), "");
5957
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5958
attributes.set_rex_vex_w_reverted();
5959
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5960
emit_int16(0x5C, (0xC0 | encode));
5961
}
5962
5963
void Assembler::vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
5964
assert(VM_Version::supports_avx(), "");
5965
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5966
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5967
emit_int16(0x5C, (0xC0 | encode));
5968
}
5969
5970
void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5971
assert(VM_Version::supports_avx(), "");
5972
InstructionMark im(this);
5973
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5974
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
5975
attributes.set_rex_vex_w_reverted();
5976
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5977
emit_int8(0x5C);
5978
emit_operand(dst, src);
5979
}
5980
5981
void Assembler::vsubps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
5982
assert(VM_Version::supports_avx(), "");
5983
InstructionMark im(this);
5984
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5985
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
5986
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
5987
emit_int8(0x5C);
5988
emit_operand(dst, src);
5989
}
5990
5991
void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
5992
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
5993
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
5994
attributes.set_rex_vex_w_reverted();
5995
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
5996
emit_int16(0x59, (0xC0 | encode));
5997
}
5998
5999
void Assembler::mulpd(XMMRegister dst, Address src) {
6000
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6001
InstructionMark im(this);
6002
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6003
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6004
attributes.set_rex_vex_w_reverted();
6005
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6006
emit_int8(0x59);
6007
emit_operand(dst, src);
6008
}
6009
6010
void Assembler::mulps(XMMRegister dst, XMMRegister src) {
6011
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6012
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6013
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6014
emit_int16(0x59, (0xC0 | encode));
6015
}
6016
6017
void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6018
assert(VM_Version::supports_avx(), "");
6019
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6020
attributes.set_rex_vex_w_reverted();
6021
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6022
emit_int16(0x59, (0xC0 | encode));
6023
}
6024
6025
void Assembler::vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6026
assert(VM_Version::supports_avx(), "");
6027
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6028
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6029
emit_int16(0x59, (0xC0 | encode));
6030
}
6031
6032
void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6033
assert(VM_Version::supports_avx(), "");
6034
InstructionMark im(this);
6035
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6036
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6037
attributes.set_rex_vex_w_reverted();
6038
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6039
emit_int8(0x59);
6040
emit_operand(dst, src);
6041
}
6042
6043
void Assembler::vmulps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6044
assert(VM_Version::supports_avx(), "");
6045
InstructionMark im(this);
6046
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6047
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6048
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6049
emit_int8(0x59);
6050
emit_operand(dst, src);
6051
}
6052
6053
void Assembler::vfmadd231pd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len) {
6054
assert(VM_Version::supports_fma(), "");
6055
InstructionAttr attributes(vector_len, /* vex_w */ true, /* 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::vfmadd231ps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len) {
6061
assert(VM_Version::supports_fma(), "");
6062
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6063
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6064
emit_int16((unsigned char)0xB8, (0xC0 | encode));
6065
}
6066
6067
void Assembler::vfmadd231pd(XMMRegister dst, XMMRegister src1, Address src2, int vector_len) {
6068
assert(VM_Version::supports_fma(), "");
6069
InstructionMark im(this);
6070
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6071
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6072
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6073
emit_int8((unsigned char)0xB8);
6074
emit_operand(dst, src2);
6075
}
6076
6077
void Assembler::vfmadd231ps(XMMRegister dst, XMMRegister src1, Address src2, int vector_len) {
6078
assert(VM_Version::supports_fma(), "");
6079
InstructionMark im(this);
6080
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6081
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6082
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6083
emit_int8((unsigned char)0xB8);
6084
emit_operand(dst, src2);
6085
}
6086
6087
void Assembler::divpd(XMMRegister dst, XMMRegister src) {
6088
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6089
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6090
attributes.set_rex_vex_w_reverted();
6091
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6092
emit_int16(0x5E, (0xC0 | encode));
6093
}
6094
6095
void Assembler::divps(XMMRegister dst, XMMRegister src) {
6096
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6097
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6098
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6099
emit_int16(0x5E, (0xC0 | encode));
6100
}
6101
6102
void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6103
assert(VM_Version::supports_avx(), "");
6104
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6105
attributes.set_rex_vex_w_reverted();
6106
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6107
emit_int16(0x5E, (0xC0 | encode));
6108
}
6109
6110
void Assembler::vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6111
assert(VM_Version::supports_avx(), "");
6112
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6113
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6114
emit_int16(0x5E, (0xC0 | encode));
6115
}
6116
6117
void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6118
assert(VM_Version::supports_avx(), "");
6119
InstructionMark im(this);
6120
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6121
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6122
attributes.set_rex_vex_w_reverted();
6123
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6124
emit_int8(0x5E);
6125
emit_operand(dst, src);
6126
}
6127
6128
void Assembler::vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6129
assert(VM_Version::supports_avx(), "");
6130
InstructionMark im(this);
6131
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6132
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6133
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6134
emit_int8(0x5E);
6135
emit_operand(dst, src);
6136
}
6137
6138
void Assembler::vroundpd(XMMRegister dst, XMMRegister src, int32_t rmode, int vector_len) {
6139
assert(VM_Version::supports_avx(), "");
6140
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
6141
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6142
emit_int24(0x09, (0xC0 | encode), (rmode));
6143
}
6144
6145
void Assembler::vroundpd(XMMRegister dst, Address src, int32_t rmode, int vector_len) {
6146
assert(VM_Version::supports_avx(), "");
6147
InstructionMark im(this);
6148
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
6149
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6150
emit_int8(0x09);
6151
emit_operand(dst, src);
6152
emit_int8((rmode));
6153
}
6154
6155
void Assembler::vrndscalepd(XMMRegister dst, XMMRegister src, int32_t rmode, int vector_len) {
6156
assert(VM_Version::supports_evex(), "requires EVEX support");
6157
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6158
attributes.set_is_evex_instruction();
6159
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6160
emit_int24(0x09, (0xC0 | encode), (rmode));
6161
}
6162
6163
void Assembler::vrndscalepd(XMMRegister dst, Address src, int32_t rmode, int vector_len) {
6164
assert(VM_Version::supports_evex(), "requires EVEX support");
6165
assert(dst != xnoreg, "sanity");
6166
InstructionMark im(this);
6167
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6168
attributes.set_is_evex_instruction();
6169
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6170
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
6171
emit_int8(0x09);
6172
emit_operand(dst, src);
6173
emit_int8((rmode));
6174
}
6175
6176
6177
void Assembler::vsqrtpd(XMMRegister dst, XMMRegister src, int vector_len) {
6178
assert(VM_Version::supports_avx(), "");
6179
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6180
attributes.set_rex_vex_w_reverted();
6181
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6182
emit_int16(0x51, (0xC0 | encode));
6183
}
6184
6185
void Assembler::vsqrtpd(XMMRegister dst, Address src, int vector_len) {
6186
assert(VM_Version::supports_avx(), "");
6187
InstructionMark im(this);
6188
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6189
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6190
attributes.set_rex_vex_w_reverted();
6191
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6192
emit_int8(0x51);
6193
emit_operand(dst, src);
6194
}
6195
6196
void Assembler::vsqrtps(XMMRegister dst, XMMRegister src, int vector_len) {
6197
assert(VM_Version::supports_avx(), "");
6198
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6199
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6200
emit_int16(0x51, (0xC0 | encode));
6201
}
6202
6203
void Assembler::vsqrtps(XMMRegister dst, Address src, int vector_len) {
6204
assert(VM_Version::supports_avx(), "");
6205
InstructionMark im(this);
6206
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6207
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6208
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6209
emit_int8(0x51);
6210
emit_operand(dst, src);
6211
}
6212
6213
void Assembler::andpd(XMMRegister dst, XMMRegister src) {
6214
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6215
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6216
attributes.set_rex_vex_w_reverted();
6217
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6218
emit_int16(0x54, (0xC0 | encode));
6219
}
6220
6221
void Assembler::andps(XMMRegister dst, XMMRegister src) {
6222
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6223
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6224
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6225
emit_int16(0x54, (0xC0 | encode));
6226
}
6227
6228
void Assembler::andps(XMMRegister dst, Address src) {
6229
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6230
InstructionMark im(this);
6231
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6232
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6233
simd_prefix(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6234
emit_int8(0x54);
6235
emit_operand(dst, src);
6236
}
6237
6238
void Assembler::andpd(XMMRegister dst, Address src) {
6239
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6240
InstructionMark im(this);
6241
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6242
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6243
attributes.set_rex_vex_w_reverted();
6244
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6245
emit_int8(0x54);
6246
emit_operand(dst, src);
6247
}
6248
6249
void Assembler::vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6250
assert(VM_Version::supports_avx(), "");
6251
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6252
attributes.set_rex_vex_w_reverted();
6253
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6254
emit_int16(0x54, (0xC0 | encode));
6255
}
6256
6257
void Assembler::vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6258
assert(VM_Version::supports_avx(), "");
6259
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6260
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6261
emit_int16(0x54, (0xC0 | encode));
6262
}
6263
6264
void Assembler::vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6265
assert(VM_Version::supports_avx(), "");
6266
InstructionMark im(this);
6267
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6268
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6269
attributes.set_rex_vex_w_reverted();
6270
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6271
emit_int8(0x54);
6272
emit_operand(dst, src);
6273
}
6274
6275
void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6276
assert(VM_Version::supports_avx(), "");
6277
InstructionMark im(this);
6278
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6279
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6280
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6281
emit_int8(0x54);
6282
emit_operand(dst, src);
6283
}
6284
6285
void Assembler::unpckhpd(XMMRegister dst, XMMRegister src) {
6286
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6287
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6288
attributes.set_rex_vex_w_reverted();
6289
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6290
emit_int8(0x15);
6291
emit_int8((0xC0 | encode));
6292
}
6293
6294
void Assembler::unpcklpd(XMMRegister dst, XMMRegister src) {
6295
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6296
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6297
attributes.set_rex_vex_w_reverted();
6298
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6299
emit_int16(0x14, (0xC0 | encode));
6300
}
6301
6302
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
6303
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6304
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6305
attributes.set_rex_vex_w_reverted();
6306
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6307
emit_int16(0x57, (0xC0 | encode));
6308
}
6309
6310
void Assembler::xorps(XMMRegister dst, XMMRegister src) {
6311
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6312
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6313
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6314
emit_int16(0x57, (0xC0 | encode));
6315
}
6316
6317
void Assembler::xorpd(XMMRegister dst, Address src) {
6318
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6319
InstructionMark im(this);
6320
InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6321
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6322
attributes.set_rex_vex_w_reverted();
6323
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6324
emit_int8(0x57);
6325
emit_operand(dst, src);
6326
}
6327
6328
void Assembler::xorps(XMMRegister dst, Address src) {
6329
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6330
InstructionMark im(this);
6331
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6332
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6333
simd_prefix(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6334
emit_int8(0x57);
6335
emit_operand(dst, src);
6336
}
6337
6338
void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6339
assert(VM_Version::supports_avx(), "");
6340
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6341
attributes.set_rex_vex_w_reverted();
6342
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6343
emit_int16(0x57, (0xC0 | encode));
6344
}
6345
6346
void Assembler::vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6347
assert(VM_Version::supports_avx(), "");
6348
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6349
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6350
emit_int16(0x57, (0xC0 | encode));
6351
}
6352
6353
void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6354
assert(VM_Version::supports_avx(), "");
6355
InstructionMark im(this);
6356
InstructionAttr attributes(vector_len, /* vex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6357
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6358
attributes.set_rex_vex_w_reverted();
6359
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6360
emit_int8(0x57);
6361
emit_operand(dst, src);
6362
}
6363
6364
void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6365
assert(VM_Version::supports_avx(), "");
6366
InstructionMark im(this);
6367
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6368
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6369
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6370
emit_int8(0x57);
6371
emit_operand(dst, src);
6372
}
6373
6374
// Integer vector arithmetic
6375
void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6376
assert(VM_Version::supports_avx() && (vector_len == 0) ||
6377
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
6378
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6379
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6380
emit_int16(0x01, (0xC0 | encode));
6381
}
6382
6383
void Assembler::vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6384
assert(VM_Version::supports_avx() && (vector_len == 0) ||
6385
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
6386
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6387
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6388
emit_int16(0x02, (0xC0 | encode));
6389
}
6390
6391
void Assembler::paddb(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)0xFC, (0xC0 | encode));
6396
}
6397
6398
void Assembler::paddw(XMMRegister dst, XMMRegister src) {
6399
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6400
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* 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)0xFD, (0xC0 | encode));
6403
}
6404
6405
void Assembler::paddd(XMMRegister dst, XMMRegister src) {
6406
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6407
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6408
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6409
emit_int16((unsigned char)0xFE, (0xC0 | encode));
6410
}
6411
6412
void Assembler::paddd(XMMRegister dst, Address src) {
6413
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6414
InstructionMark im(this);
6415
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6416
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6417
emit_int8((unsigned char)0xFE);
6418
emit_operand(dst, src);
6419
}
6420
6421
void Assembler::paddq(XMMRegister dst, XMMRegister src) {
6422
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6423
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6424
attributes.set_rex_vex_w_reverted();
6425
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6426
emit_int16((unsigned char)0xD4, (0xC0 | encode));
6427
}
6428
6429
void Assembler::phaddw(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(0x01, (0xC0 | encode));
6434
}
6435
6436
void Assembler::phaddd(XMMRegister dst, XMMRegister src) {
6437
assert(VM_Version::supports_sse3(), "");
6438
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
6439
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6440
emit_int16(0x02, (0xC0 | encode));
6441
}
6442
6443
void Assembler::vpaddb(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)0xFC, (0xC0 | encode));
6448
}
6449
6450
void Assembler::vpaddw(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 */ _legacy_mode_bw, /* 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)0xFD, (0xC0 | encode));
6455
}
6456
6457
void Assembler::vpaddd(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 */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6460
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6461
emit_int16((unsigned char)0xFE, (0xC0 | encode));
6462
}
6463
6464
void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6465
assert(UseAVX > 0, "requires some form of AVX");
6466
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6467
attributes.set_rex_vex_w_reverted();
6468
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6469
emit_int16((unsigned char)0xD4, (0xC0 | encode));
6470
}
6471
6472
void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6473
assert(UseAVX > 0, "requires some form of AVX");
6474
InstructionMark im(this);
6475
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6476
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6477
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6478
emit_int8((unsigned char)0xFC);
6479
emit_operand(dst, src);
6480
}
6481
6482
void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6483
assert(UseAVX > 0, "requires some form of AVX");
6484
InstructionMark im(this);
6485
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6486
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6487
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6488
emit_int8((unsigned char)0xFD);
6489
emit_operand(dst, src);
6490
}
6491
6492
void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6493
assert(UseAVX > 0, "requires some form of AVX");
6494
InstructionMark im(this);
6495
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6496
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6497
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6498
emit_int8((unsigned char)0xFE);
6499
emit_operand(dst, src);
6500
}
6501
6502
void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6503
assert(UseAVX > 0, "requires some form of AVX");
6504
InstructionMark im(this);
6505
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6506
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6507
attributes.set_rex_vex_w_reverted();
6508
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6509
emit_int8((unsigned char)0xD4);
6510
emit_operand(dst, src);
6511
}
6512
6513
void Assembler::psubb(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)0xF8, (0xC0 | encode));
6518
}
6519
6520
void Assembler::psubw(XMMRegister dst, XMMRegister src) {
6521
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6522
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6523
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6524
emit_int16((unsigned char)0xF9, (0xC0 | encode));
6525
}
6526
6527
void Assembler::psubd(XMMRegister dst, XMMRegister src) {
6528
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6529
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6530
emit_int16((unsigned char)0xFA, (0xC0 | encode));
6531
}
6532
6533
void Assembler::psubq(XMMRegister dst, XMMRegister src) {
6534
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6535
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6536
attributes.set_rex_vex_w_reverted();
6537
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6538
emit_int8((unsigned char)0xFB);
6539
emit_int8((0xC0 | encode));
6540
}
6541
6542
void Assembler::vpsubb(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)0xF8, (0xC0 | encode));
6547
}
6548
6549
void Assembler::vpsubw(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 */ _legacy_mode_bw, /* 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)0xF9, (0xC0 | encode));
6554
}
6555
6556
void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6557
assert(UseAVX > 0, "requires some form of AVX");
6558
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6559
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6560
emit_int16((unsigned char)0xFA, (0xC0 | encode));
6561
}
6562
6563
void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6564
assert(UseAVX > 0, "requires some form of AVX");
6565
InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6566
attributes.set_rex_vex_w_reverted();
6567
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6568
emit_int16((unsigned char)0xFB, (0xC0 | encode));
6569
}
6570
6571
void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6572
assert(UseAVX > 0, "requires some form of AVX");
6573
InstructionMark im(this);
6574
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6575
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6576
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6577
emit_int8((unsigned char)0xF8);
6578
emit_operand(dst, src);
6579
}
6580
6581
void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6582
assert(UseAVX > 0, "requires some form of AVX");
6583
InstructionMark im(this);
6584
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6585
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6586
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6587
emit_int8((unsigned char)0xF9);
6588
emit_operand(dst, src);
6589
}
6590
6591
void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6592
assert(UseAVX > 0, "requires some form of AVX");
6593
InstructionMark im(this);
6594
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6595
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6596
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6597
emit_int8((unsigned char)0xFA);
6598
emit_operand(dst, src);
6599
}
6600
6601
void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6602
assert(UseAVX > 0, "requires some form of AVX");
6603
InstructionMark im(this);
6604
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6605
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6606
attributes.set_rex_vex_w_reverted();
6607
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6608
emit_int8((unsigned char)0xFB);
6609
emit_operand(dst, src);
6610
}
6611
6612
void Assembler::pmullw(XMMRegister dst, XMMRegister src) {
6613
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6614
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6615
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6616
emit_int16((unsigned char)0xD5, (0xC0 | encode));
6617
}
6618
6619
void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
6620
assert(VM_Version::supports_sse4_1(), "");
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_38, &attributes);
6623
emit_int16(0x40, (0xC0 | encode));
6624
}
6625
6626
void Assembler::pmuludq(XMMRegister dst, XMMRegister src) {
6627
assert(VM_Version::supports_sse2(), "");
6628
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6629
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6630
emit_int16((unsigned char)0xF4, (0xC0 | encode));
6631
}
6632
6633
void Assembler::vpmullw(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 */ _legacy_mode_bw, /* 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, &attributes);
6637
emit_int16((unsigned char)0xD5, (0xC0 | encode));
6638
}
6639
6640
void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6641
assert(UseAVX > 0, "requires some form of AVX");
6642
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6643
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6644
emit_int16(0x40, (0xC0 | encode));
6645
}
6646
6647
void Assembler::vpmullq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6648
assert(UseAVX > 2, "requires some form of EVEX");
6649
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6650
attributes.set_is_evex_instruction();
6651
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6652
emit_int16(0x40, (0xC0 | encode));
6653
}
6654
6655
void Assembler::vpmuludq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6656
assert(UseAVX > 0, "requires some form of AVX");
6657
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6658
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6659
emit_int16((unsigned char)0xF4, (0xC0 | encode));
6660
}
6661
6662
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6663
assert(UseAVX > 0, "requires some form of AVX");
6664
InstructionMark im(this);
6665
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6666
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
6667
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6668
emit_int8((unsigned char)0xD5);
6669
emit_operand(dst, src);
6670
}
6671
6672
void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6673
assert(UseAVX > 0, "requires some form of AVX");
6674
InstructionMark im(this);
6675
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6676
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
6677
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6678
emit_int8(0x40);
6679
emit_operand(dst, src);
6680
}
6681
6682
void Assembler::vpmullq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
6683
assert(UseAVX > 2, "requires some form of EVEX");
6684
InstructionMark im(this);
6685
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true);
6686
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
6687
attributes.set_is_evex_instruction();
6688
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6689
emit_int8(0x40);
6690
emit_operand(dst, src);
6691
}
6692
6693
// Min, max
6694
void Assembler::pminsb(XMMRegister dst, XMMRegister src) {
6695
assert(VM_Version::supports_sse4_1(), "");
6696
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6697
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6698
emit_int16(0x38, (0xC0 | encode));
6699
}
6700
6701
void Assembler::vpminsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6702
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6703
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6704
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6705
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6706
emit_int16(0x38, (0xC0 | encode));
6707
}
6708
6709
void Assembler::pminsw(XMMRegister dst, XMMRegister src) {
6710
assert(VM_Version::supports_sse2(), "");
6711
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6712
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6713
emit_int16((unsigned char)0xEA, (0xC0 | encode));
6714
}
6715
6716
void Assembler::vpminsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6717
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6718
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6719
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6720
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6721
emit_int16((unsigned char)0xEA, (0xC0 | encode));
6722
}
6723
6724
void Assembler::pminsd(XMMRegister dst, XMMRegister src) {
6725
assert(VM_Version::supports_sse4_1(), "");
6726
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6727
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6728
emit_int16(0x39, (0xC0 | encode));
6729
}
6730
6731
void Assembler::vpminsd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6732
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6733
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex()), "");
6734
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6735
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6736
emit_int16(0x39, (0xC0 | encode));
6737
}
6738
6739
void Assembler::vpminsq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6740
assert(UseAVX > 2, "requires AVX512F");
6741
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6742
attributes.set_is_evex_instruction();
6743
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6744
emit_int16(0x39, (0xC0 | encode));
6745
}
6746
6747
void Assembler::minps(XMMRegister dst, XMMRegister src) {
6748
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6749
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6750
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6751
emit_int16(0x5D, (0xC0 | encode));
6752
}
6753
void Assembler::vminps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6754
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6755
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6756
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6757
emit_int16(0x5D, (0xC0 | encode));
6758
}
6759
6760
void Assembler::minpd(XMMRegister dst, XMMRegister src) {
6761
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6762
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6763
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6764
emit_int16(0x5D, (0xC0 | encode));
6765
}
6766
void Assembler::vminpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6767
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6768
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6769
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6770
emit_int16(0x5D, (0xC0 | encode));
6771
}
6772
6773
void Assembler::pmaxsb(XMMRegister dst, XMMRegister src) {
6774
assert(VM_Version::supports_sse4_1(), "");
6775
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6776
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6777
emit_int16(0x3C, (0xC0 | encode));
6778
}
6779
6780
void Assembler::vpmaxsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6781
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6782
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6783
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6784
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6785
emit_int16(0x3C, (0xC0 | encode));
6786
}
6787
6788
void Assembler::pmaxsw(XMMRegister dst, XMMRegister src) {
6789
assert(VM_Version::supports_sse2(), "");
6790
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6791
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6792
emit_int16((unsigned char)0xEE, (0xC0 | encode));
6793
}
6794
6795
void Assembler::vpmaxsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6796
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6797
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
6798
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6799
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6800
emit_int16((unsigned char)0xEE, (0xC0 | encode));
6801
}
6802
6803
void Assembler::pmaxsd(XMMRegister dst, XMMRegister src) {
6804
assert(VM_Version::supports_sse4_1(), "");
6805
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6806
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6807
emit_int16(0x3D, (0xC0 | encode));
6808
}
6809
6810
void Assembler::vpmaxsd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6811
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
6812
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_evex()), "");
6813
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6814
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6815
emit_int16(0x3D, (0xC0 | encode));
6816
}
6817
6818
void Assembler::vpmaxsq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6819
assert(UseAVX > 2, "requires AVX512F");
6820
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6821
attributes.set_is_evex_instruction();
6822
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
6823
emit_int16(0x3D, (0xC0 | encode));
6824
}
6825
6826
void Assembler::maxps(XMMRegister dst, XMMRegister src) {
6827
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6828
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6829
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6830
emit_int16(0x5F, (0xC0 | encode));
6831
}
6832
6833
void Assembler::vmaxps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6834
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6835
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6836
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
6837
emit_int16(0x5F, (0xC0 | encode));
6838
}
6839
6840
void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
6841
NOT_LP64(assert(VM_Version::supports_sse(), ""));
6842
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6843
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6844
emit_int16(0x5F, (0xC0 | encode));
6845
}
6846
6847
void Assembler::vmaxpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
6848
assert(vector_len >= AVX_512bit ? VM_Version::supports_evex() : VM_Version::supports_avx(), "");
6849
InstructionAttr attributes(vector_len, /* vex_w */true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6850
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6851
emit_int16(0x5F, (0xC0 | encode));
6852
}
6853
6854
// Shift packed integers left by specified number of bits.
6855
void Assembler::psllw(XMMRegister dst, int shift) {
6856
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6857
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6858
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
6859
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6860
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6861
}
6862
6863
void Assembler::pslld(XMMRegister dst, int shift) {
6864
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6865
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6866
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
6867
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6868
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
6869
}
6870
6871
void Assembler::psllq(XMMRegister dst, int shift) {
6872
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6873
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6874
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
6875
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6876
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
6877
}
6878
6879
void Assembler::psllw(XMMRegister dst, XMMRegister shift) {
6880
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6881
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* 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)0xF1, (0xC0 | encode));
6884
}
6885
6886
void Assembler::pslld(XMMRegister dst, XMMRegister shift) {
6887
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6888
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6889
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6890
emit_int16((unsigned char)0xF2, (0xC0 | encode));
6891
}
6892
6893
void Assembler::psllq(XMMRegister dst, XMMRegister shift) {
6894
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6895
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6896
attributes.set_rex_vex_w_reverted();
6897
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6898
emit_int16((unsigned char)0xF3, (0xC0 | encode));
6899
}
6900
6901
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6902
assert(UseAVX > 0, "requires some form of AVX");
6903
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6904
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
6905
int encode = vex_prefix_and_encode(xmm6->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6906
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6907
}
6908
6909
void Assembler::vpslld(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6910
assert(UseAVX > 0, "requires some form of AVX");
6911
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6912
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6913
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
6914
int encode = vex_prefix_and_encode(xmm6->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6915
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
6916
}
6917
6918
void Assembler::vpsllq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
6919
assert(UseAVX > 0, "requires some form of AVX");
6920
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6921
attributes.set_rex_vex_w_reverted();
6922
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
6923
int encode = vex_prefix_and_encode(xmm6->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6924
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
6925
}
6926
6927
void Assembler::vpsllw(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 */ _legacy_mode_bw, /* 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)0xF1, (0xC0 | encode));
6932
}
6933
6934
void Assembler::vpslld(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 */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6937
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6938
emit_int16((unsigned char)0xF2, (0xC0 | encode));
6939
}
6940
6941
void Assembler::vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
6942
assert(UseAVX > 0, "requires some form of AVX");
6943
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6944
attributes.set_rex_vex_w_reverted();
6945
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6946
emit_int16((unsigned char)0xF3, (0xC0 | encode));
6947
}
6948
6949
// Shift packed integers logically right by specified number of bits.
6950
void Assembler::psrlw(XMMRegister dst, int shift) {
6951
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6952
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
6953
// XMM2 is for /2 encoding: 66 0F 71 /2 ib
6954
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6955
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
6956
}
6957
6958
void Assembler::psrld(XMMRegister dst, int shift) {
6959
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6960
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6961
// XMM2 is for /2 encoding: 66 0F 72 /2 ib
6962
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6963
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
6964
}
6965
6966
void Assembler::psrlq(XMMRegister dst, int shift) {
6967
// Do not confuse it with psrldq SSE2 instruction which
6968
// shifts 128 bit value in xmm register by number of bytes.
6969
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6970
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6971
attributes.set_rex_vex_w_reverted();
6972
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
6973
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6974
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
6975
}
6976
6977
void Assembler::psrlw(XMMRegister dst, XMMRegister shift) {
6978
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6979
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* 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)0xD1, (0xC0 | encode));
6982
}
6983
6984
void Assembler::psrld(XMMRegister dst, XMMRegister shift) {
6985
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6986
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6987
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6988
emit_int16((unsigned char)0xD2, (0xC0 | encode));
6989
}
6990
6991
void Assembler::psrlq(XMMRegister dst, XMMRegister shift) {
6992
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
6993
InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
6994
attributes.set_rex_vex_w_reverted();
6995
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
6996
emit_int16((unsigned char)0xD3, (0xC0 | encode));
6997
}
6998
6999
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7000
assert(UseAVX > 0, "requires some form of AVX");
7001
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7002
// XMM2 is for /2 encoding: 66 0F 71 /2 ib
7003
int encode = vex_prefix_and_encode(xmm2->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7004
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
7005
}
7006
7007
void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7008
assert(UseAVX > 0, "requires some form of AVX");
7009
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7010
// XMM2 is for /2 encoding: 66 0F 72 /2 ib
7011
int encode = vex_prefix_and_encode(xmm2->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7012
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7013
}
7014
7015
void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7016
assert(UseAVX > 0, "requires some form of AVX");
7017
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7018
attributes.set_rex_vex_w_reverted();
7019
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
7020
int encode = vex_prefix_and_encode(xmm2->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7021
emit_int24(0x73, (0xC0 | encode), shift & 0xFF);
7022
}
7023
7024
void Assembler::vpsrlw(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 */ _legacy_mode_bw, /* 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)0xD1, (0xC0 | encode));
7029
}
7030
7031
void Assembler::vpsrld(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 */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7034
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7035
emit_int16((unsigned char)0xD2, (0xC0 | encode));
7036
}
7037
7038
void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7039
assert(UseAVX > 0, "requires some form of AVX");
7040
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7041
attributes.set_rex_vex_w_reverted();
7042
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7043
emit_int16((unsigned char)0xD3, (0xC0 | encode));
7044
}
7045
7046
void Assembler::evpsrlvw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7047
assert(VM_Version::supports_avx512bw(), "");
7048
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7049
attributes.set_is_evex_instruction();
7050
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7051
emit_int16(0x10, (0xC0 | encode));
7052
}
7053
7054
void Assembler::evpsllvw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7055
assert(VM_Version::supports_avx512bw(), "");
7056
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7057
attributes.set_is_evex_instruction();
7058
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7059
emit_int16(0x12, (0xC0 | encode));
7060
}
7061
7062
// Shift packed integers arithmetically right by specified number of bits.
7063
void Assembler::psraw(XMMRegister dst, int shift) {
7064
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7065
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7066
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
7067
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7068
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
7069
}
7070
7071
void Assembler::psrad(XMMRegister dst, int shift) {
7072
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7073
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7074
// XMM4 is for /4 encoding: 66 0F 72 /4 ib
7075
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7076
emit_int8(0x72);
7077
emit_int8((0xC0 | encode));
7078
emit_int8(shift & 0xFF);
7079
}
7080
7081
void Assembler::psraw(XMMRegister dst, XMMRegister shift) {
7082
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7083
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* 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)0xE1, (0xC0 | encode));
7086
}
7087
7088
void Assembler::psrad(XMMRegister dst, XMMRegister shift) {
7089
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7090
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7091
int encode = simd_prefix_and_encode(dst, dst, shift, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7092
emit_int16((unsigned char)0xE2, (0xC0 | encode));
7093
}
7094
7095
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7096
assert(UseAVX > 0, "requires some form of AVX");
7097
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7098
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
7099
int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7100
emit_int24(0x71, (0xC0 | encode), shift & 0xFF);
7101
}
7102
7103
void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7104
assert(UseAVX > 0, "requires some form of AVX");
7105
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7106
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
7107
int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7108
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7109
}
7110
7111
void Assembler::vpsraw(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 */ _legacy_mode_bw, /* 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)0xE1, (0xC0 | encode));
7116
}
7117
7118
void Assembler::vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7119
assert(UseAVX > 0, "requires some form of AVX");
7120
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7121
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7122
emit_int16((unsigned char)0xE2, (0xC0 | encode));
7123
}
7124
7125
void Assembler::evpsraq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7126
assert(UseAVX > 2, "requires AVX512");
7127
assert ((VM_Version::supports_avx512vl() || vector_len == 2), "requires AVX512vl");
7128
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7129
attributes.set_is_evex_instruction();
7130
int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7131
emit_int24((unsigned char)0x72, (0xC0 | encode), shift & 0xFF);
7132
}
7133
7134
void Assembler::evpsraq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7135
assert(UseAVX > 2, "requires AVX512");
7136
assert ((VM_Version::supports_avx512vl() || vector_len == 2), "requires AVX512vl");
7137
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7138
attributes.set_is_evex_instruction();
7139
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7140
emit_int16((unsigned char)0xE2, (0xC0 | encode));
7141
}
7142
7143
// logical operations packed integers
7144
void Assembler::pand(XMMRegister dst, XMMRegister src) {
7145
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7146
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7147
int encode = simd_prefix_and_encode(dst, dst, src, 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, XMMRegister src, int vector_len) {
7152
assert(UseAVX > 0, "requires some form of AVX");
7153
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7154
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7155
emit_int16((unsigned char)0xDB, (0xC0 | encode));
7156
}
7157
7158
void Assembler::vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7159
assert(UseAVX > 0, "requires some form of AVX");
7160
InstructionMark im(this);
7161
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7162
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
7163
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7164
emit_int8((unsigned char)0xDB);
7165
emit_operand(dst, src);
7166
}
7167
7168
void Assembler::vpandq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7169
assert(VM_Version::supports_evex(), "");
7170
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7171
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7172
emit_int16((unsigned char)0xDB, (0xC0 | encode));
7173
}
7174
7175
//Variable Shift packed integers logically left.
7176
void Assembler::vpsllvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7177
assert(UseAVX > 1, "requires AVX2");
7178
InstructionAttr attributes(vector_len, /* vex_w */ false, /* 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
void Assembler::vpsllvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7184
assert(UseAVX > 1, "requires AVX2");
7185
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7186
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7187
emit_int16(0x47, (0xC0 | encode));
7188
}
7189
7190
//Variable Shift packed integers logically right.
7191
void Assembler::vpsrlvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7192
assert(UseAVX > 1, "requires AVX2");
7193
InstructionAttr attributes(vector_len, /* vex_w */ false, /* 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
void Assembler::vpsrlvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7199
assert(UseAVX > 1, "requires AVX2");
7200
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7201
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7202
emit_int16(0x45, (0xC0 | encode));
7203
}
7204
7205
//Variable right Shift arithmetic packed integers .
7206
void Assembler::vpsravd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7207
assert(UseAVX > 1, "requires AVX2");
7208
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7209
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7210
emit_int16(0x46, (0xC0 | encode));
7211
}
7212
7213
void Assembler::evpsravw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7214
assert(VM_Version::supports_avx512bw(), "");
7215
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7216
attributes.set_is_evex_instruction();
7217
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7218
emit_int16(0x11, (0xC0 | encode));
7219
}
7220
7221
void Assembler::evpsravq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7222
assert(UseAVX > 2, "requires AVX512");
7223
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires AVX512VL");
7224
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7225
attributes.set_is_evex_instruction();
7226
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7227
emit_int16(0x46, (0xC0 | encode));
7228
}
7229
7230
void Assembler::vpshldvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7231
assert(VM_Version::supports_avx512_vbmi2(), "requires vbmi2");
7232
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7233
attributes.set_is_evex_instruction();
7234
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7235
emit_int16(0x71, (0xC0 | encode));
7236
}
7237
7238
void Assembler::vpshrdvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7239
assert(VM_Version::supports_avx512_vbmi2(), "requires vbmi2");
7240
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7241
attributes.set_is_evex_instruction();
7242
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7243
emit_int16(0x73, (0xC0 | encode));
7244
}
7245
7246
void Assembler::pandn(XMMRegister dst, XMMRegister src) {
7247
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7248
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7249
attributes.set_rex_vex_w_reverted();
7250
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7251
emit_int16((unsigned char)0xDF, (0xC0 | encode));
7252
}
7253
7254
void Assembler::vpandn(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7255
assert(UseAVX > 0, "requires some form of AVX");
7256
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7257
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7258
emit_int16((unsigned char)0xDF, (0xC0 | encode));
7259
}
7260
7261
void Assembler::por(XMMRegister dst, XMMRegister src) {
7262
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7263
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7264
int encode = simd_prefix_and_encode(dst, dst, src, 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, XMMRegister src, int vector_len) {
7269
assert(UseAVX > 0, "requires some form of AVX");
7270
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7271
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7272
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7273
}
7274
7275
void Assembler::vpor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7276
assert(UseAVX > 0, "requires some form of AVX");
7277
InstructionMark im(this);
7278
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7279
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
7280
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7281
emit_int8((unsigned char)0xEB);
7282
emit_operand(dst, src);
7283
}
7284
7285
void Assembler::vporq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7286
assert(VM_Version::supports_evex(), "");
7287
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7288
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7289
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7290
}
7291
7292
7293
void Assembler::evpord(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
7294
assert(VM_Version::supports_evex(), "");
7295
// Encoding: EVEX.NDS.XXX.66.0F.W0 EB /r
7296
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
7297
attributes.set_is_evex_instruction();
7298
attributes.set_embedded_opmask_register_specifier(mask);
7299
if (merge) {
7300
attributes.reset_is_clear_context();
7301
}
7302
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7303
emit_int16((unsigned char)0xEB, (0xC0 | encode));
7304
}
7305
7306
void Assembler::evpord(XMMRegister dst, KRegister mask, XMMRegister nds, Address src, bool merge, int vector_len) {
7307
assert(VM_Version::supports_evex(), "");
7308
// Encoding: EVEX.NDS.XXX.66.0F.W0 EB /r
7309
InstructionMark im(this);
7310
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
7311
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
7312
attributes.set_is_evex_instruction();
7313
attributes.set_embedded_opmask_register_specifier(mask);
7314
if (merge) {
7315
attributes.reset_is_clear_context();
7316
}
7317
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7318
emit_int8((unsigned char)0xEB);
7319
emit_operand(dst, src);
7320
}
7321
7322
void Assembler::pxor(XMMRegister dst, XMMRegister src) {
7323
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
7324
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7325
int encode = simd_prefix_and_encode(dst, dst, src, 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, XMMRegister src, int vector_len) {
7330
assert(UseAVX > 0, "requires some form of AVX");
7331
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
7332
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
7333
vector_len == AVX_512bit ? VM_Version::supports_evex() : 0, "");
7334
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7335
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7336
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7337
}
7338
7339
void Assembler::vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7340
assert(UseAVX > 0, "requires some form of AVX");
7341
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
7342
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
7343
vector_len == AVX_512bit ? VM_Version::supports_evex() : 0, "");
7344
InstructionMark im(this);
7345
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7346
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
7347
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7348
emit_int8((unsigned char)0xEF);
7349
emit_operand(dst, src);
7350
}
7351
7352
void Assembler::vpxorq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7353
assert(UseAVX > 2, "requires some form of EVEX");
7354
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7355
attributes.set_rex_vex_w_reverted();
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::evpxord(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
7361
assert(VM_Version::supports_evex(), "");
7362
// Encoding: EVEX.NDS.XXX.66.0F.W0 EF /r
7363
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
7364
attributes.set_is_evex_instruction();
7365
attributes.set_embedded_opmask_register_specifier(mask);
7366
if (merge) {
7367
attributes.reset_is_clear_context();
7368
}
7369
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7370
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7371
}
7372
7373
void Assembler::evpxorq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
7374
assert(VM_Version::supports_evex(), "requires EVEX support");
7375
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7376
attributes.set_is_evex_instruction();
7377
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7378
emit_int16((unsigned char)0xEF, (0xC0 | encode));
7379
}
7380
7381
void Assembler::evpxorq(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
7382
assert(VM_Version::supports_evex(), "requires EVEX support");
7383
assert(dst != xnoreg, "sanity");
7384
InstructionMark im(this);
7385
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7386
attributes.set_is_evex_instruction();
7387
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
7388
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7389
emit_int8((unsigned char)0xEF);
7390
emit_operand(dst, src);
7391
}
7392
7393
void Assembler::evprold(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7394
assert(VM_Version::supports_evex(), "requires EVEX support");
7395
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7396
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7397
attributes.set_is_evex_instruction();
7398
int encode = vex_prefix_and_encode(xmm1->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7399
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7400
}
7401
7402
void Assembler::evprolq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7403
assert(VM_Version::supports_evex(), "requires EVEX support");
7404
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7405
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7406
attributes.set_is_evex_instruction();
7407
int encode = vex_prefix_and_encode(xmm1->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7408
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7409
}
7410
7411
void Assembler::evprord(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7412
assert(VM_Version::supports_evex(), "requires EVEX support");
7413
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7414
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7415
attributes.set_is_evex_instruction();
7416
int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7417
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7418
}
7419
7420
void Assembler::evprorq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
7421
assert(VM_Version::supports_evex(), "requires EVEX support");
7422
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7423
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7424
attributes.set_is_evex_instruction();
7425
int encode = vex_prefix_and_encode(xmm0->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
7426
emit_int24(0x72, (0xC0 | encode), shift & 0xFF);
7427
}
7428
7429
void Assembler::evprolvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7430
assert(VM_Version::supports_evex(), "requires EVEX support");
7431
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7432
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7433
attributes.set_is_evex_instruction();
7434
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7435
emit_int16(0x15, (unsigned char)(0xC0 | encode));
7436
}
7437
7438
void Assembler::evprolvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7439
assert(VM_Version::supports_evex(), "requires EVEX support");
7440
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7441
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7442
attributes.set_is_evex_instruction();
7443
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7444
emit_int16(0x15, (unsigned char)(0xC0 | encode));
7445
}
7446
7447
void Assembler::evprorvd(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7448
assert(VM_Version::supports_evex(), "requires EVEX support");
7449
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7450
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7451
attributes.set_is_evex_instruction();
7452
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7453
emit_int16(0x14, (unsigned char)(0xC0 | encode));
7454
}
7455
7456
void Assembler::evprorvq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
7457
assert(VM_Version::supports_evex(), "requires EVEX support");
7458
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7459
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7460
attributes.set_is_evex_instruction();
7461
int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7462
emit_int16(0x14, (unsigned char)(0xC0 | encode));
7463
}
7464
7465
void Assembler::vpternlogd(XMMRegister dst, int imm8, XMMRegister src2, XMMRegister src3, int vector_len) {
7466
assert(VM_Version::supports_evex(), "requires EVEX support");
7467
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
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
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src3->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7471
emit_int8(0x25);
7472
emit_int8((unsigned char)(0xC0 | encode));
7473
emit_int8(imm8);
7474
}
7475
7476
void Assembler::vpternlogd(XMMRegister dst, int imm8, XMMRegister src2, Address src3, int vector_len) {
7477
assert(VM_Version::supports_evex(), "requires EVEX support");
7478
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7479
assert(dst != xnoreg, "sanity");
7480
InstructionMark im(this);
7481
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7482
attributes.set_is_evex_instruction();
7483
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
7484
vex_prefix(src3, src2->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7485
emit_int8(0x25);
7486
emit_operand(dst, src3);
7487
emit_int8(imm8);
7488
}
7489
7490
void Assembler::vpternlogq(XMMRegister dst, int imm8, XMMRegister src2, XMMRegister src3, int vector_len) {
7491
assert(VM_Version::supports_evex(), "requires EVEX support");
7492
assert(vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl(), "requires VL support");
7493
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7494
attributes.set_is_evex_instruction();
7495
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src3->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7496
emit_int8(0x25);
7497
emit_int8((unsigned char)(0xC0 | encode));
7498
emit_int8(imm8);
7499
}
7500
7501
// vinserti forms
7502
7503
void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7504
assert(VM_Version::supports_avx2(), "");
7505
assert(imm8 <= 0x01, "imm8: %u", imm8);
7506
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7507
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7508
// last byte:
7509
// 0x00 - insert into lower 128 bits
7510
// 0x01 - insert into upper 128 bits
7511
emit_int24(0x38, (0xC0 | encode), imm8 & 0x01);
7512
}
7513
7514
void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7515
assert(VM_Version::supports_avx2(), "");
7516
assert(dst != xnoreg, "sanity");
7517
assert(imm8 <= 0x01, "imm8: %u", imm8);
7518
InstructionMark im(this);
7519
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7520
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7521
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7522
emit_int8(0x38);
7523
emit_operand(dst, src);
7524
// 0x00 - insert into lower 128 bits
7525
// 0x01 - insert into upper 128 bits
7526
emit_int8(imm8 & 0x01);
7527
}
7528
7529
void Assembler::vinserti32x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7530
assert(VM_Version::supports_evex(), "");
7531
assert(imm8 <= 0x03, "imm8: %u", imm8);
7532
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7533
attributes.set_is_evex_instruction();
7534
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7535
// imm8:
7536
// 0x00 - insert into q0 128 bits (0..127)
7537
// 0x01 - insert into q1 128 bits (128..255)
7538
// 0x02 - insert into q2 128 bits (256..383)
7539
// 0x03 - insert into q3 128 bits (384..511)
7540
emit_int24(0x38, (0xC0 | encode), imm8 & 0x03);
7541
}
7542
7543
void Assembler::vinserti32x4(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7544
assert(VM_Version::supports_avx(), "");
7545
assert(dst != xnoreg, "sanity");
7546
assert(imm8 <= 0x03, "imm8: %u", imm8);
7547
InstructionMark im(this);
7548
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7549
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7550
attributes.set_is_evex_instruction();
7551
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7552
emit_int8(0x18);
7553
emit_operand(dst, src);
7554
// 0x00 - insert into q0 128 bits (0..127)
7555
// 0x01 - insert into q1 128 bits (128..255)
7556
// 0x02 - insert into q2 128 bits (256..383)
7557
// 0x03 - insert into q3 128 bits (384..511)
7558
emit_int8(imm8 & 0x03);
7559
}
7560
7561
void Assembler::vinserti64x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7562
assert(VM_Version::supports_evex(), "");
7563
assert(imm8 <= 0x01, "imm8: %u", imm8);
7564
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7565
attributes.set_is_evex_instruction();
7566
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7567
//imm8:
7568
// 0x00 - insert into lower 256 bits
7569
// 0x01 - insert into upper 256 bits
7570
emit_int24(0x3A, (0xC0 | encode), imm8 & 0x01);
7571
}
7572
7573
7574
// vinsertf forms
7575
7576
void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7577
assert(VM_Version::supports_avx(), "");
7578
assert(imm8 <= 0x01, "imm8: %u", imm8);
7579
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7580
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7581
// imm8:
7582
// 0x00 - insert into lower 128 bits
7583
// 0x01 - insert into upper 128 bits
7584
emit_int24(0x18, (0xC0 | encode), imm8 & 0x01);
7585
}
7586
7587
void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7588
assert(VM_Version::supports_avx(), "");
7589
assert(dst != xnoreg, "sanity");
7590
assert(imm8 <= 0x01, "imm8: %u", imm8);
7591
InstructionMark im(this);
7592
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7593
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7594
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7595
emit_int8(0x18);
7596
emit_operand(dst, src);
7597
// 0x00 - insert into lower 128 bits
7598
// 0x01 - insert into upper 128 bits
7599
emit_int8(imm8 & 0x01);
7600
}
7601
7602
void Assembler::vinsertf32x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7603
assert(VM_Version::supports_avx2(), "");
7604
assert(imm8 <= 0x03, "imm8: %u", imm8);
7605
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7606
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7607
// imm8:
7608
// 0x00 - insert into q0 128 bits (0..127)
7609
// 0x01 - insert into q1 128 bits (128..255)
7610
// 0x02 - insert into q0 128 bits (256..383)
7611
// 0x03 - insert into q1 128 bits (384..512)
7612
emit_int24(0x18, (0xC0 | encode), imm8 & 0x03);
7613
}
7614
7615
void Assembler::vinsertf32x4(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7616
assert(VM_Version::supports_avx(), "");
7617
assert(dst != xnoreg, "sanity");
7618
assert(imm8 <= 0x03, "imm8: %u", imm8);
7619
InstructionMark im(this);
7620
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7621
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7622
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7623
emit_int8(0x18);
7624
emit_operand(dst, src);
7625
// 0x00 - insert into q0 128 bits (0..127)
7626
// 0x01 - insert into q1 128 bits (128..255)
7627
// 0x02 - insert into q0 128 bits (256..383)
7628
// 0x03 - insert into q1 128 bits (384..512)
7629
emit_int8(imm8 & 0x03);
7630
}
7631
7632
void Assembler::vinsertf64x4(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) {
7633
assert(VM_Version::supports_evex(), "");
7634
assert(imm8 <= 0x01, "imm8: %u", imm8);
7635
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7636
attributes.set_is_evex_instruction();
7637
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7638
// imm8:
7639
// 0x00 - insert into lower 256 bits
7640
// 0x01 - insert into upper 256 bits
7641
emit_int24(0x1A, (0xC0 | encode), imm8 & 0x01);
7642
}
7643
7644
void Assembler::vinsertf64x4(XMMRegister dst, XMMRegister nds, Address src, uint8_t imm8) {
7645
assert(VM_Version::supports_evex(), "");
7646
assert(dst != xnoreg, "sanity");
7647
assert(imm8 <= 0x01, "imm8: %u", imm8);
7648
InstructionMark im(this);
7649
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7650
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_64bit);
7651
attributes.set_is_evex_instruction();
7652
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7653
emit_int8(0x1A);
7654
emit_operand(dst, src);
7655
// 0x00 - insert into lower 256 bits
7656
// 0x01 - insert into upper 256 bits
7657
emit_int8(imm8 & 0x01);
7658
}
7659
7660
7661
// vextracti forms
7662
7663
void Assembler::vextracti128(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7664
assert(VM_Version::supports_avx2(), "");
7665
assert(imm8 <= 0x01, "imm8: %u", imm8);
7666
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7667
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7668
// imm8:
7669
// 0x00 - extract from lower 128 bits
7670
// 0x01 - extract from upper 128 bits
7671
emit_int24(0x39, (0xC0 | encode), imm8 & 0x01);
7672
}
7673
7674
void Assembler::vextracti128(Address dst, XMMRegister src, uint8_t imm8) {
7675
assert(VM_Version::supports_avx2(), "");
7676
assert(src != xnoreg, "sanity");
7677
assert(imm8 <= 0x01, "imm8: %u", imm8);
7678
InstructionMark im(this);
7679
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7680
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7681
attributes.reset_is_clear_context();
7682
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7683
emit_int8(0x39);
7684
emit_operand(src, dst);
7685
// 0x00 - extract from lower 128 bits
7686
// 0x01 - extract from upper 128 bits
7687
emit_int8(imm8 & 0x01);
7688
}
7689
7690
void Assembler::vextracti32x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7691
assert(VM_Version::supports_evex(), "");
7692
assert(imm8 <= 0x03, "imm8: %u", imm8);
7693
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7694
attributes.set_is_evex_instruction();
7695
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7696
// imm8:
7697
// 0x00 - extract from bits 127:0
7698
// 0x01 - extract from bits 255:128
7699
// 0x02 - extract from bits 383:256
7700
// 0x03 - extract from bits 511:384
7701
emit_int24(0x39, (0xC0 | encode), imm8 & 0x03);
7702
}
7703
7704
void Assembler::vextracti32x4(Address dst, XMMRegister src, uint8_t imm8) {
7705
assert(VM_Version::supports_evex(), "");
7706
assert(src != xnoreg, "sanity");
7707
assert(imm8 <= 0x03, "imm8: %u", imm8);
7708
InstructionMark im(this);
7709
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7710
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7711
attributes.reset_is_clear_context();
7712
attributes.set_is_evex_instruction();
7713
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7714
emit_int8(0x39);
7715
emit_operand(src, dst);
7716
// 0x00 - extract from bits 127:0
7717
// 0x01 - extract from bits 255:128
7718
// 0x02 - extract from bits 383:256
7719
// 0x03 - extract from bits 511:384
7720
emit_int8(imm8 & 0x03);
7721
}
7722
7723
void Assembler::vextracti64x2(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7724
assert(VM_Version::supports_avx512dq(), "");
7725
assert(imm8 <= 0x03, "imm8: %u", imm8);
7726
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7727
attributes.set_is_evex_instruction();
7728
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7729
// imm8:
7730
// 0x00 - extract from bits 127:0
7731
// 0x01 - extract from bits 255:128
7732
// 0x02 - extract from bits 383:256
7733
// 0x03 - extract from bits 511:384
7734
emit_int24(0x39, (0xC0 | encode), imm8 & 0x03);
7735
}
7736
7737
void Assembler::vextracti64x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7738
assert(VM_Version::supports_evex(), "");
7739
assert(imm8 <= 0x01, "imm8: %u", imm8);
7740
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7741
attributes.set_is_evex_instruction();
7742
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7743
// imm8:
7744
// 0x00 - extract from lower 256 bits
7745
// 0x01 - extract from upper 256 bits
7746
emit_int24(0x3B, (0xC0 | encode), imm8 & 0x01);
7747
}
7748
7749
void Assembler::vextracti64x4(Address dst, XMMRegister src, uint8_t imm8) {
7750
assert(VM_Version::supports_evex(), "");
7751
assert(src != xnoreg, "sanity");
7752
assert(imm8 <= 0x01, "imm8: %u", imm8);
7753
InstructionMark im(this);
7754
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7755
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_64bit);
7756
attributes.reset_is_clear_context();
7757
attributes.set_is_evex_instruction();
7758
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7759
emit_int8(0x38);
7760
emit_operand(src, dst);
7761
// 0x00 - extract from lower 256 bits
7762
// 0x01 - extract from upper 256 bits
7763
emit_int8(imm8 & 0x01);
7764
}
7765
// vextractf forms
7766
7767
void Assembler::vextractf128(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7768
assert(VM_Version::supports_avx(), "");
7769
assert(imm8 <= 0x01, "imm8: %u", imm8);
7770
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7771
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7772
// imm8:
7773
// 0x00 - extract from lower 128 bits
7774
// 0x01 - extract from upper 128 bits
7775
emit_int24(0x19, (0xC0 | encode), imm8 & 0x01);
7776
}
7777
7778
void Assembler::vextractf128(Address dst, XMMRegister src, uint8_t imm8) {
7779
assert(VM_Version::supports_avx(), "");
7780
assert(src != xnoreg, "sanity");
7781
assert(imm8 <= 0x01, "imm8: %u", imm8);
7782
InstructionMark im(this);
7783
InstructionAttr attributes(AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7784
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7785
attributes.reset_is_clear_context();
7786
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7787
emit_int8(0x19);
7788
emit_operand(src, dst);
7789
// 0x00 - extract from lower 128 bits
7790
// 0x01 - extract from upper 128 bits
7791
emit_int8(imm8 & 0x01);
7792
}
7793
7794
void Assembler::vextractf32x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7795
assert(VM_Version::supports_evex(), "");
7796
assert(imm8 <= 0x03, "imm8: %u", imm8);
7797
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7798
attributes.set_is_evex_instruction();
7799
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7800
// imm8:
7801
// 0x00 - extract from bits 127:0
7802
// 0x01 - extract from bits 255:128
7803
// 0x02 - extract from bits 383:256
7804
// 0x03 - extract from bits 511:384
7805
emit_int24(0x19, (0xC0 | encode), imm8 & 0x03);
7806
}
7807
7808
void Assembler::vextractf32x4(Address dst, XMMRegister src, uint8_t imm8) {
7809
assert(VM_Version::supports_evex(), "");
7810
assert(src != xnoreg, "sanity");
7811
assert(imm8 <= 0x03, "imm8: %u", imm8);
7812
InstructionMark im(this);
7813
InstructionAttr attributes(AVX_512bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7814
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7815
attributes.reset_is_clear_context();
7816
attributes.set_is_evex_instruction();
7817
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7818
emit_int8(0x19);
7819
emit_operand(src, dst);
7820
// 0x00 - extract from bits 127:0
7821
// 0x01 - extract from bits 255:128
7822
// 0x02 - extract from bits 383:256
7823
// 0x03 - extract from bits 511:384
7824
emit_int8(imm8 & 0x03);
7825
}
7826
7827
void Assembler::vextractf64x2(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7828
assert(VM_Version::supports_avx512dq(), "");
7829
assert(imm8 <= 0x03, "imm8: %u", imm8);
7830
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7831
attributes.set_is_evex_instruction();
7832
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7833
// imm8:
7834
// 0x00 - extract from bits 127:0
7835
// 0x01 - extract from bits 255:128
7836
// 0x02 - extract from bits 383:256
7837
// 0x03 - extract from bits 511:384
7838
emit_int24(0x19, (0xC0 | encode), imm8 & 0x03);
7839
}
7840
7841
void Assembler::vextractf64x4(XMMRegister dst, XMMRegister src, uint8_t imm8) {
7842
assert(VM_Version::supports_evex(), "");
7843
assert(imm8 <= 0x01, "imm8: %u", imm8);
7844
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7845
attributes.set_is_evex_instruction();
7846
int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7847
// imm8:
7848
// 0x00 - extract from lower 256 bits
7849
// 0x01 - extract from upper 256 bits
7850
emit_int24(0x1B, (0xC0 | encode), imm8 & 0x01);
7851
}
7852
7853
void Assembler::vextractf64x4(Address dst, XMMRegister src, uint8_t imm8) {
7854
assert(VM_Version::supports_evex(), "");
7855
assert(src != xnoreg, "sanity");
7856
assert(imm8 <= 0x01, "imm8: %u", imm8);
7857
InstructionMark im(this);
7858
InstructionAttr attributes(AVX_512bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7859
attributes.set_address_attributes(/* tuple_type */ EVEX_T4,/* input_size_in_bits */ EVEX_64bit);
7860
attributes.reset_is_clear_context();
7861
attributes.set_is_evex_instruction();
7862
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
7863
emit_int8(0x1B);
7864
emit_operand(src, dst);
7865
// 0x00 - extract from lower 256 bits
7866
// 0x01 - extract from upper 256 bits
7867
emit_int8(imm8 & 0x01);
7868
}
7869
7870
// duplicate 1-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
7871
void Assembler::vpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len) {
7872
assert(VM_Version::supports_avx2(), "");
7873
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7874
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7875
emit_int16(0x78, (0xC0 | encode));
7876
}
7877
7878
void Assembler::vpbroadcastb(XMMRegister dst, Address src, int vector_len) {
7879
assert(VM_Version::supports_avx2(), "");
7880
assert(dst != xnoreg, "sanity");
7881
InstructionMark im(this);
7882
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7883
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_8bit);
7884
// swap src<->dst for encoding
7885
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7886
emit_int8(0x78);
7887
emit_operand(dst, src);
7888
}
7889
7890
// duplicate 2-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
7891
void Assembler::vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len) {
7892
assert(VM_Version::supports_avx2(), "");
7893
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7894
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7895
emit_int16(0x79, (0xC0 | encode));
7896
}
7897
7898
void Assembler::vpbroadcastw(XMMRegister dst, Address src, int vector_len) {
7899
assert(VM_Version::supports_avx2(), "");
7900
assert(dst != xnoreg, "sanity");
7901
InstructionMark im(this);
7902
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
7903
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_16bit);
7904
// swap src<->dst for encoding
7905
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7906
emit_int8(0x79);
7907
emit_operand(dst, src);
7908
}
7909
7910
// xmm/mem sourced byte/word/dword/qword replicate
7911
7912
// duplicate 4-byte integer data from src into programmed locations in dest : requires AVX512VL
7913
void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) {
7914
assert(UseAVX >= 2, "");
7915
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7916
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7917
emit_int16(0x58, (0xC0 | encode));
7918
}
7919
7920
void Assembler::vpbroadcastd(XMMRegister dst, Address src, int vector_len) {
7921
assert(VM_Version::supports_avx2(), "");
7922
assert(dst != xnoreg, "sanity");
7923
InstructionMark im(this);
7924
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7925
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
7926
// swap src<->dst for encoding
7927
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7928
emit_int8(0x58);
7929
emit_operand(dst, src);
7930
}
7931
7932
// duplicate 8-byte integer data from src into programmed locations in dest : requires AVX512VL
7933
void Assembler::vpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len) {
7934
assert(VM_Version::supports_avx2(), "");
7935
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7936
attributes.set_rex_vex_w_reverted();
7937
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7938
emit_int16(0x59, (0xC0 | encode));
7939
}
7940
7941
void Assembler::vpbroadcastq(XMMRegister dst, Address src, int vector_len) {
7942
assert(VM_Version::supports_avx2(), "");
7943
assert(dst != xnoreg, "sanity");
7944
InstructionMark im(this);
7945
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7946
attributes.set_rex_vex_w_reverted();
7947
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
7948
// swap src<->dst for encoding
7949
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7950
emit_int8(0x59);
7951
emit_operand(dst, src);
7952
}
7953
7954
void Assembler::evbroadcasti32x4(XMMRegister dst, Address src, int vector_len) {
7955
assert(vector_len != Assembler::AVX_128bit, "");
7956
assert(VM_Version::supports_evex(), "");
7957
assert(dst != xnoreg, "sanity");
7958
InstructionMark im(this);
7959
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7960
attributes.set_rex_vex_w_reverted();
7961
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
7962
// swap src<->dst for encoding
7963
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7964
emit_int8(0x5A);
7965
emit_operand(dst, src);
7966
}
7967
7968
void Assembler::evbroadcasti64x2(XMMRegister dst, XMMRegister src, int vector_len) {
7969
assert(vector_len != Assembler::AVX_128bit, "");
7970
assert(VM_Version::supports_avx512dq(), "");
7971
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7972
attributes.set_rex_vex_w_reverted();
7973
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7974
emit_int16(0x5A, (0xC0 | encode));
7975
}
7976
7977
void Assembler::evbroadcasti64x2(XMMRegister dst, Address src, int vector_len) {
7978
assert(vector_len != Assembler::AVX_128bit, "");
7979
assert(VM_Version::supports_avx512dq(), "");
7980
assert(dst != xnoreg, "sanity");
7981
InstructionMark im(this);
7982
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7983
attributes.set_rex_vex_w_reverted();
7984
attributes.set_address_attributes(/* tuple_type */ EVEX_T2, /* input_size_in_bits */ EVEX_64bit);
7985
// swap src<->dst for encoding
7986
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7987
emit_int8(0x5A);
7988
emit_operand(dst, src);
7989
}
7990
7991
// scalar single/double precision replicate
7992
7993
// duplicate single precision data from src into programmed locations in dest : requires AVX512VL
7994
void Assembler::vbroadcastss(XMMRegister dst, XMMRegister src, int vector_len) {
7995
assert(VM_Version::supports_avx2(), "");
7996
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
7997
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
7998
emit_int16(0x18, (0xC0 | encode));
7999
}
8000
8001
void Assembler::vbroadcastss(XMMRegister dst, Address src, int vector_len) {
8002
assert(VM_Version::supports_avx(), "");
8003
assert(dst != xnoreg, "sanity");
8004
InstructionMark im(this);
8005
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8006
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8007
// swap src<->dst for encoding
8008
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8009
emit_int8(0x18);
8010
emit_operand(dst, src);
8011
}
8012
8013
// duplicate double precision data from src into programmed locations in dest : requires AVX512VL
8014
void Assembler::vbroadcastsd(XMMRegister dst, XMMRegister src, int vector_len) {
8015
assert(VM_Version::supports_avx2(), "");
8016
assert(vector_len == AVX_256bit || vector_len == AVX_512bit, "");
8017
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8018
attributes.set_rex_vex_w_reverted();
8019
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8020
emit_int16(0x19, (0xC0 | encode));
8021
}
8022
8023
void Assembler::vbroadcastsd(XMMRegister dst, Address src, int vector_len) {
8024
assert(VM_Version::supports_avx(), "");
8025
assert(vector_len == AVX_256bit || vector_len == AVX_512bit, "");
8026
assert(dst != xnoreg, "sanity");
8027
InstructionMark im(this);
8028
InstructionAttr attributes(vector_len, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8029
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
8030
attributes.set_rex_vex_w_reverted();
8031
// swap src<->dst for encoding
8032
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8033
emit_int8(0x19);
8034
emit_operand(dst, src);
8035
}
8036
8037
void Assembler::vbroadcastf128(XMMRegister dst, Address src, int vector_len) {
8038
assert(VM_Version::supports_avx(), "");
8039
assert(vector_len == AVX_256bit, "");
8040
assert(dst != xnoreg, "sanity");
8041
InstructionMark im(this);
8042
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8043
attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit);
8044
// swap src<->dst for encoding
8045
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8046
emit_int8(0x1A);
8047
emit_operand(dst, src);
8048
}
8049
8050
// gpr source broadcast forms
8051
8052
// duplicate 1-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
8053
void Assembler::evpbroadcastb(XMMRegister dst, Register src, int vector_len) {
8054
assert(VM_Version::supports_avx512bw(), "");
8055
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
8056
attributes.set_is_evex_instruction();
8057
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8058
emit_int16(0x7A, (0xC0 | encode));
8059
}
8060
8061
// duplicate 2-byte integer data from src into programmed locations in dest : requires AVX512BW and AVX512VL
8062
void Assembler::evpbroadcastw(XMMRegister dst, Register src, int vector_len) {
8063
assert(VM_Version::supports_avx512bw(), "");
8064
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
8065
attributes.set_is_evex_instruction();
8066
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8067
emit_int16(0x7B, (0xC0 | encode));
8068
}
8069
8070
// duplicate 4-byte integer data from src into programmed locations in dest : requires AVX512VL
8071
void Assembler::evpbroadcastd(XMMRegister dst, Register src, int vector_len) {
8072
assert(VM_Version::supports_evex(), "");
8073
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8074
attributes.set_is_evex_instruction();
8075
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8076
emit_int16(0x7C, (0xC0 | encode));
8077
}
8078
8079
// duplicate 8-byte integer data from src into programmed locations in dest : requires AVX512VL
8080
void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) {
8081
assert(VM_Version::supports_evex(), "");
8082
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8083
attributes.set_is_evex_instruction();
8084
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8085
emit_int16(0x7C, (0xC0 | encode));
8086
}
8087
8088
void Assembler::vpgatherdd(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 */ false, /* 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::vpgatherdq(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)0x90);
8111
emit_operand(dst, src);
8112
}
8113
8114
void Assembler::vgatherdpd(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 */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* 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
8127
void Assembler::vgatherdps(XMMRegister dst, Address src, XMMRegister mask, int vector_len) {
8128
assert(VM_Version::supports_avx2(), "");
8129
assert(vector_len == Assembler::AVX_128bit || vector_len == Assembler::AVX_256bit, "");
8130
assert(dst != xnoreg, "sanity");
8131
assert(src.isxmmindex(),"expected to be xmm index");
8132
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8133
InstructionMark im(this);
8134
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ true);
8135
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8136
emit_int8((unsigned char)0x92);
8137
emit_operand(dst, src);
8138
}
8139
void Assembler::evpgatherdd(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8140
assert(VM_Version::supports_evex(), "");
8141
assert(dst != xnoreg, "sanity");
8142
assert(src.isxmmindex(),"expected to be xmm index");
8143
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8144
assert(mask != k0, "instruction will #UD if mask is in k0");
8145
InstructionMark im(this);
8146
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8147
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8148
attributes.reset_is_clear_context();
8149
attributes.set_embedded_opmask_register_specifier(mask);
8150
attributes.set_is_evex_instruction();
8151
// swap src<->dst for encoding
8152
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8153
emit_int8((unsigned char)0x90);
8154
emit_operand(dst, src);
8155
}
8156
8157
void Assembler::evpgatherdq(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8158
assert(VM_Version::supports_evex(), "");
8159
assert(dst != xnoreg, "sanity");
8160
assert(src.isxmmindex(),"expected to be xmm index");
8161
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8162
assert(mask != k0, "instruction will #UD if mask is in k0");
8163
InstructionMark im(this);
8164
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8165
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8166
attributes.reset_is_clear_context();
8167
attributes.set_embedded_opmask_register_specifier(mask);
8168
attributes.set_is_evex_instruction();
8169
// swap src<->dst for encoding
8170
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8171
emit_int8((unsigned char)0x90);
8172
emit_operand(dst, src);
8173
}
8174
8175
void Assembler::evgatherdpd(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8176
assert(VM_Version::supports_evex(), "");
8177
assert(dst != xnoreg, "sanity");
8178
assert(src.isxmmindex(),"expected to be xmm index");
8179
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8180
assert(mask != k0, "instruction will #UD if mask is in k0");
8181
InstructionMark im(this);
8182
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8183
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8184
attributes.reset_is_clear_context();
8185
attributes.set_embedded_opmask_register_specifier(mask);
8186
attributes.set_is_evex_instruction();
8187
// swap src<->dst for encoding
8188
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8189
emit_int8((unsigned char)0x92);
8190
emit_operand(dst, src);
8191
}
8192
8193
void Assembler::evgatherdps(XMMRegister dst, KRegister mask, Address src, int vector_len) {
8194
assert(VM_Version::supports_evex(), "");
8195
assert(dst != xnoreg, "sanity");
8196
assert(src.isxmmindex(),"expected to be xmm index");
8197
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
8198
assert(mask != k0, "instruction will #UD if mask is in k0");
8199
InstructionMark im(this);
8200
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8201
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8202
attributes.reset_is_clear_context();
8203
attributes.set_embedded_opmask_register_specifier(mask);
8204
attributes.set_is_evex_instruction();
8205
// swap src<->dst for encoding
8206
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8207
emit_int8((unsigned char)0x92);
8208
emit_operand(dst, src);
8209
}
8210
8211
void Assembler::evpscatterdd(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8212
assert(VM_Version::supports_evex(), "");
8213
assert(mask != k0, "instruction will #UD if mask is in k0");
8214
InstructionMark im(this);
8215
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8216
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8217
attributes.reset_is_clear_context();
8218
attributes.set_embedded_opmask_register_specifier(mask);
8219
attributes.set_is_evex_instruction();
8220
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8221
emit_int8((unsigned char)0xA0);
8222
emit_operand(src, dst);
8223
}
8224
8225
void Assembler::evpscatterdq(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8226
assert(VM_Version::supports_evex(), "");
8227
assert(mask != k0, "instruction will #UD if mask is in k0");
8228
InstructionMark im(this);
8229
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8230
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8231
attributes.reset_is_clear_context();
8232
attributes.set_embedded_opmask_register_specifier(mask);
8233
attributes.set_is_evex_instruction();
8234
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8235
emit_int8((unsigned char)0xA0);
8236
emit_operand(src, dst);
8237
}
8238
8239
void Assembler::evscatterdps(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8240
assert(VM_Version::supports_evex(), "");
8241
assert(mask != k0, "instruction will #UD if mask is in k0");
8242
InstructionMark im(this);
8243
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8244
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8245
attributes.reset_is_clear_context();
8246
attributes.set_embedded_opmask_register_specifier(mask);
8247
attributes.set_is_evex_instruction();
8248
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8249
emit_int8((unsigned char)0xA2);
8250
emit_operand(src, dst);
8251
}
8252
8253
void Assembler::evscatterdpd(Address dst, KRegister mask, XMMRegister src, int vector_len) {
8254
assert(VM_Version::supports_evex(), "");
8255
assert(mask != k0, "instruction will #UD if mask is in k0");
8256
InstructionMark im(this);
8257
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
8258
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
8259
attributes.reset_is_clear_context();
8260
attributes.set_embedded_opmask_register_specifier(mask);
8261
attributes.set_is_evex_instruction();
8262
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
8263
emit_int8((unsigned char)0xA2);
8264
emit_operand(src, dst);
8265
}
8266
// Carry-Less Multiplication Quadword
8267
void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) {
8268
assert(VM_Version::supports_clmul(), "");
8269
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8270
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
8271
emit_int24(0x44, (0xC0 | encode), (unsigned char)mask);
8272
}
8273
8274
// Carry-Less Multiplication Quadword
8275
void Assembler::vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask) {
8276
assert(VM_Version::supports_avx() && VM_Version::supports_clmul(), "");
8277
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
8278
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
8279
emit_int24(0x44, (0xC0 | encode), (unsigned char)mask);
8280
}
8281
8282
void Assembler::evpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask, int vector_len) {
8283
assert(VM_Version::supports_avx512_vpclmulqdq(), "Requires vector carryless multiplication support");
8284
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
8285
attributes.set_is_evex_instruction();
8286
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
8287
emit_int24(0x44, (0xC0 | encode), (unsigned char)mask);
8288
}
8289
8290
void Assembler::vzeroupper_uncached() {
8291
if (VM_Version::supports_vzeroupper()) {
8292
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
8293
(void)vex_prefix_and_encode(0, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
8294
emit_int8(0x77);
8295
}
8296
}
8297
8298
void Assembler::fld_x(Address adr) {
8299
InstructionMark im(this);
8300
emit_int8((unsigned char)0xDB);
8301
emit_operand32(rbp, adr);
8302
}
8303
8304
void Assembler::fstp_x(Address adr) {
8305
InstructionMark im(this);
8306
emit_int8((unsigned char)0xDB);
8307
emit_operand32(rdi, adr);
8308
}
8309
8310
void Assembler::emit_operand32(Register reg, Address adr) {
8311
assert(reg->encoding() < 8, "no extended registers");
8312
assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers");
8313
emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp,
8314
adr._rspec);
8315
}
8316
8317
#ifndef _LP64
8318
// 32bit only pieces of the assembler
8319
8320
void Assembler::emms() {
8321
NOT_LP64(assert(VM_Version::supports_mmx(), ""));
8322
emit_int16(0x0F, 0x77);
8323
}
8324
8325
void Assembler::vzeroupper() {
8326
vzeroupper_uncached();
8327
}
8328
8329
void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) {
8330
// NO PREFIX AS NEVER 64BIT
8331
InstructionMark im(this);
8332
emit_int16((unsigned char)0x81, (0xF8 | src1->encoding()));
8333
emit_data(imm32, rspec, 0);
8334
}
8335
8336
void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) {
8337
// NO PREFIX AS NEVER 64BIT (not even 32bit versions of 64bit regs
8338
InstructionMark im(this);
8339
emit_int8((unsigned char)0x81);
8340
emit_operand(rdi, src1);
8341
emit_data(imm32, rspec, 0);
8342
}
8343
8344
// The 64-bit (32bit platform) cmpxchg compares the value at adr with the contents of rdx:rax,
8345
// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded
8346
// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise.
8347
void Assembler::cmpxchg8(Address adr) {
8348
InstructionMark im(this);
8349
emit_int16(0x0F, (unsigned char)0xC7);
8350
emit_operand(rcx, adr);
8351
}
8352
8353
void Assembler::decl(Register dst) {
8354
// Don't use it directly. Use MacroAssembler::decrementl() instead.
8355
emit_int8(0x48 | dst->encoding());
8356
}
8357
8358
// 64bit doesn't use the x87
8359
8360
void Assembler::emit_farith(int b1, int b2, int i) {
8361
assert(isByte(b1) && isByte(b2), "wrong opcode");
8362
assert(0 <= i && i < 8, "illegal stack offset");
8363
emit_int16(b1, b2 + i);
8364
}
8365
8366
void Assembler::fabs() {
8367
emit_int16((unsigned char)0xD9, (unsigned char)0xE1);
8368
}
8369
8370
void Assembler::fadd(int i) {
8371
emit_farith(0xD8, 0xC0, i);
8372
}
8373
8374
void Assembler::fadd_d(Address src) {
8375
InstructionMark im(this);
8376
emit_int8((unsigned char)0xDC);
8377
emit_operand32(rax, src);
8378
}
8379
8380
void Assembler::fadd_s(Address src) {
8381
InstructionMark im(this);
8382
emit_int8((unsigned char)0xD8);
8383
emit_operand32(rax, src);
8384
}
8385
8386
void Assembler::fadda(int i) {
8387
emit_farith(0xDC, 0xC0, i);
8388
}
8389
8390
void Assembler::faddp(int i) {
8391
emit_farith(0xDE, 0xC0, i);
8392
}
8393
8394
void Assembler::fchs() {
8395
emit_int16((unsigned char)0xD9, (unsigned char)0xE0);
8396
}
8397
8398
void Assembler::fcom(int i) {
8399
emit_farith(0xD8, 0xD0, i);
8400
}
8401
8402
void Assembler::fcomp(int i) {
8403
emit_farith(0xD8, 0xD8, i);
8404
}
8405
8406
void Assembler::fcomp_d(Address src) {
8407
InstructionMark im(this);
8408
emit_int8((unsigned char)0xDC);
8409
emit_operand32(rbx, src);
8410
}
8411
8412
void Assembler::fcomp_s(Address src) {
8413
InstructionMark im(this);
8414
emit_int8((unsigned char)0xD8);
8415
emit_operand32(rbx, src);
8416
}
8417
8418
void Assembler::fcompp() {
8419
emit_int16((unsigned char)0xDE, (unsigned char)0xD9);
8420
}
8421
8422
void Assembler::fcos() {
8423
emit_int16((unsigned char)0xD9, (unsigned char)0xFF);
8424
}
8425
8426
void Assembler::fdecstp() {
8427
emit_int16((unsigned char)0xD9, (unsigned char)0xF6);
8428
}
8429
8430
void Assembler::fdiv(int i) {
8431
emit_farith(0xD8, 0xF0, i);
8432
}
8433
8434
void Assembler::fdiv_d(Address src) {
8435
InstructionMark im(this);
8436
emit_int8((unsigned char)0xDC);
8437
emit_operand32(rsi, src);
8438
}
8439
8440
void Assembler::fdiv_s(Address src) {
8441
InstructionMark im(this);
8442
emit_int8((unsigned char)0xD8);
8443
emit_operand32(rsi, src);
8444
}
8445
8446
void Assembler::fdiva(int i) {
8447
emit_farith(0xDC, 0xF8, i);
8448
}
8449
8450
// Note: The Intel manual (Pentium Processor User's Manual, Vol.3, 1994)
8451
// is erroneous for some of the floating-point instructions below.
8452
8453
void Assembler::fdivp(int i) {
8454
emit_farith(0xDE, 0xF8, i); // ST(0) <- ST(0) / ST(1) and pop (Intel manual wrong)
8455
}
8456
8457
void Assembler::fdivr(int i) {
8458
emit_farith(0xD8, 0xF8, i);
8459
}
8460
8461
void Assembler::fdivr_d(Address src) {
8462
InstructionMark im(this);
8463
emit_int8((unsigned char)0xDC);
8464
emit_operand32(rdi, src);
8465
}
8466
8467
void Assembler::fdivr_s(Address src) {
8468
InstructionMark im(this);
8469
emit_int8((unsigned char)0xD8);
8470
emit_operand32(rdi, src);
8471
}
8472
8473
void Assembler::fdivra(int i) {
8474
emit_farith(0xDC, 0xF0, i);
8475
}
8476
8477
void Assembler::fdivrp(int i) {
8478
emit_farith(0xDE, 0xF0, i); // ST(0) <- ST(1) / ST(0) and pop (Intel manual wrong)
8479
}
8480
8481
void Assembler::ffree(int i) {
8482
emit_farith(0xDD, 0xC0, i);
8483
}
8484
8485
void Assembler::fild_d(Address adr) {
8486
InstructionMark im(this);
8487
emit_int8((unsigned char)0xDF);
8488
emit_operand32(rbp, adr);
8489
}
8490
8491
void Assembler::fild_s(Address adr) {
8492
InstructionMark im(this);
8493
emit_int8((unsigned char)0xDB);
8494
emit_operand32(rax, adr);
8495
}
8496
8497
void Assembler::fincstp() {
8498
emit_int16((unsigned char)0xD9, (unsigned char)0xF7);
8499
}
8500
8501
void Assembler::finit() {
8502
emit_int24((unsigned char)0x9B, (unsigned char)0xDB, (unsigned char)0xE3);
8503
}
8504
8505
void Assembler::fist_s(Address adr) {
8506
InstructionMark im(this);
8507
emit_int8((unsigned char)0xDB);
8508
emit_operand32(rdx, adr);
8509
}
8510
8511
void Assembler::fistp_d(Address adr) {
8512
InstructionMark im(this);
8513
emit_int8((unsigned char)0xDF);
8514
emit_operand32(rdi, adr);
8515
}
8516
8517
void Assembler::fistp_s(Address adr) {
8518
InstructionMark im(this);
8519
emit_int8((unsigned char)0xDB);
8520
emit_operand32(rbx, adr);
8521
}
8522
8523
void Assembler::fld1() {
8524
emit_int16((unsigned char)0xD9, (unsigned char)0xE8);
8525
}
8526
8527
void Assembler::fld_d(Address adr) {
8528
InstructionMark im(this);
8529
emit_int8((unsigned char)0xDD);
8530
emit_operand32(rax, adr);
8531
}
8532
8533
void Assembler::fld_s(Address adr) {
8534
InstructionMark im(this);
8535
emit_int8((unsigned char)0xD9);
8536
emit_operand32(rax, adr);
8537
}
8538
8539
8540
void Assembler::fld_s(int index) {
8541
emit_farith(0xD9, 0xC0, index);
8542
}
8543
8544
void Assembler::fldcw(Address src) {
8545
InstructionMark im(this);
8546
emit_int8((unsigned char)0xD9);
8547
emit_operand32(rbp, src);
8548
}
8549
8550
void Assembler::fldenv(Address src) {
8551
InstructionMark im(this);
8552
emit_int8((unsigned char)0xD9);
8553
emit_operand32(rsp, src);
8554
}
8555
8556
void Assembler::fldlg2() {
8557
emit_int16((unsigned char)0xD9, (unsigned char)0xEC);
8558
}
8559
8560
void Assembler::fldln2() {
8561
emit_int16((unsigned char)0xD9, (unsigned char)0xED);
8562
}
8563
8564
void Assembler::fldz() {
8565
emit_int16((unsigned char)0xD9, (unsigned char)0xEE);
8566
}
8567
8568
void Assembler::flog() {
8569
fldln2();
8570
fxch();
8571
fyl2x();
8572
}
8573
8574
void Assembler::flog10() {
8575
fldlg2();
8576
fxch();
8577
fyl2x();
8578
}
8579
8580
void Assembler::fmul(int i) {
8581
emit_farith(0xD8, 0xC8, i);
8582
}
8583
8584
void Assembler::fmul_d(Address src) {
8585
InstructionMark im(this);
8586
emit_int8((unsigned char)0xDC);
8587
emit_operand32(rcx, src);
8588
}
8589
8590
void Assembler::fmul_s(Address src) {
8591
InstructionMark im(this);
8592
emit_int8((unsigned char)0xD8);
8593
emit_operand32(rcx, src);
8594
}
8595
8596
void Assembler::fmula(int i) {
8597
emit_farith(0xDC, 0xC8, i);
8598
}
8599
8600
void Assembler::fmulp(int i) {
8601
emit_farith(0xDE, 0xC8, i);
8602
}
8603
8604
void Assembler::fnsave(Address dst) {
8605
InstructionMark im(this);
8606
emit_int8((unsigned char)0xDD);
8607
emit_operand32(rsi, dst);
8608
}
8609
8610
void Assembler::fnstcw(Address src) {
8611
InstructionMark im(this);
8612
emit_int16((unsigned char)0x9B, (unsigned char)0xD9);
8613
emit_operand32(rdi, src);
8614
}
8615
8616
void Assembler::fnstsw_ax() {
8617
emit_int16((unsigned char)0xDF, (unsigned char)0xE0);
8618
}
8619
8620
void Assembler::fprem() {
8621
emit_int16((unsigned char)0xD9, (unsigned char)0xF8);
8622
}
8623
8624
void Assembler::fprem1() {
8625
emit_int16((unsigned char)0xD9, (unsigned char)0xF5);
8626
}
8627
8628
void Assembler::frstor(Address src) {
8629
InstructionMark im(this);
8630
emit_int8((unsigned char)0xDD);
8631
emit_operand32(rsp, src);
8632
}
8633
8634
void Assembler::fsin() {
8635
emit_int16((unsigned char)0xD9, (unsigned char)0xFE);
8636
}
8637
8638
void Assembler::fsqrt() {
8639
emit_int16((unsigned char)0xD9, (unsigned char)0xFA);
8640
}
8641
8642
void Assembler::fst_d(Address adr) {
8643
InstructionMark im(this);
8644
emit_int8((unsigned char)0xDD);
8645
emit_operand32(rdx, adr);
8646
}
8647
8648
void Assembler::fst_s(Address adr) {
8649
InstructionMark im(this);
8650
emit_int8((unsigned char)0xD9);
8651
emit_operand32(rdx, adr);
8652
}
8653
8654
void Assembler::fstp_d(Address adr) {
8655
InstructionMark im(this);
8656
emit_int8((unsigned char)0xDD);
8657
emit_operand32(rbx, adr);
8658
}
8659
8660
void Assembler::fstp_d(int index) {
8661
emit_farith(0xDD, 0xD8, index);
8662
}
8663
8664
void Assembler::fstp_s(Address adr) {
8665
InstructionMark im(this);
8666
emit_int8((unsigned char)0xD9);
8667
emit_operand32(rbx, adr);
8668
}
8669
8670
void Assembler::fsub(int i) {
8671
emit_farith(0xD8, 0xE0, i);
8672
}
8673
8674
void Assembler::fsub_d(Address src) {
8675
InstructionMark im(this);
8676
emit_int8((unsigned char)0xDC);
8677
emit_operand32(rsp, src);
8678
}
8679
8680
void Assembler::fsub_s(Address src) {
8681
InstructionMark im(this);
8682
emit_int8((unsigned char)0xD8);
8683
emit_operand32(rsp, src);
8684
}
8685
8686
void Assembler::fsuba(int i) {
8687
emit_farith(0xDC, 0xE8, i);
8688
}
8689
8690
void Assembler::fsubp(int i) {
8691
emit_farith(0xDE, 0xE8, i); // ST(0) <- ST(0) - ST(1) and pop (Intel manual wrong)
8692
}
8693
8694
void Assembler::fsubr(int i) {
8695
emit_farith(0xD8, 0xE8, i);
8696
}
8697
8698
void Assembler::fsubr_d(Address src) {
8699
InstructionMark im(this);
8700
emit_int8((unsigned char)0xDC);
8701
emit_operand32(rbp, src);
8702
}
8703
8704
void Assembler::fsubr_s(Address src) {
8705
InstructionMark im(this);
8706
emit_int8((unsigned char)0xD8);
8707
emit_operand32(rbp, src);
8708
}
8709
8710
void Assembler::fsubra(int i) {
8711
emit_farith(0xDC, 0xE0, i);
8712
}
8713
8714
void Assembler::fsubrp(int i) {
8715
emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong)
8716
}
8717
8718
void Assembler::ftan() {
8719
emit_int32((unsigned char)0xD9, (unsigned char)0xF2, (unsigned char)0xDD, (unsigned char)0xD8);
8720
}
8721
8722
void Assembler::ftst() {
8723
emit_int16((unsigned char)0xD9, (unsigned char)0xE4);
8724
}
8725
8726
void Assembler::fucomi(int i) {
8727
// make sure the instruction is supported (introduced for P6, together with cmov)
8728
guarantee(VM_Version::supports_cmov(), "illegal instruction");
8729
emit_farith(0xDB, 0xE8, i);
8730
}
8731
8732
void Assembler::fucomip(int i) {
8733
// make sure the instruction is supported (introduced for P6, together with cmov)
8734
guarantee(VM_Version::supports_cmov(), "illegal instruction");
8735
emit_farith(0xDF, 0xE8, i);
8736
}
8737
8738
void Assembler::fwait() {
8739
emit_int8((unsigned char)0x9B);
8740
}
8741
8742
void Assembler::fxch(int i) {
8743
emit_farith(0xD9, 0xC8, i);
8744
}
8745
8746
void Assembler::fyl2x() {
8747
emit_int16((unsigned char)0xD9, (unsigned char)0xF1);
8748
}
8749
8750
void Assembler::frndint() {
8751
emit_int16((unsigned char)0xD9, (unsigned char)0xFC);
8752
}
8753
8754
void Assembler::f2xm1() {
8755
emit_int16((unsigned char)0xD9, (unsigned char)0xF0);
8756
}
8757
8758
void Assembler::fldl2e() {
8759
emit_int16((unsigned char)0xD9, (unsigned char)0xEA);
8760
}
8761
#endif // !_LP64
8762
8763
// SSE SIMD prefix byte values corresponding to VexSimdPrefix encoding.
8764
static int simd_pre[4] = { 0, 0x66, 0xF3, 0xF2 };
8765
// SSE opcode second byte values (first is 0x0F) corresponding to VexOpcode encoding.
8766
static int simd_opc[4] = { 0, 0, 0x38, 0x3A };
8767
8768
// Generate SSE legacy REX prefix and SIMD opcode based on VEX encoding.
8769
void Assembler::rex_prefix(Address adr, XMMRegister xreg, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
8770
if (pre > 0) {
8771
emit_int8(simd_pre[pre]);
8772
}
8773
if (rex_w) {
8774
prefixq(adr, xreg);
8775
} else {
8776
prefix(adr, xreg);
8777
}
8778
if (opc > 0) {
8779
emit_int8(0x0F);
8780
int opc2 = simd_opc[opc];
8781
if (opc2 > 0) {
8782
emit_int8(opc2);
8783
}
8784
}
8785
}
8786
8787
int Assembler::rex_prefix_and_encode(int dst_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
8788
if (pre > 0) {
8789
emit_int8(simd_pre[pre]);
8790
}
8791
int encode = (rex_w) ? prefixq_and_encode(dst_enc, src_enc) : prefix_and_encode(dst_enc, src_enc);
8792
if (opc > 0) {
8793
emit_int8(0x0F);
8794
int opc2 = simd_opc[opc];
8795
if (opc2 > 0) {
8796
emit_int8(opc2);
8797
}
8798
}
8799
return encode;
8800
}
8801
8802
8803
void Assembler::vex_prefix(bool vex_r, bool vex_b, bool vex_x, int nds_enc, VexSimdPrefix pre, VexOpcode opc) {
8804
int vector_len = _attributes->get_vector_len();
8805
bool vex_w = _attributes->is_rex_vex_w();
8806
if (vex_b || vex_x || vex_w || (opc == VEX_OPCODE_0F_38) || (opc == VEX_OPCODE_0F_3A)) {
8807
int byte1 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0);
8808
byte1 = (~byte1) & 0xE0;
8809
byte1 |= opc;
8810
8811
int byte2 = ((~nds_enc) & 0xf) << 3;
8812
byte2 |= (vex_w ? VEX_W : 0) | ((vector_len > 0) ? 4 : 0) | pre;
8813
8814
emit_int24((unsigned char)VEX_3bytes, byte1, byte2);
8815
} else {
8816
int byte1 = vex_r ? VEX_R : 0;
8817
byte1 = (~byte1) & 0x80;
8818
byte1 |= ((~nds_enc) & 0xf) << 3;
8819
byte1 |= ((vector_len > 0 ) ? 4 : 0) | pre;
8820
emit_int16((unsigned char)VEX_2bytes, byte1);
8821
}
8822
}
8823
8824
// This is a 4 byte encoding
8825
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){
8826
// EVEX 0x62 prefix
8827
// byte1 = EVEX_4bytes;
8828
8829
bool vex_w = _attributes->is_rex_vex_w();
8830
int evex_encoding = (vex_w ? VEX_W : 0);
8831
// EVEX.b is not currently used for broadcast of single element or data rounding modes
8832
_attributes->set_evex_encoding(evex_encoding);
8833
8834
// P0: byte 2, initialized to RXBR`00mm
8835
// instead of not'd
8836
int byte2 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0) | (evex_r ? EVEX_Rb : 0);
8837
byte2 = (~byte2) & 0xF0;
8838
// confine opc opcode extensions in mm bits to lower two bits
8839
// of form {0F, 0F_38, 0F_3A}
8840
byte2 |= opc;
8841
8842
// P1: byte 3 as Wvvvv1pp
8843
int byte3 = ((~nds_enc) & 0xf) << 3;
8844
// p[10] is always 1
8845
byte3 |= EVEX_F;
8846
byte3 |= (vex_w & 1) << 7;
8847
// confine pre opcode extensions in pp bits to lower two bits
8848
// of form {66, F3, F2}
8849
byte3 |= pre;
8850
8851
// P2: byte 4 as zL'Lbv'aaa
8852
// kregs are implemented in the low 3 bits as aaa
8853
int byte4 = (_attributes->is_no_reg_mask()) ?
8854
0 :
8855
_attributes->get_embedded_opmask_register_specifier();
8856
// EVEX.v` for extending EVEX.vvvv or VIDX
8857
byte4 |= (evex_v ? 0: EVEX_V);
8858
// third EXEC.b for broadcast actions
8859
byte4 |= (_attributes->is_extended_context() ? EVEX_Rb : 0);
8860
// fourth EVEX.L'L for vector length : 0 is 128, 1 is 256, 2 is 512, currently we do not support 1024
8861
byte4 |= ((_attributes->get_vector_len())& 0x3) << 5;
8862
// last is EVEX.z for zero/merge actions
8863
if (_attributes->is_no_reg_mask() == false &&
8864
_attributes->get_embedded_opmask_register_specifier() != 0) {
8865
byte4 |= (_attributes->is_clear_context() ? EVEX_Z : 0);
8866
}
8867
8868
emit_int32(EVEX_4bytes, byte2, byte3, byte4);
8869
}
8870
8871
void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) {
8872
bool vex_r = (xreg_enc & 8) == 8;
8873
bool vex_b = adr.base_needs_rex();
8874
bool vex_x;
8875
if (adr.isxmmindex()) {
8876
vex_x = adr.xmmindex_needs_rex();
8877
} else {
8878
vex_x = adr.index_needs_rex();
8879
}
8880
set_attributes(attributes);
8881
attributes->set_current_assembler(this);
8882
8883
// For EVEX instruction (which is not marked as pure EVEX instruction) check and see if this instruction
8884
// is allowed in legacy mode and has resources which will fit in it.
8885
// Pure EVEX instructions will have is_evex_instruction set in their definition.
8886
if (!attributes->is_legacy_mode()) {
8887
if (UseAVX > 2 && !attributes->is_evex_instruction() && !is_managed()) {
8888
if ((attributes->get_vector_len() != AVX_512bit) && (nds_enc < 16) && (xreg_enc < 16)) {
8889
attributes->set_is_legacy_mode();
8890
}
8891
}
8892
}
8893
8894
if (UseAVX > 2) {
8895
assert(((!attributes->uses_vl()) ||
8896
(attributes->get_vector_len() == AVX_512bit) ||
8897
(!_legacy_mode_vl) ||
8898
(attributes->is_legacy_mode())),"XMM register should be 0-15");
8899
assert(((nds_enc < 16 && xreg_enc < 16) || (!attributes->is_legacy_mode())),"XMM register should be 0-15");
8900
}
8901
8902
clear_managed();
8903
if (UseAVX > 2 && !attributes->is_legacy_mode())
8904
{
8905
bool evex_r = (xreg_enc >= 16);
8906
bool evex_v;
8907
// EVEX.V' is set to true when VSIB is used as we may need to use higher order XMM registers (16-31)
8908
if (adr.isxmmindex()) {
8909
evex_v = ((adr._xmmindex->encoding() > 15) ? true : false);
8910
} else {
8911
evex_v = (nds_enc >= 16);
8912
}
8913
attributes->set_is_evex_instruction();
8914
evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc);
8915
} else {
8916
if (UseAVX > 2 && attributes->is_rex_vex_w_reverted()) {
8917
attributes->set_rex_vex_w(false);
8918
}
8919
vex_prefix(vex_r, vex_b, vex_x, nds_enc, pre, opc);
8920
}
8921
}
8922
8923
int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) {
8924
bool vex_r = (dst_enc & 8) == 8;
8925
bool vex_b = (src_enc & 8) == 8;
8926
bool vex_x = false;
8927
set_attributes(attributes);
8928
attributes->set_current_assembler(this);
8929
8930
// For EVEX instruction (which is not marked as pure EVEX instruction) check and see if this instruction
8931
// is allowed in legacy mode and has resources which will fit in it.
8932
// Pure EVEX instructions will have is_evex_instruction set in their definition.
8933
if (!attributes->is_legacy_mode()) {
8934
if (UseAVX > 2 && !attributes->is_evex_instruction() && !is_managed()) {
8935
if ((!attributes->uses_vl() || (attributes->get_vector_len() != AVX_512bit)) &&
8936
(dst_enc < 16) && (nds_enc < 16) && (src_enc < 16)) {
8937
attributes->set_is_legacy_mode();
8938
}
8939
}
8940
}
8941
8942
if (UseAVX > 2) {
8943
// All the scalar fp instructions (with uses_vl as false) can have legacy_mode as false
8944
// Instruction with uses_vl true are vector instructions
8945
// All the vector instructions with AVX_512bit length can have legacy_mode as false
8946
// All the vector instructions with < AVX_512bit length can have legacy_mode as false if AVX512vl() is supported
8947
// Rest all should have legacy_mode set as true
8948
assert(((!attributes->uses_vl()) ||
8949
(attributes->get_vector_len() == AVX_512bit) ||
8950
(!_legacy_mode_vl) ||
8951
(attributes->is_legacy_mode())),"XMM register should be 0-15");
8952
// Instruction with legacy_mode true should have dst, nds and src < 15
8953
assert(((dst_enc < 16 && nds_enc < 16 && src_enc < 16) || (!attributes->is_legacy_mode())),"XMM register should be 0-15");
8954
}
8955
8956
clear_managed();
8957
if (UseAVX > 2 && !attributes->is_legacy_mode())
8958
{
8959
bool evex_r = (dst_enc >= 16);
8960
bool evex_v = (nds_enc >= 16);
8961
// can use vex_x as bank extender on rm encoding
8962
vex_x = (src_enc >= 16);
8963
attributes->set_is_evex_instruction();
8964
evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc);
8965
} else {
8966
if (UseAVX > 2 && attributes->is_rex_vex_w_reverted()) {
8967
attributes->set_rex_vex_w(false);
8968
}
8969
vex_prefix(vex_r, vex_b, vex_x, nds_enc, pre, opc);
8970
}
8971
8972
// return modrm byte components for operands
8973
return (((dst_enc & 7) << 3) | (src_enc & 7));
8974
}
8975
8976
8977
void Assembler::simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr, VexSimdPrefix pre,
8978
VexOpcode opc, InstructionAttr *attributes) {
8979
if (UseAVX > 0) {
8980
int xreg_enc = xreg->encoding();
8981
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
8982
vex_prefix(adr, nds_enc, xreg_enc, pre, opc, attributes);
8983
} else {
8984
assert((nds == xreg) || (nds == xnoreg), "wrong sse encoding");
8985
rex_prefix(adr, xreg, pre, opc, attributes->is_rex_vex_w());
8986
}
8987
}
8988
8989
int Assembler::simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src, VexSimdPrefix pre,
8990
VexOpcode opc, InstructionAttr *attributes) {
8991
int dst_enc = dst->encoding();
8992
int src_enc = src->encoding();
8993
if (UseAVX > 0) {
8994
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
8995
return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, attributes);
8996
} else {
8997
assert((nds == dst) || (nds == src) || (nds == xnoreg), "wrong sse encoding");
8998
return rex_prefix_and_encode(dst_enc, src_enc, pre, opc, attributes->is_rex_vex_w());
8999
}
9000
}
9001
9002
void Assembler::vmaxss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
9003
assert(VM_Version::supports_avx(), "");
9004
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
9005
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
9006
emit_int16(0x5F, (0xC0 | encode));
9007
}
9008
9009
void Assembler::vmaxsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
9010
assert(VM_Version::supports_avx(), "");
9011
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
9012
attributes.set_rex_vex_w_reverted();
9013
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
9014
emit_int16(0x5F, (0xC0 | encode));
9015
}
9016
9017
void Assembler::vminss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
9018
assert(VM_Version::supports_avx(), "");
9019
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
9020
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
9021
emit_int16(0x5D, (0xC0 | encode));
9022
}
9023
9024
void Assembler::vminsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
9025
assert(VM_Version::supports_avx(), "");
9026
InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
9027
attributes.set_rex_vex_w_reverted();
9028
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
9029
emit_int16(0x5D, (0xC0 | encode));
9030
}
9031
9032
void Assembler::vcmppd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len) {
9033
assert(VM_Version::supports_avx(), "");
9034
assert(vector_len <= AVX_256bit, "");
9035
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9036
int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9037
emit_int24((unsigned char)0xC2, (0xC0 | encode), (0xF & cop));
9038
}
9039
9040
void Assembler::blendvpb(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
9041
assert(VM_Version::supports_avx(), "");
9042
assert(vector_len <= AVX_256bit, "");
9043
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9044
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9045
int src2_enc = src2->encoding();
9046
emit_int24(0x4C, (0xC0 | encode), (0xF0 & src2_enc << 4));
9047
}
9048
9049
void Assembler::vblendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
9050
assert(UseAVX > 0 && (vector_len == AVX_128bit || vector_len == AVX_256bit), "");
9051
assert(vector_len <= AVX_256bit, "");
9052
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9053
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9054
int src2_enc = src2->encoding();
9055
emit_int24(0x4B, (0xC0 | encode), (0xF0 & src2_enc << 4));
9056
}
9057
9058
void Assembler::vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
9059
assert(VM_Version::supports_avx2(), "");
9060
assert(vector_len <= AVX_256bit, "");
9061
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9062
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9063
emit_int24(0x02, (0xC0 | encode), (unsigned char)imm8);
9064
}
9065
9066
void Assembler::vcmpps(XMMRegister dst, XMMRegister nds, XMMRegister src, int comparison, int vector_len) {
9067
assert(VM_Version::supports_avx(), "");
9068
assert(vector_len <= AVX_256bit, "");
9069
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9070
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
9071
emit_int24((unsigned char)0xC2, (0xC0 | encode), (unsigned char)comparison);
9072
}
9073
9074
void Assembler::evcmpps(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9075
ComparisonPredicateFP comparison, int vector_len) {
9076
assert(VM_Version::supports_evex(), "");
9077
// Encoding: EVEX.NDS.XXX.0F.W0 C2 /r ib
9078
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9079
attributes.set_is_evex_instruction();
9080
attributes.set_embedded_opmask_register_specifier(mask);
9081
attributes.reset_is_clear_context();
9082
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
9083
emit_int24((unsigned char)0xC2, (0xC0 | encode), comparison);
9084
}
9085
9086
void Assembler::evcmppd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9087
ComparisonPredicateFP comparison, int vector_len) {
9088
assert(VM_Version::supports_evex(), "");
9089
// Encoding: EVEX.NDS.XXX.66.0F.W1 C2 /r ib
9090
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9091
attributes.set_is_evex_instruction();
9092
attributes.set_embedded_opmask_register_specifier(mask);
9093
attributes.reset_is_clear_context();
9094
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9095
emit_int24((unsigned char)0xC2, (0xC0 | encode), comparison);
9096
}
9097
9098
void Assembler::blendvps(XMMRegister dst, XMMRegister src) {
9099
assert(VM_Version::supports_sse4_1(), "");
9100
assert(UseAVX <= 0, "sse encoding is inconsistent with avx encoding");
9101
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9102
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9103
emit_int16(0x14, (0xC0 | encode));
9104
}
9105
9106
void Assembler::blendvpd(XMMRegister dst, XMMRegister src) {
9107
assert(VM_Version::supports_sse4_1(), "");
9108
assert(UseAVX <= 0, "sse encoding is inconsistent with avx encoding");
9109
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9110
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9111
emit_int16(0x15, (0xC0 | encode));
9112
}
9113
9114
void Assembler::pblendvb(XMMRegister dst, XMMRegister src) {
9115
assert(VM_Version::supports_sse4_1(), "");
9116
assert(UseAVX <= 0, "sse encoding is inconsistent with avx encoding");
9117
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9118
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9119
emit_int16(0x10, (0xC0 | encode));
9120
}
9121
9122
void Assembler::vblendvps(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) {
9123
assert(UseAVX > 0 && (vector_len == AVX_128bit || vector_len == AVX_256bit), "");
9124
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9125
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9126
int src2_enc = src2->encoding();
9127
emit_int24(0x4A, (0xC0 | encode), (0xF0 & src2_enc << 4));
9128
}
9129
9130
void Assembler::vblendps(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
9131
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9132
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9133
emit_int24(0x0C, (0xC0 | encode), imm8);
9134
}
9135
9136
void Assembler::vpcmpgtb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9137
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9138
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9139
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9140
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9141
emit_int16(0x64, (0xC0 | encode));
9142
}
9143
9144
void Assembler::vpcmpgtw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9145
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9146
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9147
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9148
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9149
emit_int16(0x65, (0xC0 | encode));
9150
}
9151
9152
void Assembler::vpcmpgtd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9153
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9154
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9155
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9156
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
9157
emit_int16(0x66, (0xC0 | encode));
9158
}
9159
9160
void Assembler::vpcmpgtq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
9161
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
9162
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
9163
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9164
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9165
emit_int16(0x37, (0xC0 | encode));
9166
}
9167
9168
void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9169
int comparison, bool is_signed, int vector_len) {
9170
assert(VM_Version::supports_evex(), "");
9171
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9172
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 1F /r ib
9173
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9174
attributes.set_is_evex_instruction();
9175
attributes.set_embedded_opmask_register_specifier(mask);
9176
attributes.reset_is_clear_context();
9177
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9178
int opcode = is_signed ? 0x1F : 0x1E;
9179
emit_int24(opcode, (0xC0 | encode), comparison);
9180
}
9181
9182
void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9183
int comparison, bool is_signed, int vector_len) {
9184
assert(VM_Version::supports_evex(), "");
9185
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9186
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 1F /r ib
9187
InstructionMark im(this);
9188
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9189
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
9190
attributes.set_is_evex_instruction();
9191
attributes.set_embedded_opmask_register_specifier(mask);
9192
attributes.reset_is_clear_context();
9193
int dst_enc = kdst->encoding();
9194
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9195
int opcode = is_signed ? 0x1F : 0x1E;
9196
emit_int8((unsigned char)opcode);
9197
emit_operand(as_Register(dst_enc), src);
9198
emit_int8((unsigned char)comparison);
9199
}
9200
9201
void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9202
int comparison, bool is_signed, int vector_len) {
9203
assert(VM_Version::supports_evex(), "");
9204
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9205
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 1F /r ib
9206
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9207
attributes.set_is_evex_instruction();
9208
attributes.set_embedded_opmask_register_specifier(mask);
9209
attributes.reset_is_clear_context();
9210
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9211
int opcode = is_signed ? 0x1F : 0x1E;
9212
emit_int24(opcode, (0xC0 | encode), comparison);
9213
}
9214
9215
void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9216
int comparison, bool is_signed, int vector_len) {
9217
assert(VM_Version::supports_evex(), "");
9218
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9219
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 1F /r ib
9220
InstructionMark im(this);
9221
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9222
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_NObit);
9223
attributes.set_is_evex_instruction();
9224
attributes.set_embedded_opmask_register_specifier(mask);
9225
attributes.reset_is_clear_context();
9226
int dst_enc = kdst->encoding();
9227
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9228
int opcode = is_signed ? 0x1F : 0x1E;
9229
emit_int8((unsigned char)opcode);
9230
emit_operand(as_Register(dst_enc), src);
9231
emit_int8((unsigned char)comparison);
9232
}
9233
9234
void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9235
int comparison, bool is_signed, int vector_len) {
9236
assert(VM_Version::supports_evex(), "");
9237
assert(VM_Version::supports_avx512bw(), "");
9238
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9239
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 3F /r ib
9240
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9241
attributes.set_is_evex_instruction();
9242
attributes.set_embedded_opmask_register_specifier(mask);
9243
attributes.reset_is_clear_context();
9244
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9245
int opcode = is_signed ? 0x3F : 0x3E;
9246
emit_int24(opcode, (0xC0 | encode), comparison);
9247
}
9248
9249
void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9250
int comparison, bool is_signed, int vector_len) {
9251
assert(VM_Version::supports_evex(), "");
9252
assert(VM_Version::supports_avx512bw(), "");
9253
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9254
// Encoding: EVEX.NDS.XXX.66.0F3A.W0 3F /r ib
9255
InstructionMark im(this);
9256
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9257
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
9258
attributes.set_is_evex_instruction();
9259
attributes.set_embedded_opmask_register_specifier(mask);
9260
attributes.reset_is_clear_context();
9261
int dst_enc = kdst->encoding();
9262
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9263
int opcode = is_signed ? 0x3F : 0x3E;
9264
emit_int8((unsigned char)opcode);
9265
emit_operand(as_Register(dst_enc), src);
9266
emit_int8((unsigned char)comparison);
9267
}
9268
9269
void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src,
9270
int comparison, bool is_signed, int vector_len) {
9271
assert(VM_Version::supports_evex(), "");
9272
assert(VM_Version::supports_avx512bw(), "");
9273
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9274
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 3F /r ib
9275
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9276
attributes.set_is_evex_instruction();
9277
attributes.set_embedded_opmask_register_specifier(mask);
9278
attributes.reset_is_clear_context();
9279
int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9280
int opcode = is_signed ? 0x3F : 0x3E;
9281
emit_int24(opcode, (0xC0 | encode), comparison);
9282
}
9283
9284
void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address src,
9285
int comparison, bool is_signed, int vector_len) {
9286
assert(VM_Version::supports_evex(), "");
9287
assert(VM_Version::supports_avx512bw(), "");
9288
assert(comparison >= Assembler::eq && comparison <= Assembler::_true, "");
9289
// Encoding: EVEX.NDS.XXX.66.0F3A.W1 3F /r ib
9290
InstructionMark im(this);
9291
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9292
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
9293
attributes.set_is_evex_instruction();
9294
attributes.set_embedded_opmask_register_specifier(mask);
9295
attributes.reset_is_clear_context();
9296
int dst_enc = kdst->encoding();
9297
vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9298
int opcode = is_signed ? 0x3F : 0x3E;
9299
emit_int8((unsigned char)opcode);
9300
emit_operand(as_Register(dst_enc), src);
9301
emit_int8((unsigned char)comparison);
9302
}
9303
9304
void Assembler::vpblendvb(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister mask, int vector_len) {
9305
assert(VM_Version::supports_avx(), "");
9306
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9307
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
9308
int mask_enc = mask->encoding();
9309
emit_int24(0x4C, (0xC0 | encode), 0xF0 & mask_enc << 4);
9310
}
9311
9312
void Assembler::evblendmpd(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.W1 65 /r
9315
InstructionAttr attributes(vector_len, /* vex_w */ true, /* 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::evblendmps(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9326
assert(VM_Version::supports_evex(), "");
9327
// Encoding: EVEX.NDS.XXX.66.0F38.W0 65 /r
9328
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9329
attributes.set_is_evex_instruction();
9330
attributes.set_embedded_opmask_register_specifier(mask);
9331
if (merge) {
9332
attributes.reset_is_clear_context();
9333
}
9334
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9335
emit_int16(0x65, (0xC0 | encode));
9336
}
9337
9338
void Assembler::evpblendmb (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9339
assert(VM_Version::supports_evex(), "");
9340
assert(VM_Version::supports_avx512bw(), "");
9341
// Encoding: EVEX.NDS.512.66.0F38.W0 66 /r
9342
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ false, /* uses_vl */ true);
9343
attributes.set_is_evex_instruction();
9344
attributes.set_embedded_opmask_register_specifier(mask);
9345
if (merge) {
9346
attributes.reset_is_clear_context();
9347
}
9348
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9349
emit_int16(0x66, (0xC0 | encode));
9350
}
9351
9352
void Assembler::evpblendmw (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9353
assert(VM_Version::supports_evex(), "");
9354
assert(VM_Version::supports_avx512bw(), "");
9355
// Encoding: EVEX.NDS.512.66.0F38.W1 66 /r
9356
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* 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(0x66, (0xC0 | encode));
9364
}
9365
9366
void Assembler::evpblendmd (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.W0 64 /r
9369
InstructionAttr attributes(vector_len, /* vex_w */ false, /* 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::evpblendmq (XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) {
9380
assert(VM_Version::supports_evex(), "");
9381
//Encoding: EVEX.NDS.512.66.0F38.W1 64 /r
9382
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true);
9383
attributes.set_is_evex_instruction();
9384
attributes.set_embedded_opmask_register_specifier(mask);
9385
if (merge) {
9386
attributes.reset_is_clear_context();
9387
}
9388
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9389
emit_int16(0x64, (0xC0 | encode));
9390
}
9391
9392
void Assembler::bzhiq(Register dst, Register src1, Register src2) {
9393
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
9394
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9395
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9396
emit_int16((unsigned char)0xF5, (0xC0 | encode));
9397
}
9398
9399
void Assembler::shlxl(Register dst, Register src1, Register src2) {
9400
assert(VM_Version::supports_bmi2(), "");
9401
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9402
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9403
emit_int16((unsigned char)0xF7, (0xC0 | encode));
9404
}
9405
9406
void Assembler::shlxq(Register dst, Register src1, Register src2) {
9407
assert(VM_Version::supports_bmi2(), "");
9408
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9409
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
9410
emit_int16((unsigned char)0xF7, (0xC0 | encode));
9411
}
9412
9413
void Assembler::shrxq(Register dst, Register src1, Register src2) {
9414
assert(VM_Version::supports_bmi2(), "");
9415
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
9416
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes);
9417
emit_int16((unsigned char)0xF7, (0xC0 | encode));
9418
}
9419
9420
void Assembler::evpmovb2m(KRegister dst, XMMRegister src, int vector_len) {
9421
assert(VM_Version::supports_avx512vlbw(), "");
9422
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
9423
attributes.set_is_evex_instruction();
9424
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes);
9425
emit_int16(0x29, (0xC0 | encode));
9426
}
9427
9428
#ifndef _LP64
9429
9430
void Assembler::incl(Register dst) {
9431
// Don't use it directly. Use MacroAssembler::incrementl() instead.
9432
emit_int8(0x40 | dst->encoding());
9433
}
9434
9435
void Assembler::lea(Register dst, Address src) {
9436
leal(dst, src);
9437
}
9438
9439
void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) {
9440
InstructionMark im(this);
9441
emit_int8((unsigned char)0xC7);
9442
emit_operand(rax, dst);
9443
emit_data((int)imm32, rspec, 0);
9444
}
9445
9446
void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) {
9447
InstructionMark im(this);
9448
int encode = prefix_and_encode(dst->encoding());
9449
emit_int8((0xB8 | encode));
9450
emit_data((int)imm32, rspec, 0);
9451
}
9452
9453
void Assembler::popa() { // 32bit
9454
emit_int8(0x61);
9455
}
9456
9457
void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) {
9458
InstructionMark im(this);
9459
emit_int8(0x68);
9460
emit_data(imm32, rspec, 0);
9461
}
9462
9463
void Assembler::pusha() { // 32bit
9464
emit_int8(0x60);
9465
}
9466
9467
void Assembler::set_byte_if_not_zero(Register dst) {
9468
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | dst->encoding()));
9469
}
9470
9471
#else // LP64
9472
9473
void Assembler::set_byte_if_not_zero(Register dst) {
9474
int enc = prefix_and_encode(dst->encoding(), true);
9475
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | enc));
9476
}
9477
9478
// 64bit only pieces of the assembler
9479
// This should only be used by 64bit instructions that can use rip-relative
9480
// it cannot be used by instructions that want an immediate value.
9481
9482
bool Assembler::reachable(AddressLiteral adr) {
9483
int64_t disp;
9484
relocInfo::relocType relocType = adr.reloc();
9485
9486
// None will force a 64bit literal to the code stream. Likely a placeholder
9487
// for something that will be patched later and we need to certain it will
9488
// always be reachable.
9489
if (relocType == relocInfo::none) {
9490
return false;
9491
}
9492
if (relocType == relocInfo::internal_word_type) {
9493
// This should be rip relative and easily reachable.
9494
return true;
9495
}
9496
if (relocType == relocInfo::virtual_call_type ||
9497
relocType == relocInfo::opt_virtual_call_type ||
9498
relocType == relocInfo::static_call_type ||
9499
relocType == relocInfo::static_stub_type ) {
9500
// This should be rip relative within the code cache and easily
9501
// reachable until we get huge code caches. (At which point
9502
// ic code is going to have issues).
9503
return true;
9504
}
9505
if (relocType != relocInfo::external_word_type &&
9506
relocType != relocInfo::poll_return_type && // these are really external_word but need special
9507
relocType != relocInfo::poll_type && // relocs to identify them
9508
relocType != relocInfo::runtime_call_type ) {
9509
return false;
9510
}
9511
9512
// Stress the correction code
9513
if (ForceUnreachable) {
9514
// Must be runtimecall reloc, see if it is in the codecache
9515
// Flipping stuff in the codecache to be unreachable causes issues
9516
// with things like inline caches where the additional instructions
9517
// are not handled.
9518
if (CodeCache::find_blob(adr._target) == NULL) {
9519
return false;
9520
}
9521
}
9522
// For external_word_type/runtime_call_type if it is reachable from where we
9523
// are now (possibly a temp buffer) and where we might end up
9524
// anywhere in the codeCache then we are always reachable.
9525
// This would have to change if we ever save/restore shared code
9526
// to be more pessimistic.
9527
disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
9528
if (!is_simm32(disp)) return false;
9529
disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
9530
if (!is_simm32(disp)) return false;
9531
9532
disp = (int64_t)adr._target - ((int64_t)pc() + sizeof(int));
9533
9534
// Because rip relative is a disp + address_of_next_instruction and we
9535
// don't know the value of address_of_next_instruction we apply a fudge factor
9536
// to make sure we will be ok no matter the size of the instruction we get placed into.
9537
// We don't have to fudge the checks above here because they are already worst case.
9538
9539
// 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal
9540
// + 4 because better safe than sorry.
9541
const int fudge = 12 + 4;
9542
if (disp < 0) {
9543
disp -= fudge;
9544
} else {
9545
disp += fudge;
9546
}
9547
return is_simm32(disp);
9548
}
9549
9550
void Assembler::emit_data64(jlong data,
9551
relocInfo::relocType rtype,
9552
int format) {
9553
if (rtype == relocInfo::none) {
9554
emit_int64(data);
9555
} else {
9556
emit_data64(data, Relocation::spec_simple(rtype), format);
9557
}
9558
}
9559
9560
void Assembler::emit_data64(jlong data,
9561
RelocationHolder const& rspec,
9562
int format) {
9563
assert(imm_operand == 0, "default format must be immediate in this file");
9564
assert(imm_operand == format, "must be immediate");
9565
assert(inst_mark() != NULL, "must be inside InstructionMark");
9566
// Do not use AbstractAssembler::relocate, which is not intended for
9567
// embedded words. Instead, relocate to the enclosing instruction.
9568
code_section()->relocate(inst_mark(), rspec, format);
9569
#ifdef ASSERT
9570
check_relocation(rspec, format);
9571
#endif
9572
emit_int64(data);
9573
}
9574
9575
void Assembler::prefix(Register reg) {
9576
if (reg->encoding() >= 8) {
9577
prefix(REX_B);
9578
}
9579
}
9580
9581
void Assembler::prefix(Register dst, Register src, Prefix p) {
9582
if (src->encoding() >= 8) {
9583
p = (Prefix)(p | REX_B);
9584
}
9585
if (dst->encoding() >= 8) {
9586
p = (Prefix)(p | REX_R);
9587
}
9588
if (p != Prefix_EMPTY) {
9589
// do not generate an empty prefix
9590
prefix(p);
9591
}
9592
}
9593
9594
void Assembler::prefix(Register dst, Address adr, Prefix p) {
9595
if (adr.base_needs_rex()) {
9596
if (adr.index_needs_rex()) {
9597
assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
9598
} else {
9599
prefix(REX_B);
9600
}
9601
} else {
9602
if (adr.index_needs_rex()) {
9603
assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
9604
}
9605
}
9606
if (dst->encoding() >= 8) {
9607
p = (Prefix)(p | REX_R);
9608
}
9609
if (p != Prefix_EMPTY) {
9610
// do not generate an empty prefix
9611
prefix(p);
9612
}
9613
}
9614
9615
void Assembler::prefix(Address adr) {
9616
if (adr.base_needs_rex()) {
9617
if (adr.index_needs_rex()) {
9618
prefix(REX_XB);
9619
} else {
9620
prefix(REX_B);
9621
}
9622
} else {
9623
if (adr.index_needs_rex()) {
9624
prefix(REX_X);
9625
}
9626
}
9627
}
9628
9629
void Assembler::prefix(Address adr, Register reg, bool byteinst) {
9630
if (reg->encoding() < 8) {
9631
if (adr.base_needs_rex()) {
9632
if (adr.index_needs_rex()) {
9633
prefix(REX_XB);
9634
} else {
9635
prefix(REX_B);
9636
}
9637
} else {
9638
if (adr.index_needs_rex()) {
9639
prefix(REX_X);
9640
} else if (byteinst && reg->encoding() >= 4) {
9641
prefix(REX);
9642
}
9643
}
9644
} else {
9645
if (adr.base_needs_rex()) {
9646
if (adr.index_needs_rex()) {
9647
prefix(REX_RXB);
9648
} else {
9649
prefix(REX_RB);
9650
}
9651
} else {
9652
if (adr.index_needs_rex()) {
9653
prefix(REX_RX);
9654
} else {
9655
prefix(REX_R);
9656
}
9657
}
9658
}
9659
}
9660
9661
void Assembler::prefix(Address adr, XMMRegister reg) {
9662
if (reg->encoding() < 8) {
9663
if (adr.base_needs_rex()) {
9664
if (adr.index_needs_rex()) {
9665
prefix(REX_XB);
9666
} else {
9667
prefix(REX_B);
9668
}
9669
} else {
9670
if (adr.index_needs_rex()) {
9671
prefix(REX_X);
9672
}
9673
}
9674
} else {
9675
if (adr.base_needs_rex()) {
9676
if (adr.index_needs_rex()) {
9677
prefix(REX_RXB);
9678
} else {
9679
prefix(REX_RB);
9680
}
9681
} else {
9682
if (adr.index_needs_rex()) {
9683
prefix(REX_RX);
9684
} else {
9685
prefix(REX_R);
9686
}
9687
}
9688
}
9689
}
9690
9691
int Assembler::prefix_and_encode(int reg_enc, bool byteinst) {
9692
if (reg_enc >= 8) {
9693
prefix(REX_B);
9694
reg_enc -= 8;
9695
} else if (byteinst && reg_enc >= 4) {
9696
prefix(REX);
9697
}
9698
return reg_enc;
9699
}
9700
9701
int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) {
9702
if (dst_enc < 8) {
9703
if (src_enc >= 8) {
9704
prefix(REX_B);
9705
src_enc -= 8;
9706
} else if ((src_is_byte && src_enc >= 4) || (dst_is_byte && dst_enc >= 4)) {
9707
prefix(REX);
9708
}
9709
} else {
9710
if (src_enc < 8) {
9711
prefix(REX_R);
9712
} else {
9713
prefix(REX_RB);
9714
src_enc -= 8;
9715
}
9716
dst_enc -= 8;
9717
}
9718
return dst_enc << 3 | src_enc;
9719
}
9720
9721
int8_t Assembler::get_prefixq(Address adr) {
9722
int8_t prfx = get_prefixq(adr, rax);
9723
assert(REX_W <= prfx && prfx <= REX_WXB, "must be");
9724
return prfx;
9725
}
9726
9727
int8_t Assembler::get_prefixq(Address adr, Register src) {
9728
int8_t prfx = (int8_t)(REX_W +
9729
((int)adr.base_needs_rex()) +
9730
((int)adr.index_needs_rex() << 1) +
9731
((int)(src->encoding() >= 8) << 2));
9732
#ifdef ASSERT
9733
if (src->encoding() < 8) {
9734
if (adr.base_needs_rex()) {
9735
if (adr.index_needs_rex()) {
9736
assert(prfx == REX_WXB, "must be");
9737
} else {
9738
assert(prfx == REX_WB, "must be");
9739
}
9740
} else {
9741
if (adr.index_needs_rex()) {
9742
assert(prfx == REX_WX, "must be");
9743
} else {
9744
assert(prfx == REX_W, "must be");
9745
}
9746
}
9747
} else {
9748
if (adr.base_needs_rex()) {
9749
if (adr.index_needs_rex()) {
9750
assert(prfx == REX_WRXB, "must be");
9751
} else {
9752
assert(prfx == REX_WRB, "must be");
9753
}
9754
} else {
9755
if (adr.index_needs_rex()) {
9756
assert(prfx == REX_WRX, "must be");
9757
} else {
9758
assert(prfx == REX_WR, "must be");
9759
}
9760
}
9761
}
9762
#endif
9763
return prfx;
9764
}
9765
9766
void Assembler::prefixq(Address adr) {
9767
emit_int8(get_prefixq(adr));
9768
}
9769
9770
void Assembler::prefixq(Address adr, Register src) {
9771
emit_int8(get_prefixq(adr, src));
9772
}
9773
9774
void Assembler::prefixq(Address adr, XMMRegister src) {
9775
if (src->encoding() < 8) {
9776
if (adr.base_needs_rex()) {
9777
if (adr.index_needs_rex()) {
9778
prefix(REX_WXB);
9779
} else {
9780
prefix(REX_WB);
9781
}
9782
} else {
9783
if (adr.index_needs_rex()) {
9784
prefix(REX_WX);
9785
} else {
9786
prefix(REX_W);
9787
}
9788
}
9789
} else {
9790
if (adr.base_needs_rex()) {
9791
if (adr.index_needs_rex()) {
9792
prefix(REX_WRXB);
9793
} else {
9794
prefix(REX_WRB);
9795
}
9796
} else {
9797
if (adr.index_needs_rex()) {
9798
prefix(REX_WRX);
9799
} else {
9800
prefix(REX_WR);
9801
}
9802
}
9803
}
9804
}
9805
9806
int Assembler::prefixq_and_encode(int reg_enc) {
9807
if (reg_enc < 8) {
9808
prefix(REX_W);
9809
} else {
9810
prefix(REX_WB);
9811
reg_enc -= 8;
9812
}
9813
return reg_enc;
9814
}
9815
9816
int Assembler::prefixq_and_encode(int dst_enc, int src_enc) {
9817
if (dst_enc < 8) {
9818
if (src_enc < 8) {
9819
prefix(REX_W);
9820
} else {
9821
prefix(REX_WB);
9822
src_enc -= 8;
9823
}
9824
} else {
9825
if (src_enc < 8) {
9826
prefix(REX_WR);
9827
} else {
9828
prefix(REX_WRB);
9829
src_enc -= 8;
9830
}
9831
dst_enc -= 8;
9832
}
9833
return dst_enc << 3 | src_enc;
9834
}
9835
9836
void Assembler::adcq(Register dst, int32_t imm32) {
9837
(void) prefixq_and_encode(dst->encoding());
9838
emit_arith(0x81, 0xD0, dst, imm32);
9839
}
9840
9841
void Assembler::adcq(Register dst, Address src) {
9842
InstructionMark im(this);
9843
emit_int16(get_prefixq(src, dst), 0x13);
9844
emit_operand(dst, src);
9845
}
9846
9847
void Assembler::adcq(Register dst, Register src) {
9848
(void) prefixq_and_encode(dst->encoding(), src->encoding());
9849
emit_arith(0x13, 0xC0, dst, src);
9850
}
9851
9852
void Assembler::addq(Address dst, int32_t imm32) {
9853
InstructionMark im(this);
9854
prefixq(dst);
9855
emit_arith_operand(0x81, rax, dst, imm32);
9856
}
9857
9858
void Assembler::addq(Address dst, Register src) {
9859
InstructionMark im(this);
9860
emit_int16(get_prefixq(dst, src), 0x01);
9861
emit_operand(src, dst);
9862
}
9863
9864
void Assembler::addq(Register dst, int32_t imm32) {
9865
(void) prefixq_and_encode(dst->encoding());
9866
emit_arith(0x81, 0xC0, dst, imm32);
9867
}
9868
9869
void Assembler::addq(Register dst, Address src) {
9870
InstructionMark im(this);
9871
emit_int16(get_prefixq(src, dst), 0x03);
9872
emit_operand(dst, src);
9873
}
9874
9875
void Assembler::addq(Register dst, Register src) {
9876
(void) prefixq_and_encode(dst->encoding(), src->encoding());
9877
emit_arith(0x03, 0xC0, dst, src);
9878
}
9879
9880
void Assembler::adcxq(Register dst, Register src) {
9881
//assert(VM_Version::supports_adx(), "adx instructions not supported");
9882
emit_int8(0x66);
9883
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9884
emit_int32(0x0F,
9885
0x38,
9886
(unsigned char)0xF6,
9887
(0xC0 | encode));
9888
}
9889
9890
void Assembler::adoxq(Register dst, Register src) {
9891
//assert(VM_Version::supports_adx(), "adx instructions not supported");
9892
emit_int8((unsigned char)0xF3);
9893
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9894
emit_int32(0x0F,
9895
0x38,
9896
(unsigned char)0xF6,
9897
(0xC0 | encode));
9898
}
9899
9900
void Assembler::andq(Address dst, int32_t imm32) {
9901
InstructionMark im(this);
9902
prefixq(dst);
9903
emit_arith_operand(0x81, as_Register(4), dst, imm32);
9904
}
9905
9906
void Assembler::andq(Register dst, int32_t imm32) {
9907
(void) prefixq_and_encode(dst->encoding());
9908
emit_arith(0x81, 0xE0, dst, imm32);
9909
}
9910
9911
void Assembler::andq(Register dst, Address src) {
9912
InstructionMark im(this);
9913
emit_int16(get_prefixq(src, dst), 0x23);
9914
emit_operand(dst, src);
9915
}
9916
9917
void Assembler::andq(Register dst, Register src) {
9918
(void) prefixq_and_encode(dst->encoding(), src->encoding());
9919
emit_arith(0x23, 0xC0, dst, src);
9920
}
9921
9922
void Assembler::andq(Address dst, Register src) {
9923
InstructionMark im(this);
9924
emit_int16(get_prefixq(dst, src), 0x21);
9925
emit_operand(src, dst);
9926
}
9927
9928
void Assembler::andnq(Register dst, Register src1, Register src2) {
9929
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9930
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9931
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9932
emit_int16((unsigned char)0xF2, (0xC0 | encode));
9933
}
9934
9935
void Assembler::andnq(Register dst, Register src1, Address src2) {
9936
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9937
InstructionMark im(this);
9938
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9939
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9940
emit_int8((unsigned char)0xF2);
9941
emit_operand(dst, src2);
9942
}
9943
9944
void Assembler::bsfq(Register dst, Register src) {
9945
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9946
emit_int24(0x0F, (unsigned char)0xBC, (0xC0 | encode));
9947
}
9948
9949
void Assembler::bsrq(Register dst, Register src) {
9950
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
9951
emit_int24(0x0F, (unsigned char)0xBD, (0xC0 | encode));
9952
}
9953
9954
void Assembler::bswapq(Register reg) {
9955
int encode = prefixq_and_encode(reg->encoding());
9956
emit_int16(0x0F, (0xC8 | encode));
9957
}
9958
9959
void Assembler::blsiq(Register dst, Register src) {
9960
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9961
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9962
int encode = vex_prefix_and_encode(rbx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9963
emit_int16((unsigned char)0xF3, (0xC0 | encode));
9964
}
9965
9966
void Assembler::blsiq(Register dst, Address src) {
9967
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9968
InstructionMark im(this);
9969
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9970
vex_prefix(src, dst->encoding(), rbx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9971
emit_int8((unsigned char)0xF3);
9972
emit_operand(rbx, src);
9973
}
9974
9975
void Assembler::blsmskq(Register dst, Register src) {
9976
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9977
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9978
int encode = vex_prefix_and_encode(rdx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9979
emit_int16((unsigned char)0xF3, (0xC0 | encode));
9980
}
9981
9982
void Assembler::blsmskq(Register dst, Address src) {
9983
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9984
InstructionMark im(this);
9985
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9986
vex_prefix(src, dst->encoding(), rdx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9987
emit_int8((unsigned char)0xF3);
9988
emit_operand(rdx, src);
9989
}
9990
9991
void Assembler::blsrq(Register dst, Register src) {
9992
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
9993
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
9994
int encode = vex_prefix_and_encode(rcx->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
9995
emit_int16((unsigned char)0xF3, (0xC0 | encode));
9996
}
9997
9998
void Assembler::blsrq(Register dst, Address src) {
9999
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
10000
InstructionMark im(this);
10001
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10002
vex_prefix(src, dst->encoding(), rcx->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
10003
emit_int8((unsigned char)0xF3);
10004
emit_operand(rcx, src);
10005
}
10006
10007
void Assembler::cdqq() {
10008
emit_int16(REX_W, (unsigned char)0x99);
10009
}
10010
10011
void Assembler::clflush(Address adr) {
10012
assert(VM_Version::supports_clflush(), "should do");
10013
prefix(adr);
10014
emit_int16(0x0F, (unsigned char)0xAE);
10015
emit_operand(rdi, adr);
10016
}
10017
10018
void Assembler::clflushopt(Address adr) {
10019
assert(VM_Version::supports_clflushopt(), "should do!");
10020
// adr should be base reg only with no index or offset
10021
assert(adr.index() == noreg, "index should be noreg");
10022
assert(adr.scale() == Address::no_scale, "scale should be no_scale");
10023
assert(adr.disp() == 0, "displacement should be 0");
10024
// instruction prefix is 0x66
10025
emit_int8(0x66);
10026
prefix(adr);
10027
// opcode family is 0x0F 0xAE
10028
emit_int16(0x0F, (unsigned char)0xAE);
10029
// extended opcode byte is 7 == rdi
10030
emit_operand(rdi, adr);
10031
}
10032
10033
void Assembler::clwb(Address adr) {
10034
assert(VM_Version::supports_clwb(), "should do!");
10035
// adr should be base reg only with no index or offset
10036
assert(adr.index() == noreg, "index should be noreg");
10037
assert(adr.scale() == Address::no_scale, "scale should be no_scale");
10038
assert(adr.disp() == 0, "displacement should be 0");
10039
// instruction prefix is 0x66
10040
emit_int8(0x66);
10041
prefix(adr);
10042
// opcode family is 0x0f 0xAE
10043
emit_int16(0x0F, (unsigned char)0xAE);
10044
// extended opcode byte is 6 == rsi
10045
emit_operand(rsi, adr);
10046
}
10047
10048
void Assembler::cmovq(Condition cc, Register dst, Register src) {
10049
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10050
emit_int24(0x0F, (0x40 | cc), (0xC0 | encode));
10051
}
10052
10053
void Assembler::cmovq(Condition cc, Register dst, Address src) {
10054
InstructionMark im(this);
10055
emit_int24(get_prefixq(src, dst), 0x0F, (0x40 | cc));
10056
emit_operand(dst, src);
10057
}
10058
10059
void Assembler::cmpq(Address dst, int32_t imm32) {
10060
InstructionMark im(this);
10061
emit_int16(get_prefixq(dst), (unsigned char)0x81);
10062
emit_operand(rdi, dst, 4);
10063
emit_int32(imm32);
10064
}
10065
10066
void Assembler::cmpq(Register dst, int32_t imm32) {
10067
(void) prefixq_and_encode(dst->encoding());
10068
emit_arith(0x81, 0xF8, dst, imm32);
10069
}
10070
10071
void Assembler::cmpq(Address dst, Register src) {
10072
InstructionMark im(this);
10073
emit_int16(get_prefixq(dst, src), 0x39);
10074
emit_operand(src, dst);
10075
}
10076
10077
void Assembler::cmpq(Register dst, Register src) {
10078
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10079
emit_arith(0x3B, 0xC0, dst, src);
10080
}
10081
10082
void Assembler::cmpq(Register dst, Address src) {
10083
InstructionMark im(this);
10084
emit_int16(get_prefixq(src, dst), 0x3B);
10085
emit_operand(dst, src);
10086
}
10087
10088
void Assembler::cmpxchgq(Register reg, Address adr) {
10089
InstructionMark im(this);
10090
emit_int24(get_prefixq(adr, reg), 0x0F, (unsigned char)0xB1);
10091
emit_operand(reg, adr);
10092
}
10093
10094
void Assembler::cvtsi2sdq(XMMRegister dst, Register src) {
10095
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10096
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10097
int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
10098
emit_int16(0x2A, (0xC0 | encode));
10099
}
10100
10101
void Assembler::cvtsi2sdq(XMMRegister dst, Address src) {
10102
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10103
InstructionMark im(this);
10104
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10105
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
10106
simd_prefix(dst, dst, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
10107
emit_int8(0x2A);
10108
emit_operand(dst, src);
10109
}
10110
10111
void Assembler::cvtsi2ssq(XMMRegister dst, Address src) {
10112
NOT_LP64(assert(VM_Version::supports_sse(), ""));
10113
InstructionMark im(this);
10114
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10115
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
10116
simd_prefix(dst, dst, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
10117
emit_int8(0x2A);
10118
emit_operand(dst, src);
10119
}
10120
10121
void Assembler::cvttsd2siq(Register dst, Address src) {
10122
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10123
// F2 REX.W 0F 2C /r
10124
// CVTTSD2SI r64, xmm1/m64
10125
InstructionMark im(this);
10126
emit_int32((unsigned char)0xF2, REX_W, 0x0F, 0x2C);
10127
emit_operand(dst, src);
10128
}
10129
10130
void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
10131
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10132
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10133
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
10134
emit_int16(0x2C, (0xC0 | encode));
10135
}
10136
10137
void Assembler::cvttss2siq(Register dst, XMMRegister src) {
10138
NOT_LP64(assert(VM_Version::supports_sse(), ""));
10139
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10140
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F3, VEX_OPCODE_0F, &attributes);
10141
emit_int16(0x2C, (0xC0 | encode));
10142
}
10143
10144
void Assembler::decl(Register dst) {
10145
// Don't use it directly. Use MacroAssembler::decrementl() instead.
10146
// Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
10147
int encode = prefix_and_encode(dst->encoding());
10148
emit_int16((unsigned char)0xFF, (0xC8 | encode));
10149
}
10150
10151
void Assembler::decq(Register dst) {
10152
// Don't use it directly. Use MacroAssembler::decrementq() instead.
10153
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
10154
int encode = prefixq_and_encode(dst->encoding());
10155
emit_int16((unsigned char)0xFF, 0xC8 | encode);
10156
}
10157
10158
void Assembler::decq(Address dst) {
10159
// Don't use it directly. Use MacroAssembler::decrementq() instead.
10160
InstructionMark im(this);
10161
emit_int16(get_prefixq(dst), (unsigned char)0xFF);
10162
emit_operand(rcx, dst);
10163
}
10164
10165
void Assembler::fxrstor(Address src) {
10166
emit_int24(get_prefixq(src), 0x0F, (unsigned char)0xAE);
10167
emit_operand(as_Register(1), src);
10168
}
10169
10170
void Assembler::xrstor(Address src) {
10171
emit_int24(get_prefixq(src), 0x0F, (unsigned char)0xAE);
10172
emit_operand(as_Register(5), src);
10173
}
10174
10175
void Assembler::fxsave(Address dst) {
10176
emit_int24(get_prefixq(dst), 0x0F, (unsigned char)0xAE);
10177
emit_operand(as_Register(0), dst);
10178
}
10179
10180
void Assembler::xsave(Address dst) {
10181
emit_int24(get_prefixq(dst), 0x0F, (unsigned char)0xAE);
10182
emit_operand(as_Register(4), dst);
10183
}
10184
10185
void Assembler::idivq(Register src) {
10186
int encode = prefixq_and_encode(src->encoding());
10187
emit_int16((unsigned char)0xF7, (0xF8 | encode));
10188
}
10189
10190
void Assembler::imulq(Register dst, Register src) {
10191
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10192
emit_int24(0x0F, (unsigned char)0xAF, (0xC0 | encode));
10193
}
10194
10195
void Assembler::imulq(Register src) {
10196
int encode = prefixq_and_encode(src->encoding());
10197
emit_int16((unsigned char)0xF7, (0xE8 | encode));
10198
}
10199
10200
void Assembler::imulq(Register dst, Address src, int32_t value) {
10201
InstructionMark im(this);
10202
prefixq(src, dst);
10203
if (is8bit(value)) {
10204
emit_int8((unsigned char)0x6B);
10205
emit_operand(dst, src);
10206
emit_int8(value);
10207
} else {
10208
emit_int8((unsigned char)0x69);
10209
emit_operand(dst, src);
10210
emit_int32(value);
10211
}
10212
}
10213
10214
void Assembler::imulq(Register dst, Register src, int value) {
10215
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10216
if (is8bit(value)) {
10217
emit_int24(0x6B, (0xC0 | encode), (value & 0xFF));
10218
} else {
10219
emit_int16(0x69, (0xC0 | encode));
10220
emit_int32(value);
10221
}
10222
}
10223
10224
void Assembler::imulq(Register dst, Address src) {
10225
InstructionMark im(this);
10226
emit_int24(get_prefixq(src, dst), 0x0F, (unsigned char)0xAF);
10227
emit_operand(dst, src);
10228
}
10229
10230
void Assembler::incl(Register dst) {
10231
// Don't use it directly. Use MacroAssembler::incrementl() instead.
10232
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
10233
int encode = prefix_and_encode(dst->encoding());
10234
emit_int16((unsigned char)0xFF, (0xC0 | encode));
10235
}
10236
10237
void Assembler::incq(Register dst) {
10238
// Don't use it directly. Use MacroAssembler::incrementq() instead.
10239
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
10240
int encode = prefixq_and_encode(dst->encoding());
10241
emit_int16((unsigned char)0xFF, (0xC0 | encode));
10242
}
10243
10244
void Assembler::incq(Address dst) {
10245
// Don't use it directly. Use MacroAssembler::incrementq() instead.
10246
InstructionMark im(this);
10247
emit_int16(get_prefixq(dst), (unsigned char)0xFF);
10248
emit_operand(rax, dst);
10249
}
10250
10251
void Assembler::lea(Register dst, Address src) {
10252
leaq(dst, src);
10253
}
10254
10255
void Assembler::leaq(Register dst, Address src) {
10256
InstructionMark im(this);
10257
emit_int16(get_prefixq(src, dst), (unsigned char)0x8D);
10258
emit_operand(dst, src);
10259
}
10260
10261
void Assembler::mov64(Register dst, int64_t imm64) {
10262
InstructionMark im(this);
10263
int encode = prefixq_and_encode(dst->encoding());
10264
emit_int8(0xB8 | encode);
10265
emit_int64(imm64);
10266
}
10267
10268
void Assembler::mov64(Register dst, int64_t imm64, relocInfo::relocType rtype, int format) {
10269
InstructionMark im(this);
10270
int encode = prefixq_and_encode(dst->encoding());
10271
emit_int8(0xB8 | encode);
10272
emit_data64(imm64, rtype, format);
10273
}
10274
10275
void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) {
10276
InstructionMark im(this);
10277
int encode = prefixq_and_encode(dst->encoding());
10278
emit_int8(0xB8 | encode);
10279
emit_data64(imm64, rspec);
10280
}
10281
10282
void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) {
10283
InstructionMark im(this);
10284
int encode = prefix_and_encode(dst->encoding());
10285
emit_int8(0xB8 | encode);
10286
emit_data((int)imm32, rspec, narrow_oop_operand);
10287
}
10288
10289
void Assembler::mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec) {
10290
InstructionMark im(this);
10291
prefix(dst);
10292
emit_int8((unsigned char)0xC7);
10293
emit_operand(rax, dst, 4);
10294
emit_data((int)imm32, rspec, narrow_oop_operand);
10295
}
10296
10297
void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) {
10298
InstructionMark im(this);
10299
int encode = prefix_and_encode(src1->encoding());
10300
emit_int16((unsigned char)0x81, (0xF8 | encode));
10301
emit_data((int)imm32, rspec, narrow_oop_operand);
10302
}
10303
10304
void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) {
10305
InstructionMark im(this);
10306
prefix(src1);
10307
emit_int8((unsigned char)0x81);
10308
emit_operand(rax, src1, 4);
10309
emit_data((int)imm32, rspec, narrow_oop_operand);
10310
}
10311
10312
void Assembler::lzcntq(Register dst, Register src) {
10313
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
10314
emit_int8((unsigned char)0xF3);
10315
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10316
emit_int24(0x0F, (unsigned char)0xBD, (0xC0 | encode));
10317
}
10318
10319
void Assembler::movdq(XMMRegister dst, Register src) {
10320
// table D-1 says MMX/SSE2
10321
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10322
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10323
int encode = simd_prefix_and_encode(dst, xnoreg, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
10324
emit_int16(0x6E, (0xC0 | encode));
10325
}
10326
10327
void Assembler::movdq(Register dst, XMMRegister src) {
10328
// table D-1 says MMX/SSE2
10329
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
10330
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
10331
// swap src/dst to get correct prefix
10332
int encode = simd_prefix_and_encode(src, xnoreg, as_XMMRegister(dst->encoding()), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
10333
emit_int16(0x7E,
10334
(0xC0 | encode));
10335
}
10336
10337
void Assembler::movq(Register dst, Register src) {
10338
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10339
emit_int16((unsigned char)0x8B,
10340
(0xC0 | encode));
10341
}
10342
10343
void Assembler::movq(Register dst, Address src) {
10344
InstructionMark im(this);
10345
emit_int16(get_prefixq(src, dst), (unsigned char)0x8B);
10346
emit_operand(dst, src);
10347
}
10348
10349
void Assembler::movq(Address dst, Register src) {
10350
InstructionMark im(this);
10351
emit_int16(get_prefixq(dst, src), (unsigned char)0x89);
10352
emit_operand(src, dst);
10353
}
10354
10355
void Assembler::movq(Address dst, int32_t imm32) {
10356
InstructionMark im(this);
10357
emit_int16(get_prefixq(dst), (unsigned char)0xC7);
10358
emit_operand(as_Register(0), dst);
10359
emit_int32(imm32);
10360
}
10361
10362
void Assembler::movq(Register dst, int32_t imm32) {
10363
int encode = prefixq_and_encode(dst->encoding());
10364
emit_int16((unsigned char)0xC7, (0xC0 | encode));
10365
emit_int32(imm32);
10366
}
10367
10368
void Assembler::movsbq(Register dst, Address src) {
10369
InstructionMark im(this);
10370
emit_int24(get_prefixq(src, dst),
10371
0x0F,
10372
(unsigned char)0xBE);
10373
emit_operand(dst, src);
10374
}
10375
10376
void Assembler::movsbq(Register dst, Register src) {
10377
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10378
emit_int24(0x0F, (unsigned char)0xBE, (0xC0 | encode));
10379
}
10380
10381
void Assembler::movslq(Register dst, int32_t imm32) {
10382
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
10383
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
10384
// as a result we shouldn't use until tested at runtime...
10385
ShouldNotReachHere();
10386
InstructionMark im(this);
10387
int encode = prefixq_and_encode(dst->encoding());
10388
emit_int8(0xC7 | encode);
10389
emit_int32(imm32);
10390
}
10391
10392
void Assembler::movslq(Address dst, int32_t imm32) {
10393
assert(is_simm32(imm32), "lost bits");
10394
InstructionMark im(this);
10395
emit_int16(get_prefixq(dst), (unsigned char)0xC7);
10396
emit_operand(rax, dst, 4);
10397
emit_int32(imm32);
10398
}
10399
10400
void Assembler::movslq(Register dst, Address src) {
10401
InstructionMark im(this);
10402
emit_int16(get_prefixq(src, dst), 0x63);
10403
emit_operand(dst, src);
10404
}
10405
10406
void Assembler::movslq(Register dst, Register src) {
10407
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10408
emit_int16(0x63, (0xC0 | encode));
10409
}
10410
10411
void Assembler::movswq(Register dst, Address src) {
10412
InstructionMark im(this);
10413
emit_int24(get_prefixq(src, dst),
10414
0x0F,
10415
(unsigned char)0xBF);
10416
emit_operand(dst, src);
10417
}
10418
10419
void Assembler::movswq(Register dst, Register src) {
10420
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10421
emit_int24(0x0F, (unsigned char)0xBF, (0xC0 | encode));
10422
}
10423
10424
void Assembler::movzbq(Register dst, Address src) {
10425
InstructionMark im(this);
10426
emit_int24(get_prefixq(src, dst),
10427
0x0F,
10428
(unsigned char)0xB6);
10429
emit_operand(dst, src);
10430
}
10431
10432
void Assembler::movzbq(Register dst, Register src) {
10433
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10434
emit_int24(0x0F, (unsigned char)0xB6, (0xC0 | encode));
10435
}
10436
10437
void Assembler::movzwq(Register dst, Address src) {
10438
InstructionMark im(this);
10439
emit_int24(get_prefixq(src, dst),
10440
0x0F,
10441
(unsigned char)0xB7);
10442
emit_operand(dst, src);
10443
}
10444
10445
void Assembler::movzwq(Register dst, Register src) {
10446
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10447
emit_int24(0x0F, (unsigned char)0xB7, (0xC0 | encode));
10448
}
10449
10450
void Assembler::mulq(Address src) {
10451
InstructionMark im(this);
10452
emit_int16(get_prefixq(src), (unsigned char)0xF7);
10453
emit_operand(rsp, src);
10454
}
10455
10456
void Assembler::mulq(Register src) {
10457
int encode = prefixq_and_encode(src->encoding());
10458
emit_int16((unsigned char)0xF7, (0xE0 | encode));
10459
}
10460
10461
void Assembler::mulxq(Register dst1, Register dst2, Register src) {
10462
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
10463
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10464
int encode = vex_prefix_and_encode(dst1->encoding(), dst2->encoding(), src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes);
10465
emit_int16((unsigned char)0xF6, (0xC0 | encode));
10466
}
10467
10468
void Assembler::negq(Register dst) {
10469
int encode = prefixq_and_encode(dst->encoding());
10470
emit_int16((unsigned char)0xF7, (0xD8 | encode));
10471
}
10472
10473
void Assembler::negq(Address dst) {
10474
InstructionMark im(this);
10475
emit_int16(get_prefixq(dst), (unsigned char)0xF7);
10476
emit_operand(as_Register(3), dst);
10477
}
10478
10479
void Assembler::notq(Register dst) {
10480
int encode = prefixq_and_encode(dst->encoding());
10481
emit_int16((unsigned char)0xF7, (0xD0 | encode));
10482
}
10483
10484
void Assembler::btsq(Address dst, int imm8) {
10485
assert(isByte(imm8), "not a byte");
10486
InstructionMark im(this);
10487
emit_int24(get_prefixq(dst),
10488
0x0F,
10489
(unsigned char)0xBA);
10490
emit_operand(rbp /* 5 */, dst, 1);
10491
emit_int8(imm8);
10492
}
10493
10494
void Assembler::btrq(Address dst, int imm8) {
10495
assert(isByte(imm8), "not a byte");
10496
InstructionMark im(this);
10497
emit_int24(get_prefixq(dst),
10498
0x0F,
10499
(unsigned char)0xBA);
10500
emit_operand(rsi /* 6 */, dst, 1);
10501
emit_int8(imm8);
10502
}
10503
10504
void Assembler::orq(Address dst, int32_t imm32) {
10505
InstructionMark im(this);
10506
prefixq(dst);
10507
emit_arith_operand(0x81, as_Register(1), dst, imm32);
10508
}
10509
10510
void Assembler::orq(Address dst, Register src) {
10511
InstructionMark im(this);
10512
emit_int16(get_prefixq(dst, src), (unsigned char)0x09);
10513
emit_operand(src, dst);
10514
}
10515
10516
void Assembler::orq(Register dst, int32_t imm32) {
10517
(void) prefixq_and_encode(dst->encoding());
10518
emit_arith(0x81, 0xC8, dst, imm32);
10519
}
10520
10521
void Assembler::orq(Register dst, Address src) {
10522
InstructionMark im(this);
10523
emit_int16(get_prefixq(src, dst), 0x0B);
10524
emit_operand(dst, src);
10525
}
10526
10527
void Assembler::orq(Register dst, Register src) {
10528
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10529
emit_arith(0x0B, 0xC0, dst, src);
10530
}
10531
10532
void Assembler::popcntq(Register dst, Address src) {
10533
assert(VM_Version::supports_popcnt(), "must support");
10534
InstructionMark im(this);
10535
emit_int32((unsigned char)0xF3,
10536
get_prefixq(src, dst),
10537
0x0F,
10538
(unsigned char)0xB8);
10539
emit_operand(dst, src);
10540
}
10541
10542
void Assembler::popcntq(Register dst, Register src) {
10543
assert(VM_Version::supports_popcnt(), "must support");
10544
emit_int8((unsigned char)0xF3);
10545
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10546
emit_int24(0x0F, (unsigned char)0xB8, (0xC0 | encode));
10547
}
10548
10549
void Assembler::popq(Address dst) {
10550
InstructionMark im(this);
10551
emit_int16(get_prefixq(dst), (unsigned char)0x8F);
10552
emit_operand(rax, dst);
10553
}
10554
10555
void Assembler::popq(Register dst) {
10556
emit_int8((unsigned char)0x58 | dst->encoding());
10557
}
10558
10559
// Precomputable: popa, pusha, vzeroupper
10560
10561
// The result of these routines are invariant from one invocation to another
10562
// invocation for the duration of a run. Caching the result on bootstrap
10563
// and copying it out on subsequent invocations can thus be beneficial
10564
static bool precomputed = false;
10565
10566
static u_char* popa_code = NULL;
10567
static int popa_len = 0;
10568
10569
static u_char* pusha_code = NULL;
10570
static int pusha_len = 0;
10571
10572
static u_char* vzup_code = NULL;
10573
static int vzup_len = 0;
10574
10575
void Assembler::precompute_instructions() {
10576
assert(!Universe::is_fully_initialized(), "must still be single threaded");
10577
guarantee(!precomputed, "only once");
10578
precomputed = true;
10579
ResourceMark rm;
10580
10581
// Make a temporary buffer big enough for the routines we're capturing
10582
int size = 256;
10583
char* tmp_code = NEW_RESOURCE_ARRAY(char, size);
10584
CodeBuffer buffer((address)tmp_code, size);
10585
MacroAssembler masm(&buffer);
10586
10587
address begin_popa = masm.code_section()->end();
10588
masm.popa_uncached();
10589
address end_popa = masm.code_section()->end();
10590
masm.pusha_uncached();
10591
address end_pusha = masm.code_section()->end();
10592
masm.vzeroupper_uncached();
10593
address end_vzup = masm.code_section()->end();
10594
10595
// Save the instructions to permanent buffers.
10596
popa_len = (int)(end_popa - begin_popa);
10597
popa_code = NEW_C_HEAP_ARRAY(u_char, popa_len, mtInternal);
10598
memcpy(popa_code, begin_popa, popa_len);
10599
10600
pusha_len = (int)(end_pusha - end_popa);
10601
pusha_code = NEW_C_HEAP_ARRAY(u_char, pusha_len, mtInternal);
10602
memcpy(pusha_code, end_popa, pusha_len);
10603
10604
vzup_len = (int)(end_vzup - end_pusha);
10605
if (vzup_len > 0) {
10606
vzup_code = NEW_C_HEAP_ARRAY(u_char, vzup_len, mtInternal);
10607
memcpy(vzup_code, end_pusha, vzup_len);
10608
} else {
10609
vzup_code = pusha_code; // dummy
10610
}
10611
10612
assert(masm.code()->total_oop_size() == 0 &&
10613
masm.code()->total_metadata_size() == 0 &&
10614
masm.code()->total_relocation_size() == 0,
10615
"pre-computed code can't reference oops, metadata or contain relocations");
10616
}
10617
10618
static void emit_copy(CodeSection* code_section, u_char* src, int src_len) {
10619
assert(src != NULL, "code to copy must have been pre-computed");
10620
assert(code_section->limit() - code_section->end() > src_len, "code buffer not large enough");
10621
address end = code_section->end();
10622
memcpy(end, src, src_len);
10623
code_section->set_end(end + src_len);
10624
}
10625
10626
void Assembler::popa() { // 64bit
10627
emit_copy(code_section(), popa_code, popa_len);
10628
}
10629
10630
void Assembler::popa_uncached() { // 64bit
10631
movq(r15, Address(rsp, 0));
10632
movq(r14, Address(rsp, wordSize));
10633
movq(r13, Address(rsp, 2 * wordSize));
10634
movq(r12, Address(rsp, 3 * wordSize));
10635
movq(r11, Address(rsp, 4 * wordSize));
10636
movq(r10, Address(rsp, 5 * wordSize));
10637
movq(r9, Address(rsp, 6 * wordSize));
10638
movq(r8, Address(rsp, 7 * wordSize));
10639
movq(rdi, Address(rsp, 8 * wordSize));
10640
movq(rsi, Address(rsp, 9 * wordSize));
10641
movq(rbp, Address(rsp, 10 * wordSize));
10642
// Skip rsp as it is restored automatically to the value
10643
// before the corresponding pusha when popa is done.
10644
movq(rbx, Address(rsp, 12 * wordSize));
10645
movq(rdx, Address(rsp, 13 * wordSize));
10646
movq(rcx, Address(rsp, 14 * wordSize));
10647
movq(rax, Address(rsp, 15 * wordSize));
10648
10649
addq(rsp, 16 * wordSize);
10650
}
10651
10652
// Does not actually store the value of rsp on the stack.
10653
// The slot for rsp just contains an arbitrary value.
10654
void Assembler::pusha() { // 64bit
10655
emit_copy(code_section(), pusha_code, pusha_len);
10656
}
10657
10658
// Does not actually store the value of rsp on the stack.
10659
// The slot for rsp just contains an arbitrary value.
10660
void Assembler::pusha_uncached() { // 64bit
10661
subq(rsp, 16 * wordSize);
10662
10663
movq(Address(rsp, 15 * wordSize), rax);
10664
movq(Address(rsp, 14 * wordSize), rcx);
10665
movq(Address(rsp, 13 * wordSize), rdx);
10666
movq(Address(rsp, 12 * wordSize), rbx);
10667
// Skip rsp as the value is normally not used. There are a few places where
10668
// the original value of rsp needs to be known but that can be computed
10669
// from the value of rsp immediately after pusha (rsp + 16 * wordSize).
10670
movq(Address(rsp, 10 * wordSize), rbp);
10671
movq(Address(rsp, 9 * wordSize), rsi);
10672
movq(Address(rsp, 8 * wordSize), rdi);
10673
movq(Address(rsp, 7 * wordSize), r8);
10674
movq(Address(rsp, 6 * wordSize), r9);
10675
movq(Address(rsp, 5 * wordSize), r10);
10676
movq(Address(rsp, 4 * wordSize), r11);
10677
movq(Address(rsp, 3 * wordSize), r12);
10678
movq(Address(rsp, 2 * wordSize), r13);
10679
movq(Address(rsp, wordSize), r14);
10680
movq(Address(rsp, 0), r15);
10681
}
10682
10683
void Assembler::vzeroupper() {
10684
emit_copy(code_section(), vzup_code, vzup_len);
10685
}
10686
10687
void Assembler::pushq(Address src) {
10688
InstructionMark im(this);
10689
emit_int16(get_prefixq(src), (unsigned char)0xFF);
10690
emit_operand(rsi, src);
10691
}
10692
10693
void Assembler::rclq(Register dst, int imm8) {
10694
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10695
int encode = prefixq_and_encode(dst->encoding());
10696
if (imm8 == 1) {
10697
emit_int16((unsigned char)0xD1, (0xD0 | encode));
10698
} else {
10699
emit_int24((unsigned char)0xC1, (0xD0 | encode), imm8);
10700
}
10701
}
10702
10703
void Assembler::rcrq(Register dst, int imm8) {
10704
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10705
int encode = prefixq_and_encode(dst->encoding());
10706
if (imm8 == 1) {
10707
emit_int16((unsigned char)0xD1, (0xD8 | encode));
10708
} else {
10709
emit_int24((unsigned char)0xC1, (0xD8 | encode), imm8);
10710
}
10711
}
10712
10713
10714
void Assembler::rorxq(Register dst, Register src, int imm8) {
10715
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
10716
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10717
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
10718
emit_int24((unsigned char)0xF0, (0xC0 | encode), imm8);
10719
}
10720
10721
void Assembler::rorxd(Register dst, Register src, int imm8) {
10722
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
10723
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
10724
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3A, &attributes);
10725
emit_int24((unsigned char)0xF0, (0xC0 | encode), imm8);
10726
}
10727
10728
#ifdef _LP64
10729
void Assembler::salq(Address dst, int imm8) {
10730
InstructionMark im(this);
10731
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10732
if (imm8 == 1) {
10733
emit_int16(get_prefixq(dst), (unsigned char)0xD1);
10734
emit_operand(as_Register(4), dst);
10735
}
10736
else {
10737
emit_int16(get_prefixq(dst), (unsigned char)0xC1);
10738
emit_operand(as_Register(4), dst);
10739
emit_int8(imm8);
10740
}
10741
}
10742
10743
void Assembler::salq(Address dst) {
10744
InstructionMark im(this);
10745
emit_int16(get_prefixq(dst), (unsigned char)0xD3);
10746
emit_operand(as_Register(4), dst);
10747
}
10748
10749
void Assembler::salq(Register dst, int imm8) {
10750
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10751
int encode = prefixq_and_encode(dst->encoding());
10752
if (imm8 == 1) {
10753
emit_int16((unsigned char)0xD1, (0xE0 | encode));
10754
} else {
10755
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
10756
}
10757
}
10758
10759
void Assembler::salq(Register dst) {
10760
int encode = prefixq_and_encode(dst->encoding());
10761
emit_int16((unsigned char)0xD3, (0xE0 | encode));
10762
}
10763
10764
void Assembler::sarq(Address dst, int imm8) {
10765
InstructionMark im(this);
10766
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10767
if (imm8 == 1) {
10768
emit_int16(get_prefixq(dst), (unsigned char)0xD1);
10769
emit_operand(as_Register(7), dst);
10770
}
10771
else {
10772
emit_int16(get_prefixq(dst), (unsigned char)0xC1);
10773
emit_operand(as_Register(7), dst);
10774
emit_int8(imm8);
10775
}
10776
}
10777
10778
void Assembler::sarq(Address dst) {
10779
InstructionMark im(this);
10780
emit_int16(get_prefixq(dst), (unsigned char)0xD3);
10781
emit_operand(as_Register(7), dst);
10782
}
10783
10784
void Assembler::sarq(Register dst, int imm8) {
10785
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10786
int encode = prefixq_and_encode(dst->encoding());
10787
if (imm8 == 1) {
10788
emit_int16((unsigned char)0xD1, (0xF8 | encode));
10789
} else {
10790
emit_int24((unsigned char)0xC1, (0xF8 | encode), imm8);
10791
}
10792
}
10793
10794
void Assembler::sarq(Register dst) {
10795
int encode = prefixq_and_encode(dst->encoding());
10796
emit_int16((unsigned char)0xD3, (0xF8 | encode));
10797
}
10798
#endif
10799
10800
void Assembler::sbbq(Address dst, int32_t imm32) {
10801
InstructionMark im(this);
10802
prefixq(dst);
10803
emit_arith_operand(0x81, rbx, dst, imm32);
10804
}
10805
10806
void Assembler::sbbq(Register dst, int32_t imm32) {
10807
(void) prefixq_and_encode(dst->encoding());
10808
emit_arith(0x81, 0xD8, dst, imm32);
10809
}
10810
10811
void Assembler::sbbq(Register dst, Address src) {
10812
InstructionMark im(this);
10813
emit_int16(get_prefixq(src, dst), 0x1B);
10814
emit_operand(dst, src);
10815
}
10816
10817
void Assembler::sbbq(Register dst, Register src) {
10818
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10819
emit_arith(0x1B, 0xC0, dst, src);
10820
}
10821
10822
void Assembler::shlq(Register dst, int imm8) {
10823
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10824
int encode = prefixq_and_encode(dst->encoding());
10825
if (imm8 == 1) {
10826
emit_int16((unsigned char)0xD1, (0xE0 | encode));
10827
} else {
10828
emit_int24((unsigned char)0xC1, (0xE0 | encode), imm8);
10829
}
10830
}
10831
10832
void Assembler::shlq(Register dst) {
10833
int encode = prefixq_and_encode(dst->encoding());
10834
emit_int16((unsigned char)0xD3, (0xE0 | encode));
10835
}
10836
10837
void Assembler::shrq(Register dst, int imm8) {
10838
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10839
int encode = prefixq_and_encode(dst->encoding());
10840
if (imm8 == 1) {
10841
emit_int16((unsigned char)0xD1, (0xE8 | encode));
10842
}
10843
else {
10844
emit_int24((unsigned char)0xC1, (0xE8 | encode), imm8);
10845
}
10846
}
10847
10848
void Assembler::shrq(Register dst) {
10849
int encode = prefixq_and_encode(dst->encoding());
10850
emit_int16((unsigned char)0xD3, 0xE8 | encode);
10851
}
10852
10853
void Assembler::shrq(Address dst) {
10854
InstructionMark im(this);
10855
emit_int16(get_prefixq(dst), (unsigned char)0xD3);
10856
emit_operand(as_Register(5), dst);
10857
}
10858
10859
void Assembler::shrq(Address dst, int imm8) {
10860
InstructionMark im(this);
10861
assert(isShiftCount(imm8 >> 1), "illegal shift count");
10862
if (imm8 == 1) {
10863
emit_int16(get_prefixq(dst), (unsigned char)0xD1);
10864
emit_operand(as_Register(5), dst);
10865
}
10866
else {
10867
emit_int16(get_prefixq(dst), (unsigned char)0xC1);
10868
emit_operand(as_Register(5), dst);
10869
emit_int8(imm8);
10870
}
10871
}
10872
10873
void Assembler::subq(Address dst, int32_t imm32) {
10874
InstructionMark im(this);
10875
prefixq(dst);
10876
emit_arith_operand(0x81, rbp, dst, imm32);
10877
}
10878
10879
void Assembler::subq(Address dst, Register src) {
10880
InstructionMark im(this);
10881
emit_int16(get_prefixq(dst, src), 0x29);
10882
emit_operand(src, dst);
10883
}
10884
10885
void Assembler::subq(Register dst, int32_t imm32) {
10886
(void) prefixq_and_encode(dst->encoding());
10887
emit_arith(0x81, 0xE8, dst, imm32);
10888
}
10889
10890
// Force generation of a 4 byte immediate value even if it fits into 8bit
10891
void Assembler::subq_imm32(Register dst, int32_t imm32) {
10892
(void) prefixq_and_encode(dst->encoding());
10893
emit_arith_imm32(0x81, 0xE8, dst, imm32);
10894
}
10895
10896
void Assembler::subq(Register dst, Address src) {
10897
InstructionMark im(this);
10898
emit_int16(get_prefixq(src, dst), 0x2B);
10899
emit_operand(dst, src);
10900
}
10901
10902
void Assembler::subq(Register dst, Register src) {
10903
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10904
emit_arith(0x2B, 0xC0, dst, src);
10905
}
10906
10907
void Assembler::testq(Address dst, int32_t imm32) {
10908
InstructionMark im(this);
10909
emit_int16(get_prefixq(dst), (unsigned char)0xF7);
10910
emit_operand(as_Register(0), dst);
10911
emit_int32(imm32);
10912
}
10913
10914
void Assembler::testq(Register dst, int32_t imm32) {
10915
// not using emit_arith because test
10916
// doesn't support sign-extension of
10917
// 8bit operands
10918
int encode = dst->encoding();
10919
encode = prefixq_and_encode(encode);
10920
emit_int16((unsigned char)0xF7, (0xC0 | encode));
10921
emit_int32(imm32);
10922
}
10923
10924
void Assembler::testq(Register dst, Register src) {
10925
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10926
emit_arith(0x85, 0xC0, dst, src);
10927
}
10928
10929
void Assembler::testq(Register dst, Address src) {
10930
InstructionMark im(this);
10931
emit_int16(get_prefixq(src, dst), (unsigned char)0x85);
10932
emit_operand(dst, src);
10933
}
10934
10935
void Assembler::xaddq(Address dst, Register src) {
10936
InstructionMark im(this);
10937
emit_int24(get_prefixq(dst, src), 0x0F, (unsigned char)0xC1);
10938
emit_operand(src, dst);
10939
}
10940
10941
void Assembler::xchgq(Register dst, Address src) {
10942
InstructionMark im(this);
10943
emit_int16(get_prefixq(src, dst), (unsigned char)0x87);
10944
emit_operand(dst, src);
10945
}
10946
10947
void Assembler::xchgq(Register dst, Register src) {
10948
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
10949
emit_int16((unsigned char)0x87, (0xc0 | encode));
10950
}
10951
10952
void Assembler::xorq(Register dst, Register src) {
10953
(void) prefixq_and_encode(dst->encoding(), src->encoding());
10954
emit_arith(0x33, 0xC0, dst, src);
10955
}
10956
10957
void Assembler::xorq(Register dst, Address src) {
10958
InstructionMark im(this);
10959
emit_int16(get_prefixq(src, dst), 0x33);
10960
emit_operand(dst, src);
10961
}
10962
10963
void Assembler::xorq(Register dst, int32_t imm32) {
10964
(void) prefixq_and_encode(dst->encoding());
10965
emit_arith(0x81, 0xF0, dst, imm32);
10966
}
10967
10968
void Assembler::xorq(Address dst, int32_t imm32) {
10969
InstructionMark im(this);
10970
prefixq(dst);
10971
emit_arith_operand(0x81, as_Register(6), dst, imm32);
10972
}
10973
10974
void Assembler::xorq(Address dst, Register src) {
10975
InstructionMark im(this);
10976
emit_int16(get_prefixq(dst, src), 0x31);
10977
emit_operand(src, dst);
10978
}
10979
10980
#endif // !LP64
10981
10982
void InstructionAttr::set_address_attributes(int tuple_type, int input_size_in_bits) {
10983
if (VM_Version::supports_evex()) {
10984
_tuple_type = tuple_type;
10985
_input_size_in_bits = input_size_in_bits;
10986
}
10987
}
10988
10989