src/hotspot/cpu/arm/arm.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/hotspot/cpu/arm/arm.ad Mon Sep 17 10:29:29 2018
--- new/src/hotspot/cpu/arm/arm.ad Mon Sep 17 10:29:28 2018
*** 65,83 ****
--- 65,78 ----
extern bool maybe_far_call(const MachCallNode *n);
static inline bool cache_reachable() {
return MacroAssembler::_cache_fully_reachable();
}
#ifdef AARCH64
#define ldr_32 ldr_w
#define str_32 str_w
#else
#define ldr_32 ldr
#define str_32 str
#define tst_32 tst
#define teq_32 teq
#endif
#if 1
extern bool PrintOptoAssembly;
#endif
class c2 {
*** 109,124 ****
--- 104,114 ----
static int emit_exception_handler(CodeBuffer &cbuf);
static int emit_deopt_handler(CodeBuffer& cbuf);
static uint size_exception_handler() {
#ifdef AARCH64
// ldr_literal; br; (pad); <literal>
return 3 * Assembler::InstructionSize + wordSize;
#else
return ( 3 * 4 );
#endif
}
static uint size_deopt_handler() {
return ( 9 * 4 );
*** 203,223 ****
--- 193,209 ----
//=============================================================================
const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask();
int Compile::ConstantTable::calculate_table_base_offset() const {
#ifdef AARCH64
return 0;
#else
int offset = -(size() / 2);
// flds, fldd: 8-bit offset multiplied by 4: +/- 1024
// ldr, ldrb : 12-bit offset: +/- 4096
if (!Assembler::is_simm10(offset)) {
offset = Assembler::min_simm10();
}
return offset;
#endif
}
bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
ShouldNotReachHere();
*** 238,252 ****
--- 224,234 ----
RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
__ mov_address(r, baseaddr, rspec);
}
uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
#ifdef AARCH64
return 5 * Assembler::InstructionSize;
#else
return 8;
#endif
}
#ifndef PRODUCT
void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
char reg[128];
*** 260,275 ****
--- 242,251 ----
Compile* C = ra_->C;
for (int i = 0; i < OptoPrologueNops; i++) {
st->print_cr("NOP"); st->print("\t");
}
#ifdef AARCH64
if (OptoPrologueNops <= 0) {
st->print_cr("NOP\t! required for safe patching");
st->print("\t");
}
#endif
size_t framesize = C->frame_size_in_bytes();
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
int bangsize = C->bang_size_in_bytes();
// Remove two words for return addr and rbp,
*** 296,310 ****
--- 272,281 ----
MacroAssembler _masm(&cbuf);
for (int i = 0; i < OptoPrologueNops; i++) {
__ nop();
}
#ifdef AARCH64
if (OptoPrologueNops <= 0) {
__ nop(); // required for safe patching by patch_verified_entry()
}
#endif
size_t framesize = C->frame_size_in_bytes();
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
int bangsize = C->bang_size_in_bytes();
// Remove two words for return addr and fp,
*** 359,380 ****
--- 330,341 ----
}
st->print("POP R_FP|R_LR_LR");
if (do_polling() && ra_->C->is_method_compilation()) {
st->print("\n\t");
#ifdef AARCH64
if (MacroAssembler::page_reachable_from_cache(os::get_polling_page())) {
st->print("ADRP Rtemp, #PollAddr\t! Load Polling address\n\t");
st->print("LDR ZR,[Rtemp + #PollAddr & 0xfff]\t!Poll for Safepointing");
} else {
st->print("mov_slow Rtemp, #PollAddr\t! Load Polling address\n\t");
st->print("LDR ZR,[Rtemp]\t!Poll for Safepointing");
}
#else
st->print("MOV Rtemp, #PollAddr\t! Load Polling address\n\t");
st->print("LDR Rtemp,[Rtemp]\t!Poll for Safepointing");
#endif
}
}
#endif
void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
*** 388,427 ****
--- 349,367 ----
}
__ raw_pop(FP, LR);
// If this does safepoint polling, then do it here
if (do_polling() && ra_->C->is_method_compilation()) {
#ifdef AARCH64
if (false && MacroAssembler::page_reachable_from_cache(os::get_polling_page())) {
/* FIXME: TODO
__ relocate(relocInfo::xxx);
__ adrp(Rtemp, (intptr_t)os::get_polling_page());
__ relocate(relocInfo::poll_return_type);
int offset = os::get_polling_page() & 0xfff;
__ ldr(ZR, Address(Rtemp + offset));
*/
} else {
__ mov_address(Rtemp, (address)os::get_polling_page(), symbolic_Relocation::polling_page_reference);
__ relocate(relocInfo::poll_return_type);
__ ldr(ZR, Address(Rtemp));
}
#else
// mov_slow here is usually one or two instruction
__ mov_address(Rtemp, (address)os::get_polling_page(), symbolic_Relocation::polling_page_reference);
__ relocate(relocInfo::poll_return_type);
__ ldr(Rtemp, Address(Rtemp));
#endif
}
}
uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
#ifdef AARCH64
// allow for added alignment nop from mov_address bind_literal
return MachNode::size(ra_) + 1 * Assembler::InstructionSize;
#else
return MachNode::size(ra_);
#endif
}
int MachEpilogNode::reloc() const {
return 16; // a large enough number
}
*** 449,468 ****
--- 389,404 ----
assert(r->is_FloatRegister(), "must be");
return rc_float;
}
static inline bool is_iRegLd_memhd(OptoReg::Name src_first, OptoReg::Name src_second, int offset) {
#ifdef AARCH64
return is_memoryHD(offset);
#else
int rlo = Matcher::_regEncode[src_first];
int rhi = Matcher::_regEncode[src_second];
if (!((rlo&1)==0 && (rlo+1 == rhi))) {
tty->print_cr("CAUGHT BAD LDRD/STRD");
}
return (rlo&1)==0 && (rlo+1 == rhi) && is_memoryHD(offset);
#endif
}
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
PhaseRegAlloc *ra_,
bool do_size,
*** 547,561 ****
--- 483,492 ----
st->print("MOV R_%s, R_%s\t# spill",
Matcher::regName[dst_first],
Matcher::regName[src_first]);
#endif
}
#ifdef AARCH64
if (src_first+1 == src_second && dst_first+1 == dst_second) {
return size + 4;
}
#endif
size += 4;
}
// Check for integer store
if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
*** 720,743 ****
--- 651,666 ----
if (src_second_rc != rc_bad) {
assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
assert(src_second_rc == rc_int && dst_second_rc == rc_float, "unsupported");
if (cbuf) {
#ifdef AARCH64
__ fmov_dx(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
#else
__ fmdrr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]), reg_to_register_object(Matcher::_regEncode[src_second]));
#endif
#ifndef PRODUCT
} else if (!do_size) {
if (size != 0) st->print("\n\t");
#ifdef AARCH64
st->print("FMOV_DX R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
#else
st->print("FMDRR R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first), OptoReg::regname(src_second));
#endif
#endif
}
return size + 4;
} else {
if (cbuf) {
__ fmsr(reg_to_FloatRegister_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[src_first]));
*** 757,780 ****
--- 680,695 ----
if (src_second_rc != rc_bad) {
assert((src_first&1)==0 && src_first+1 == src_second, "pairs of registers must be aligned/contiguous");
assert((dst_first&1)==0 && dst_first+1 == dst_second, "pairs of registers must be aligned/contiguous");
assert(src_second_rc == rc_float && dst_second_rc == rc_int, "unsupported");
if (cbuf) {
#ifdef AARCH64
__ fmov_xd(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
#else
__ fmrrd(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_register_object(Matcher::_regEncode[dst_second]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
#endif
#ifndef PRODUCT
} else if (!do_size) {
if (size != 0) st->print("\n\t");
#ifdef AARCH64
st->print("FMOV_XD R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(src_first));
#else
st->print("FMRRD R_%s, R_%s, R_%s\t! spill",OptoReg::regname(dst_first), OptoReg::regname(dst_second), OptoReg::regname(src_first));
#endif
#endif
}
return size + 4;
} else {
if (cbuf) {
__ fmrs(reg_to_register_object(Matcher::_regEncode[dst_first]), reg_to_FloatRegister_object(Matcher::_regEncode[src_first]));
*** 793,803 ****
--- 708,717 ----
// arguments to native calls.
if (src_second == dst_second)
return size; // Self copy; no move
assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" );
#ifndef AARCH64
// Check for integer reg-reg copy. Hi bits are stuck up in the top
// 32-bits of a 64-bit register, but are needed in low bits of another
// register (else it's a hi-bits-to-hi-bits copy which should have
// happened already as part of a 64-bit move)
if (src_second_rc == rc_int && dst_second_rc == rc_int) {
*** 850,860 ****
--- 764,773 ----
#endif
}
}
return size + 4;
}
#endif
Unimplemented();
return 0; // Mute compiler
}
*** 908,922 ****
--- 821,831 ----
if (is_aimm(offset)) {
__ add(dst, SP, offset);
} else {
__ mov_slow(dst, offset);
#ifdef AARCH64
__ add(dst, SP, dst, ex_lsl);
#else
__ add(dst, SP, dst);
#endif
}
}
uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
// BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_)
*** 924,938 ****
--- 833,843 ----
return ra_->C->scratch_emit_size(this);
}
//=============================================================================
#ifndef PRODUCT
#ifdef AARCH64
#define R_RTEMP "R_R16"
#else
#define R_RTEMP "R_R12"
#endif
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
st->print_cr("\nUEP:");
if (UseCompressedClassPointers) {
st->print_cr("\tLDR_w " R_RTEMP ",[R_R0 + oopDesc::klass_offset_in_bytes]\t! Inline cache check");
st->print_cr("\tdecode_klass " R_RTEMP);
*** 950,967 ****
--- 855,865 ----
assert(iCache == Ricklass, "should be");
Register receiver = R0;
__ load_klass(Rtemp, receiver);
__ cmp(Rtemp, iCache);
#ifdef AARCH64
Label match;
__ b(match, eq);
__ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, Rtemp);
__ bind(match);
#else
__ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne);
#endif
}
uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
return MachNode::size(ra_);
}
*** 1003,1030 ****
--- 901,916 ----
}
int offset = __ offset();
address deopt_pc = __ pc();
#ifdef AARCH64
// See LR saved by caller in sharedRuntime_arm.cpp
// see also hse1 ws
// see also LIR_Assembler::emit_deopt_handler
__ raw_push(LR, LR); // preserve LR in both slots
__ mov_relative_address(LR, deopt_pc);
__ str(LR, Address(SP, 1 * wordSize)); // save deopt PC
// OK to kill LR, because deopt blob will restore it from SP[0]
__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, LR_tmp);
#else
__ sub(SP, SP, wordSize); // make room for saved PC
__ push(LR); // save LR that may be live when we get here
__ mov_relative_address(LR, deopt_pc);
__ str(LR, Address(SP, wordSize)); // save deopt PC
__ pop(LR); // restore LR
__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);
#endif
assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
__ end_a_stub();
return offset;
*** 1071,1095 ****
--- 957,973 ----
case Op_LoadVector:
case Op_StoreVector:
case Op_AddVF:
case Op_SubVF:
case Op_MulVF:
#ifdef AARCH64
return VM_Version::has_simd();
#else
return VM_Version::has_vfp() || VM_Version::has_simd();
#endif
case Op_AddVD:
case Op_SubVD:
case Op_MulVD:
case Op_DivVF:
case Op_DivVD:
#ifdef AARCH64
return VM_Version::has_simd();
#else
return VM_Version::has_vfp();
#endif
}
return true; // Per default match rules are supported.
}
*** 1156,1170 ****
--- 1034,1044 ----
const bool Matcher::pass_original_key_for_aes() {
return false;
}
const bool Matcher::convL2FSupported(void) {
#ifdef AARCH64
return true;
#else
return false;
#endif
}
// Is this branch offset short enough that a short branch can be used?
//
// NOTE: If the platform does not provide any short branch variants, then
*** 1179,1223 ****
--- 1053,1081 ----
return false;
}
const bool Matcher::isSimpleConstant64(jlong value) {
// Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
#ifdef AARCH64
return (value == 0);
#else
return false;
#endif
}
// No scaling for the parameter the ClearArray node.
const bool Matcher::init_array_count_is_in_bytes = true;
#ifdef AARCH64
const int Matcher::long_cmove_cost() { return 1; }
#else
// Needs 2 CMOV's for longs.
const int Matcher::long_cmove_cost() { return 2; }
#endif
#ifdef AARCH64
const int Matcher::float_cmove_cost() { return 1; }
#else
// CMOVF/CMOVD are expensive on ARM.
const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
#endif
// Does the CPU require late expand (see block.cpp for description of late expand)?
const bool Matcher::require_postalloc_expand = false;
// Do we need to mask the count passed to shift instructions or does
// the cpu only look at the lower 5/6 bits anyway?
// FIXME: does this handle vector shifts as well?
#ifdef AARCH64
const bool Matcher::need_masked_shift_count = false;
#else
const bool Matcher::need_masked_shift_count = true;
#endif
const bool Matcher::convi2l_type_required = true;
// Should the Matcher clone shifts on addressing modes, expecting them
// to be subsumed into complex addressing expressions or compute them
*** 1259,1276 ****
--- 1117,1127 ----
// If CPU can load and store mis-aligned doubles directly then no fixup is
// needed. Else we split the double into 2 integer pieces and move it
// piece-by-piece. Only happens when passing doubles into C code as the
// Java calling convention forces doubles to be aligned.
#ifdef AARCH64
// On stack replacement support:
// We don't need Load[DL]_unaligned support, because interpreter stack
// has correct alignment
const bool Matcher::misaligned_doubles_ok = true;
#else
const bool Matcher::misaligned_doubles_ok = false;
#endif
// No-op on ARM.
void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
}
*** 1298,1319 ****
--- 1149,1165 ----
// Return whether or not this register is ever used as an argument. This
// function is used on startup to build the trampoline stubs in generateOptoStub.
// Registers not mentioned will be killed by the VM call in the trampoline, and
// arguments in those registers not be available to the callee.
bool Matcher::can_be_java_arg( int reg ) {
#ifdef AARCH64
if (reg >= R_R0_num && reg < R_R8_num) return true;
if (reg >= R_V0_num && reg <= R_V7b_num && ((reg & 3) < 2)) return true;
#else
if (reg == R_R0_num ||
reg == R_R1_num ||
reg == R_R2_num ||
reg == R_R3_num) return true;
if (reg >= R_S0_num &&
reg <= R_S13_num) return true;
#endif
return false;
}
bool Matcher::is_spillable_arg( int reg ) {
return can_be_java_arg(reg);
*** 1452,1499 ****
--- 1298,1315 ----
enc_class Java_Dynamic_Call (method meth) %{
MacroAssembler _masm(&cbuf);
Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
assert(R8_ic_reg == Ricklass, "should be");
__ set_inst_mark();
#ifdef AARCH64
// TODO: see C1 LIR_Assembler::ic_call()
InlinedAddress oop_literal((address)Universe::non_oop_word());
int offset = __ offset();
int fixed_size = mov_oop_size * 4;
if (VM_Version::prefer_moves_over_load_literal()) {
uintptr_t val = (uintptr_t)Universe::non_oop_word();
__ movz(R8_ic_reg, (val >> 0) & 0xffff, 0);
__ movk(R8_ic_reg, (val >> 16) & 0xffff, 16);
__ movk(R8_ic_reg, (val >> 32) & 0xffff, 32);
__ movk(R8_ic_reg, (val >> 48) & 0xffff, 48);
} else {
__ ldr_literal(R8_ic_reg, oop_literal);
}
assert(__ offset() - offset == fixed_size, "bad mov_oop size");
#else
__ movw(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) & 0xffff);
__ movt(R8_ic_reg, ((unsigned int)Universe::non_oop_word()) >> 16);
#endif
address virtual_call_oop_addr = __ inst_mark();
// CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
// who we intended to call.
int method_index = resolved_method_index(cbuf);
__ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
emit_call_reloc(cbuf, as_MachCall(), $meth, RelocationHolder::none);
#ifdef AARCH64
if (!VM_Version::prefer_moves_over_load_literal()) {
Label skip_literal;
__ b(skip_literal);
int off2 = __ offset();
__ bind_literal(oop_literal);
if (__ offset() - off2 == wordSize) {
// no padding, so insert nop for worst-case sizing
__ nop();
}
__ bind(skip_literal);
}
#endif
%}
enc_class LdReplImmI(immI src, regD dst, iRegI tmp, int cnt, int wth) %{
// FIXME: load from constant table?
// Load a constant replicated "count" times with width "width"
*** 1556,1575 ****
--- 1372,1383 ----
// difference of the string lengths (stack)
// See if the lengths are different, and calculate min in str1_reg.
// Stash diff in tmp2 in case we need it for a tie-breaker.
__ subs_32(tmp2_reg, cnt1_reg, cnt2_reg);
#ifdef AARCH64
Label Lskip;
__ _lsl_w(cnt1_reg, cnt1_reg, exact_log2(sizeof(jchar))); // scale the limit
__ b(Lskip, mi);
__ _lsl_w(cnt1_reg, cnt2_reg, exact_log2(sizeof(jchar))); // scale the limit
__ bind(Lskip);
#else
__ mov(cnt1_reg, AsmOperand(cnt1_reg, lsl, exact_log2(sizeof(jchar)))); // scale the limit
__ mov(cnt1_reg, AsmOperand(cnt2_reg, lsl, exact_log2(sizeof(jchar))), pl); // scale the limit
#endif
// reallocate cnt1_reg, cnt2_reg, result_reg
// Note: limit_reg holds the string length pre-scaled by 2
Register limit_reg = cnt1_reg;
Register chr2_reg = cnt2_reg;
*** 1715,1734 ****
--- 1523,1532 ----
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
// return true if the same array
#ifdef AARCH64
__ cmp(ary1_reg, ary2_reg);
__ b(Lequal, eq);
__ mov(result_reg, 0);
__ cbz(ary1_reg, Ldone); // not equal
__ cbz(ary2_reg, Ldone); // not equal
#else
__ teq(ary1_reg, ary2_reg);
__ mov(result_reg, 1, eq);
__ b(Ldone, eq); // equal
__ tst(ary1_reg, ary1_reg);
*** 1736,1766 ****
--- 1534,1556 ----
__ b(Ldone, eq); // not equal
__ tst(ary2_reg, ary2_reg);
__ mov(result_reg, 0, eq);
__ b(Ldone, eq); // not equal
#endif
//load the lengths of arrays
__ ldr_s32(tmp1_reg, Address(ary1_reg, length_offset)); // int
__ ldr_s32(tmp2_reg, Address(ary2_reg, length_offset)); // int
// return false if the two arrays are not equal length
#ifdef AARCH64
__ cmp_w(tmp1_reg, tmp2_reg);
__ b(Ldone, ne); // not equal
__ cbz_w(tmp1_reg, Lequal); // zero-length arrays are equal
#else
__ teq_32(tmp1_reg, tmp2_reg);
__ mov(result_reg, 0, ne);
__ b(Ldone, ne); // not equal
__ tst(tmp1_reg, tmp1_reg);
__ mov(result_reg, 1, eq);
__ b(Ldone, eq); // zero-length arrays are equal
#endif
// load array addresses
__ add(ary1_reg, ary1_reg, base_offset);
__ add(ary2_reg, ary2_reg, base_offset);
*** 1850,1864 ****
--- 1640,1650 ----
// Number of stack slots consumed by a Monitor enter
sync_stack_slots(1 * VMRegImpl::slots_per_word);
// Compiled code's Frame Pointer
#ifdef AARCH64
frame_pointer(R_SP);
#else
frame_pointer(R_R13);
#endif
// Stack alignment requirement
stack_alignment(StackAlignmentInBytes);
// LP64: Alignment size in bytes (128-bit -> 16 bytes)
// !LP64: Alignment size in bytes (64-bit -> 8 bytes)
*** 1951,1961 ****
--- 1737,1746 ----
format %{ %}
interface(CONST_INTER);
%}
#ifndef AARCH64
// Integer Immediate: offset for half and double word loads and stores
operand immIHD() %{
predicate(is_memoryHD(n->get_int()));
match(ConI);
op_cost(0);
*** 1970,1980 ****
--- 1755,1764 ----
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
#endif
// Valid scale values for addressing modes and shifts
operand immU5() %{
predicate(0 <= n->get_int() && (n->get_int() <= 31));
match(ConI);
*** 2181,2229 ****
--- 1965,1974 ----
format %{ %}
interface(CONST_INTER);
%}
#ifdef AARCH64
// Long Immediate: for logical instruction
operand limmL() %{
predicate(is_limmL(n->get_long()));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand limmLn() %{
predicate(is_limmL(~n->get_long()));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
// Long Immediate: for arithmetic instruction
operand aimmL() %{
predicate(is_aimm(n->get_long()));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
operand aimmLneg() %{
predicate(is_aimm(-n->get_long()));
match(ConL);
op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
#endif // AARCH64
// Long Immediate: the value FF
operand immL_FF() %{
predicate( n->get_long() == 0xFFL );
match(ConL);
*** 2402,2416 ****
--- 2147,2157 ----
match(RegI);
match(R0RegI);
match(R1RegI);
match(R2RegI);
match(R3RegI);
#ifdef AARCH64
match(ZRRegI);
#else
match(R12RegI);
#endif
format %{ %}
interface(REG_INTER);
%}
*** 2444,2496 ****
--- 2185,2194 ----
format %{ %}
interface(REG_INTER);
%}
#ifdef AARCH64
// Like sp_ptr_reg, but exclude regs (Aarch64 SP) that can't be
// stored directly. Includes ZR, so can't be used as a destination.
operand store_ptr_RegP() %{
constraint(ALLOC_IN_RC(store_ptr_reg));
match(RegP);
match(iRegP);
match(ZRRegP);
format %{ %}
interface(REG_INTER);
%}
operand store_RegI() %{
constraint(ALLOC_IN_RC(store_reg));
match(RegI);
match(iRegI);
match(ZRRegI);
format %{ %}
interface(REG_INTER);
%}
operand store_RegL() %{
constraint(ALLOC_IN_RC(store_ptr_reg));
match(RegL);
match(iRegL);
match(ZRRegL);
format %{ %}
interface(REG_INTER);
%}
operand store_RegN() %{
constraint(ALLOC_IN_RC(store_reg));
match(RegN);
match(iRegN);
match(ZRRegN);
format %{ %}
interface(REG_INTER);
%}
#endif
operand R0RegP() %{
constraint(ALLOC_IN_RC(R0_regP));
match(iRegP);
*** 2576,2605 ****
--- 2274,2297 ----
format %{ %}
interface(REG_INTER);
%}
#ifndef AARCH64
operand R12RegI() %{
constraint(ALLOC_IN_RC(R12_regI));
match(iRegI);
format %{ %}
interface(REG_INTER);
%}
#endif
// Long Register
operand iRegL() %{
constraint(ALLOC_IN_RC(long_reg));
match(RegL);
#ifdef AARCH64
match(iRegLd);
#else
match(R0R1RegL);
match(R2R3RegL);
#endif
//match(iRegLex);
format %{ %}
interface(REG_INTER);
%}
*** 2610,2620 ****
--- 2302,2311 ----
format %{ %}
interface(REG_INTER);
%}
#ifndef AARCH64
// first long arg, or return value
operand R0R1RegL() %{
constraint(ALLOC_IN_RC(R0R1_regL));
match(iRegL);
*** 2627,2637 ****
--- 2318,2327 ----
match(iRegL);
format %{ %}
interface(REG_INTER);
%}
#endif
// Condition Code Flag Register
operand flagsReg() %{
constraint(ALLOC_IN_RC(int_flags));
match(RegFlags);
*** 2669,2679 ****
--- 2359,2368 ----
format %{ "apsr_P" %}
interface(REG_INTER);
%}
// Condition Code Register, long comparisons.
#ifndef AARCH64
operand flagsRegL_LTGE() %{
constraint(ALLOC_IN_RC(int_flags));
match(RegFlags);
format %{ "apsr_L_LTGE" %}
*** 2717,2727 ****
--- 2406,2415 ----
match(RegFlags);
format %{ "apsr_UL_LEGT" %}
interface(REG_INTER);
%}
#endif
// Condition Code Register, floating comparisons, unordered same as "less".
operand flagsRegF() %{
constraint(ALLOC_IN_RC(float_flags));
match(RegFlags);
*** 2798,2929 ****
--- 2486,2512 ----
op_cost(100);
format %{ "[$reg]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp(0x0);
%}
%}
#ifdef AARCH64
// Indirect with scaled*1 uimm12 offset
operand indOffsetU12ScaleB(sp_ptr_RegP reg, immUL12 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
// Indirect with scaled*2 uimm12 offset
operand indOffsetU12ScaleS(sp_ptr_RegP reg, immUL12x2 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
// Indirect with scaled*4 uimm12 offset
operand indOffsetU12ScaleI(sp_ptr_RegP reg, immUL12x4 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
// Indirect with scaled*8 uimm12 offset
operand indOffsetU12ScaleL(sp_ptr_RegP reg, immUL12x8 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
// Indirect with scaled*16 uimm12 offset
operand indOffsetU12ScaleQ(sp_ptr_RegP reg, immUL12x16 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
#else // ! AARCH64
// Indirect with Offset in ]-4096, 4096[
operand indOffset12(sp_ptr_RegP reg, immI12 offset) %{
constraint(ALLOC_IN_RC(sp_ptr_reg));
match(AddP reg offset);
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
*** 2934,2948 ****
--- 2517,2527 ----
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
*** 2953,2967 ****
--- 2532,2542 ----
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
*** 2972,2986 ****
--- 2547,2557 ----
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
*** 2991,3010 ****
--- 2562,2576 ----
op_cost(100);
format %{ "[$reg + $offset]" %}
interface(MEMORY_INTER) %{
base($reg);
#ifdef AARCH64
index(0xff); // 0xff => no index
#else
index(0xf); // PC => no index
#endif
scale(0x0);
disp($offset);
%}
%}
#endif // !AARCH64
// Indirect with Register Index
operand indIndex(iRegP addr, iRegX index) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr index);
*** 3017,3029 ****
--- 2583,2594 ----
scale(0x0);
disp(0x0);
%}
%}
#ifdef AARCH64
// Indirect Memory Times Scale Plus Index Register
! operand indIndexScaleS(iRegP addr, iRegX index, immI_1 scale) %{
! operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX index scale));
op_cost(100);
format %{"[$addr + $index << $scale]" %}
*** 3033,3166 ****
--- 2598,2610 ----
scale($scale);
disp(0x0);
%}
%}
// Indirect Memory Times Scale Plus 32-bit Index Register
operand indIndexIScaleS(iRegP addr, iRegI index, immI_1 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX (ConvI2L index) scale));
op_cost(100);
format %{"[$addr + $index.w << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x7fffffff); // sxtw
%}
%}
// Indirect Memory Times Scale Plus Index Register
operand indIndexScaleI(iRegP addr, iRegX index, immI_2 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX index scale));
op_cost(100);
format %{"[$addr + $index << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x0);
%}
%}
// Indirect Memory Times Scale Plus 32-bit Index Register
operand indIndexIScaleI(iRegP addr, iRegI index, immI_2 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX (ConvI2L index) scale));
op_cost(100);
format %{"[$addr + $index.w << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x7fffffff); // sxtw
%}
%}
// Indirect Memory Times Scale Plus Index Register
operand indIndexScaleL(iRegP addr, iRegX index, immI_3 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX index scale));
op_cost(100);
format %{"[$addr + $index << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x0);
%}
%}
// Indirect Memory Times Scale Plus 32-bit Index Register
operand indIndexIScaleL(iRegP addr, iRegI index, immI_3 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX (ConvI2L index) scale));
op_cost(100);
format %{"[$addr + $index.w << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x7fffffff); // sxtw
%}
%}
// Indirect Memory Times Scale Plus Index Register
operand indIndexScaleQ(iRegP addr, iRegX index, immI_4 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX index scale));
op_cost(100);
format %{"[$addr + $index << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x0);
%}
%}
// Indirect Memory Times Scale Plus 32-bit Index Register
operand indIndexIScaleQ(iRegP addr, iRegI index, immI_4 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX (ConvI2L index) scale));
op_cost(100);
format %{"[$addr + $index.w << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x7fffffff); // sxtw
%}
%}
#else
// Indirect Memory Times Scale Plus Index Register
operand indIndexScale(iRegP addr, iRegX index, immU5 scale) %{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP addr (LShiftX index scale));
op_cost(100);
format %{"[$addr + $index << $scale]" %}
interface(MEMORY_INTER) %{
base($addr);
index($index);
scale($scale);
disp(0x0);
%}
%}
#endif
// Operands for expressing Control Flow
// NOTE: Label is a predefined operand which should not be redefined in
// the AD file. It is generically handled within the ADLC.
+ // Operands for expressing Control Flow
+ // NOTE: Label is a predefined operand which should not be redefined in
+ // the AD file. It is generically handled within the ADLC.
//----------Conditional Branch Operands----------------------------------------
// Comparison Op - This is the operation of the comparison, and is limited to
// the following set of codes:
// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
*** 3310,3342 ****
--- 2754,2763 ----
// Operand Classes are groups of operands that are used to simplify
// instruction definitions by not requiring the AD writer to specify separate
// instructions for every form of operand when the instruction accepts
// multiple operand types with the same basic encoding and format. The classic
// case of this is memory operands.
#ifdef AARCH64
opclass memoryB(indirect, indIndex, indOffsetU12ScaleB);
opclass memoryS(indirect, indIndex, indIndexScaleS, indIndexIScaleS, indOffsetU12ScaleS);
opclass memoryI(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
opclass memoryL(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
opclass memoryP(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
opclass memoryQ(indirect, indIndex, indIndexScaleQ, indIndexIScaleQ, indOffsetU12ScaleQ);
opclass memoryF(indirect, indIndex, indIndexScaleI, indIndexIScaleI, indOffsetU12ScaleI);
opclass memoryD(indirect, indIndex, indIndexScaleL, indIndexIScaleL, indOffsetU12ScaleL);
opclass memoryScaledS(indIndexScaleS, indIndexIScaleS);
opclass memoryScaledI(indIndexScaleI, indIndexIScaleI);
opclass memoryScaledL(indIndexScaleL, indIndexIScaleL);
opclass memoryScaledP(indIndexScaleL, indIndexIScaleL);
opclass memoryScaledQ(indIndexScaleQ, indIndexIScaleQ);
opclass memoryScaledF(indIndexScaleI, indIndexIScaleI);
opclass memoryScaledD(indIndexScaleL, indIndexIScaleL);
// when ldrex/strex is used:
opclass memoryex ( indirect );
opclass indIndexMemory( indIndex );
opclass memoryvld ( indirect /* , write back mode not implemented */ );
#else
opclass memoryI ( indirect, indOffset12, indIndex, indIndexScale );
opclass memoryP ( indirect, indOffset12, indIndex, indIndexScale );
opclass memoryF ( indirect, indOffsetFP );
opclass memoryF2 ( indirect, indOffsetFPx2 );
*** 3352,3362 ****
--- 2773,2782 ----
// when ldrex/strex is used:
opclass memoryex ( indirect );
opclass indIndexMemory( indIndex );
opclass memorylong ( indirect, indOffset12x2 );
opclass memoryvld ( indirect /* , write back mode not implemented */ );
#endif
//----------PIPELINE-----------------------------------------------------------
pipeline %{
//----------ATTRIBUTES---------------------------------------------------------
*** 4161,4196 ****
--- 3581,3607 ----
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDRSB $dst,$mem\t! byte -> int" %}
ins_encode %{
// High 32 bits are harmlessly set on Aarch64
__ ldrsb($dst$$Register, $mem$$Address);
%}
ins_pipe(iload_mask_mem);
%}
// Load Byte (8bit signed) into a Long Register
instruct loadB2L(iRegL dst, memoryB mem) %{
match(Set dst (ConvI2L (LoadB mem)));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
size(4);
format %{ "LDRSB $dst,$mem\t! byte -> long" %}
ins_encode %{
__ ldrsb($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDRSB $dst.lo,$mem\t! byte -> long\n\t"
"ASR $dst.hi,$dst.lo,31" %}
ins_encode %{
__ ldrsb($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
%}
#endif
ins_pipe(iload_mask_mem);
%}
// Load Unsigned Byte (8bit UNsigned) into an int reg
instruct loadUB(iRegI dst, memoryB mem) %{
*** 4208,4282 ****
--- 3619,3656 ----
// Load Unsigned Byte (8bit UNsigned) into a Long Register
instruct loadUB2L(iRegL dst, memoryB mem) %{
match(Set dst (ConvI2L (LoadUB mem)));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
size(4);
format %{ "LDRB $dst,$mem\t! ubyte -> long" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDRB $dst.lo,$mem\t! ubyte -> long\n\t"
"MOV $dst.hi,0" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(iload_mem);
%}
// Load Unsigned Byte (8 bit UNsigned) with immediate mask into Long Register
instruct loadUB2L_limmI(iRegL dst, memoryB mem, limmIlow8 mask) %{
match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
#ifdef AARCH64
ins_cost(MEMORY_REF_COST + DEFAULT_COST);
size(8);
format %{ "LDRB $dst,$mem\t! ubyte -> long\n\t"
"AND $dst,$dst,$mask" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
__ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
%}
#else
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
size(12);
format %{ "LDRB $dst.lo,$mem\t! ubyte -> long\n\t"
"MOV $dst.hi,0\n\t"
"AND $dst.lo,$dst.lo,$mask" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
__ andr($dst$$Register, $dst$$Register, limmI_low($mask$$constant, 8));
%}
#endif
ins_pipe(iload_mem);
%}
// Load Short (16bit signed)
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadS (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "LDRSH $dst,$mem+$off\t! short temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldrsh($dst$$Register, nmem);
%}
ins_pipe(iload_mask_mem);
%}
#endif
instruct loadS(iRegI dst, memoryS mem) %{
match(Set dst (LoadS mem));
ins_cost(MEMORY_REF_COST);
*** 4295,4353 ****
--- 3669,3700 ----
size(4);
format %{ "LDRSB $dst,$mem\t! short -> byte" %}
ins_encode %{
// High 32 bits are harmlessly set on Aarch64
__ ldrsb($dst$$Register, $mem$$Address);
%}
ins_pipe(iload_mask_mem);
%}
// Load Short (16bit signed) into a Long Register
instruct loadS2L(iRegL dst, memoryS mem) %{
match(Set dst (ConvI2L (LoadS mem)));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
size(4);
format %{ "LDRSH $dst,$mem\t! short -> long" %}
ins_encode %{
__ ldrsh($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDRSH $dst.lo,$mem\t! short -> long\n\t"
"ASR $dst.hi,$dst.lo,31" %}
ins_encode %{
__ ldrsh($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
%}
#endif
ins_pipe(iload_mask_mem);
%}
// Load Unsigned Short/Char (16bit UNsigned)
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadUSoff(iRegI dst, memoryScaledS mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadUS (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "LDRH $dst,$mem+$off\t! ushort/char temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldrh($dst$$Register, nmem);
%}
ins_pipe(iload_mem);
%}
#endif
instruct loadUS(iRegI dst, memoryS mem) %{
match(Set dst (LoadUS mem));
ins_cost(MEMORY_REF_COST);
*** 4375,4439 ****
--- 3722,3759 ----
// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
instruct loadUS2L(iRegL dst, memoryS mem) %{
match(Set dst (ConvI2L (LoadUS mem)));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
size(4);
format %{ "LDRH $dst,$mem\t! short -> long" %}
ins_encode %{
__ ldrh($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDRH $dst.lo,$mem\t! short -> long\n\t"
"MOV $dst.hi, 0" %}
ins_encode %{
__ ldrh($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(iload_mem);
%}
// Load Unsigned Short/Char (16bit UNsigned) with mask 0xFF into a Long Register
instruct loadUS2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
size(4);
format %{ "LDRB $dst,$mem" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDRB $dst.lo,$mem\t! \n\t"
"MOV $dst.hi, 0" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(iload_mem);
%}
// Load Unsigned Short/Char (16bit UNsigned) with a immediate mask into a Long Register
instruct loadUS2L_limmI(iRegL dst, memoryS mem, limmI mask) %{
match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
#ifdef AARCH64
ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
size(8);
format %{ "LDRH $dst,$mem\t! ushort/char & mask -> long\n\t"
"AND $dst,$dst,$mask" %}
ins_encode %{
__ ldrh($dst$$Register, $mem$$Address);
__ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
%}
#else
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
size(12);
format %{ "LDRH $dst,$mem\t! ushort/char & mask -> long\n\t"
"MOV $dst.hi, 0\n\t"
*** 4441,4474 ****
--- 3761,3775 ----
ins_encode %{
__ ldrh($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
__ andr($dst$$Register, $dst$$Register, $mask$$constant);
%}
#endif
ins_pipe(iload_mem);
%}
// Load Integer
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadIoff(iRegI dst, memoryScaledI mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadI (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "ldr_s32 $dst,$mem+$off\t! int temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldr_s32($dst$$Register, nmem);
%}
ins_pipe(iload_mem);
%}
#endif
instruct loadI(iRegI dst, memoryI mem) %{
match(Set dst (LoadI mem));
ins_cost(MEMORY_REF_COST);
*** 4535,4631 ****
--- 3836,3887 ----
%}
// Load Integer into a Long Register
instruct loadI2L(iRegL dst, memoryI mem) %{
match(Set dst (ConvI2L (LoadI mem)));
#ifdef AARCH64
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDRSW $dst.lo,$mem\t! int -> long" %}
ins_encode %{
__ ldr_s32($dst$$Register, $mem$$Address);
%}
#else
ins_cost(MEMORY_REF_COST);
size(8);
format %{ "LDR $dst.lo,$mem\t! int -> long\n\t"
"ASR $dst.hi,$dst.lo,31\t! int->long" %}
ins_encode %{
__ ldr($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), AsmOperand($dst$$Register, asr, 31));
%}
#endif
ins_pipe(iload_mask_mem);
%}
// Load Integer with mask 0xFF into a Long Register
instruct loadI2L_immI_255(iRegL dst, memoryB mem, immI_255 mask) %{
match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
#ifdef AARCH64
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDRB $dst.lo,$mem\t! int & 0xFF -> long" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
%}
#else
ins_cost(MEMORY_REF_COST);
size(8);
format %{ "LDRB $dst.lo,$mem\t! int & 0xFF -> long\n\t"
"MOV $dst.hi, 0" %}
ins_encode %{
__ ldrb($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(iload_mem);
%}
// Load Integer with mask 0xFFFF into a Long Register
instruct loadI2L_immI_65535(iRegL dst, memoryS mem, immI_65535 mask) %{
match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
size(4);
format %{ "LDRH $dst,$mem\t! int & 0xFFFF -> long" %}
ins_encode %{
__ ldrh($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDRH $dst,$mem\t! int & 0xFFFF -> long\n\t"
"MOV $dst.hi, 0" %}
ins_encode %{
__ ldrh($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(iload_mask_mem);
%}
#ifdef AARCH64
// Load Integer with an immediate mask into a Long Register
instruct loadI2L_limmI(iRegL dst, memoryI mem, limmI mask) %{
match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
ins_cost(MEMORY_REF_COST + 1*DEFAULT_COST);
size(8);
format %{ "LDRSW $dst,$mem\t! int -> long\n\t"
"AND $dst,$dst,$mask" %}
ins_encode %{
__ ldr_s32($dst$$Register, $mem$$Address);
__ andr($dst$$Register, $dst$$Register, (uintx)$mask$$constant);
%}
ins_pipe(iload_mem);
%}
#else
// Load Integer with a 31-bit immediate mask into a Long Register
instruct loadI2L_limmU31(iRegL dst, memoryI mem, limmU31 mask) %{
match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
ins_cost(MEMORY_REF_COST + 2*DEFAULT_COST);
*** 4639,4669 ****
--- 3895,3905 ----
__ mov($dst$$Register->successor(), 0);
__ andr($dst$$Register, $dst$$Register, $mask$$constant);
%}
ins_pipe(iload_mem);
%}
#endif
#ifdef AARCH64
// Load Integer with mask into a Long Register
// FIXME: use signedRegI mask, remove tmp?
instruct loadI2L_immI(iRegL dst, memoryI mem, immI mask, iRegI tmp) %{
match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
effect(TEMP dst, TEMP tmp);
ins_cost(MEMORY_REF_COST + 3*DEFAULT_COST);
format %{ "LDRSW $mem,$dst\t! int & 31-bit mask -> long\n\t"
"MOV_SLOW $tmp,$mask\n\t"
"AND $dst,$tmp,$dst" %}
ins_encode %{
__ ldrsw($dst$$Register, $mem$$Address);
__ mov_slow($tmp$$Register, $mask$$constant);
__ andr($dst$$Register, $dst$$Register, $tmp$$Register);
%}
ins_pipe(iload_mem);
%}
#else
// Load Integer with a 31-bit mask into a Long Register
// FIXME: use iRegI mask, remove tmp?
instruct loadI2L_immU31(iRegL dst, memoryI mem, immU31 mask, iRegI tmp) %{
match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
effect(TEMP dst, TEMP tmp);
*** 4680,4741 ****
--- 3916,3946 ----
__ mov_slow($tmp$$Register, $mask$$constant);
__ andr($dst$$Register, $dst$$Register, $tmp$$Register);
%}
ins_pipe(iload_mem);
%}
#endif
// Load Unsigned Integer into a Long Register
instruct loadUI2L(iRegL dst, memoryI mem, immL_32bits mask) %{
match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
ins_cost(MEMORY_REF_COST);
#ifdef AARCH64
//size(4);
format %{ "LDR_w $dst,$mem\t! uint -> long" %}
ins_encode %{
__ ldr_w($dst$$Register, $mem$$Address);
%}
#else
size(8);
format %{ "LDR $dst.lo,$mem\t! uint -> long\n\t"
"MOV $dst.hi,0" %}
ins_encode %{
__ ldr($dst$$Register, $mem$$Address);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(iload_mem);
%}
// Load Long
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadLoff(iRegLd dst, memoryScaledL mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadL (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "LDR $dst,$mem+$off\t! long temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldr($dst$$Register, nmem);
%}
ins_pipe(iload_mem);
%}
#endif
instruct loadL(iRegLd dst, memoryL mem ) %{
#ifdef AARCH64
// already atomic for Aarch64
#else
predicate(!((LoadLNode*)n)->require_atomic_access());
#endif
match(Set dst (LoadL mem));
effect(TEMP dst);
ins_cost(MEMORY_REF_COST);
size(4);
*** 4744,4754 ****
--- 3949,3958 ----
__ ldr_64($dst$$Register, $mem$$Address);
%}
ins_pipe(iload_mem);
%}
#ifndef AARCH64
instruct loadL_2instr(iRegL dst, memorylong mem ) %{
predicate(!((LoadLNode*)n)->require_atomic_access());
match(Set dst (LoadL mem));
ins_cost(MEMORY_REF_COST + DEFAULT_COST);
*** 4820,4830 ****
--- 4024,4033 ----
__ ldr($dst$$Register->successor(), Amemhi);
}
%}
ins_pipe(iload_mem);
%}
#endif // !AARCH64
// Load Range
instruct loadRange(iRegI dst, memoryI mem) %{
match(Set dst (LoadRange mem));
ins_cost(MEMORY_REF_COST);
*** 4837,4864 ****
--- 4040,4049 ----
ins_pipe(iload_mem);
%}
// Load Pointer
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadPoff(iRegP dst, memoryScaledP mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadP (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "LDR $dst,$mem+$off\t! ptr temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldr($dst$$Register, nmem);
%}
ins_pipe(iload_mem);
%}
#endif
instruct loadP(iRegP dst, memoryP mem) %{
match(Set dst (LoadP mem));
ins_cost(MEMORY_REF_COST);
size(4);
*** 4948,4975 ****
--- 4133,4142 ----
%}
ins_pipe(iload_mem);
%}
#endif
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadDoff(regD dst, memoryScaledD mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadD (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "ldr $dst,$mem+$off\t! double temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldr_d($dst$$FloatRegister, nmem);
%}
ins_pipe(floadD_mem);
%}
#endif
instruct loadD(regD dst, memoryD mem) %{
match(Set dst (LoadD mem));
ins_cost(MEMORY_REF_COST);
*** 4981,4991 ****
--- 4148,4157 ----
__ ldr_double($dst$$FloatRegister, $mem$$Address);
%}
ins_pipe(floadD_mem);
%}
#ifndef AARCH64
// Load Double - UNaligned
instruct loadD_unaligned(regD_low dst, memoryF2 mem ) %{
match(Set dst (LoadD_unaligned mem));
ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
size(8);
*** 4997,5026 ****
--- 4163,4173 ----
__ flds($dst$$FloatRegister, Amemlo);
__ flds($dst$$FloatRegister->successor(), Amemhi);
%}
ins_pipe(iload_mem);
%}
#endif
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct loadFoff(regF dst, memoryScaledF mem, aimmX off, iRegP tmp) %{
match(Set dst (LoadF (AddP mem off)));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "ldr $dst,$mem+$off\t! float temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ ldr_s($dst$$FloatRegister, nmem);
%}
ins_pipe(floadF_mem);
%}
#endif
instruct loadF(regF dst, memoryF mem) %{
match(Set dst (LoadF mem));
ins_cost(MEMORY_REF_COST);
*** 5030,5050 ****
--- 4177,4186 ----
__ ldr_float($dst$$FloatRegister, $mem$$Address);
%}
ins_pipe(floadF_mem);
%}
#ifdef AARCH64
instruct load_limmI(iRegI dst, limmI src) %{
match(Set dst src);
ins_cost(DEFAULT_COST + 1); // + 1 because MOV is preferred
format %{ "ORR_w $dst, ZR, $src\t! int" %}
ins_encode %{
__ orr_w($dst$$Register, ZR, (uintx)$src$$constant);
%}
ins_pipe(ialu_imm);
%}
#endif
// // Load Constant
instruct loadConI( iRegI dst, immI src ) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 3/2);
*** 5063,5098 ****
--- 4199,4224 ----
__ mov($dst$$Register, $src$$constant);
%}
ins_pipe(ialu_imm);
%}
#ifndef AARCH64
instruct loadConIMovn( iRegI dst, immIRotn src ) %{
match(Set dst src);
size(4);
format %{ "MVN $dst, ~$src" %}
ins_encode %{
__ mvn($dst$$Register, ~$src$$constant);
%}
ins_pipe(ialu_imm_n);
%}
#endif
instruct loadConI16( iRegI dst, immI16 src ) %{
match(Set dst src);
size(4);
#ifdef AARCH64
format %{ "MOVZ_w $dst, $src" %}
#else
format %{ "MOVW $dst, $src" %}
#endif
ins_encode %{
#ifdef AARCH64
__ mov_w($dst$$Register, $src$$constant);
#else
__ movw($dst$$Register, $src$$constant);
#endif
%}
ins_pipe(ialu_imm_n);
%}
instruct loadConP(iRegP dst, immP src) %{
*** 5122,5205 ****
--- 4248,4257 ----
__ mov_slow($dst$$Register, $src$$constant);
%}
ins_pipe(loadConP_poll);
%}
#ifdef AARCH64
instruct loadConP0(iRegP dst, immP0 src) %{
match(Set dst src);
ins_cost(DEFAULT_COST);
format %{ "MOV $dst,ZR\t!ptr" %}
ins_encode %{
__ mov($dst$$Register, ZR);
%}
ins_pipe(ialu_none);
%}
instruct loadConN(iRegN dst, immN src) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 3/2);
format %{ "SET $dst,$src\t! compressed ptr" %}
ins_encode %{
Register dst = $dst$$Register;
// FIXME: use $constanttablebase?
__ set_narrow_oop(dst, (jobject)$src$$constant);
%}
ins_pipe(ialu_hi_lo_reg);
%}
instruct loadConN0(iRegN dst, immN0 src) %{
match(Set dst src);
ins_cost(DEFAULT_COST);
format %{ "MOV $dst,ZR\t! compressed ptr" %}
ins_encode %{
__ mov($dst$$Register, ZR);
%}
ins_pipe(ialu_none);
%}
instruct loadConNKlass(iRegN dst, immNKlass src) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 3/2);
format %{ "SET $dst,$src\t! compressed klass ptr" %}
ins_encode %{
Register dst = $dst$$Register;
// FIXME: use $constanttablebase?
__ set_narrow_klass(dst, (Klass*)$src$$constant);
%}
ins_pipe(ialu_hi_lo_reg);
%}
instruct load_limmL(iRegL dst, limmL src) %{
match(Set dst src);
ins_cost(DEFAULT_COST);
format %{ "ORR $dst, ZR, $src\t! long" %}
ins_encode %{
__ orr($dst$$Register, ZR, (uintx)$src$$constant);
%}
ins_pipe(loadConL);
%}
instruct load_immLMov(iRegL dst, immLMov src) %{
match(Set dst src);
ins_cost(DEFAULT_COST);
format %{ "MOV $dst, $src\t! long" %}
ins_encode %{
__ mov($dst$$Register, $src$$constant);
%}
ins_pipe(loadConL);
%}
instruct loadConL(iRegL dst, immL src) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 4); // worst case
format %{ "mov_slow $dst, $src\t! long" %}
ins_encode %{
// FIXME: use $constanttablebase?
__ mov_slow($dst$$Register, $src$$constant);
%}
ins_pipe(loadConL);
%}
#else
instruct loadConL(iRegL dst, immL src) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 4);
format %{ "MOV_SLOW $dst.lo, $src & 0x0FFFFFFFFL \t! long\n\t"
"MOV_SLOW $dst.hi, $src >> 32" %}
*** 5221,5231 ****
--- 4273,4282 ----
__ movw($dst$$Register, $src$$constant);
__ movw($dst$$Register->successor(), 0);
%}
ins_pipe(ialu_imm);
%}
#endif
instruct loadConF_imm8(regF dst, imm8F src) %{
match(Set dst src);
ins_cost(DEFAULT_COST);
size(4);
*** 5236,5264 ****
--- 4287,4296 ----
__ fconsts($dst$$FloatRegister, Assembler::float_num($src$$constant).imm8());
%}
ins_pipe(loadConFD); // FIXME
%}
#ifdef AARCH64
instruct loadIConF(iRegI dst, immF src) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 2);
format %{ "MOV_SLOW $dst, $src\t! loadIConF" %}
ins_encode %{
// FIXME revisit once 6961697 is in
union {
jfloat f;
int i;
} v;
v.f = $src$$constant;
__ mov_slow($dst$$Register, v.i);
%}
ins_pipe(ialu_imm);
%}
#endif
instruct loadConF(regF dst, immF src, iRegI tmp) %{
match(Set dst src);
ins_cost(DEFAULT_COST * 2);
effect(TEMP tmp);
*** 5322,5336 ****
--- 4354,4364 ----
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "PLDW $mem\t! Prefetch allocation" %}
ins_encode %{
#ifdef AARCH64
__ prfm(pstl1keep, $mem$$Address);
#else
__ pldw($mem$$Address);
#endif
%}
ins_pipe(iload_mem);
%}
instruct prefetchAlloc_sp( memoryP mem ) %{
*** 5339,5353 ****
--- 4367,4377 ----
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "PLD $mem\t! Prefetch allocation" %}
ins_encode %{
#ifdef AARCH64
__ prfm(pstl1keep, $mem$$Address);
#else
__ pld($mem$$Address);
#endif
%}
ins_pipe(iload_mem);
%}
//----------Store Instructions-------------------------------------------------
*** 5376,5403 ****
--- 4400,4409 ----
ins_pipe(istore_mem_reg);
%}
// Store Char/Short
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storeCoff(store_RegI src, memoryScaledS mem, aimmX off, iRegP tmp) %{
match(Set mem (StoreC (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "STRH $src,$mem+$off\t! short temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ strh($src$$Register, nmem);
%}
ins_pipe(istore_mem_reg);
%}
#endif
instruct storeC(memoryS mem, store_RegI src) %{
match(Set mem (StoreC mem src));
ins_cost(MEMORY_REF_COST);
*** 5409,5436 ****
--- 4415,4424 ----
ins_pipe(istore_mem_reg);
%}
// Store Integer
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storeIoff(store_RegI src, memoryScaledI mem, aimmX off, iRegP tmp) %{
match(Set mem (StoreI (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "str_32 $src,$mem+$off\t! int temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ str_32($src$$Register, nmem);
%}
ins_pipe(istore_mem_reg);
%}
#endif
instruct storeI(memoryI mem, store_RegI src) %{
match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST);
*** 5442,5476 ****
--- 4430,4442 ----
ins_pipe(istore_mem_reg);
%}
// Store Long
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storeLoff(store_RegLd src, memoryScaledL mem, aimmX off, iRegP tmp) %{
match(Set mem (StoreL (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "str_64 $src,$mem+$off\t! long temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ str_64($src$$Register, nmem);
%}
ins_pipe(istore_mem_reg);
%}
#endif
instruct storeL(memoryL mem, store_RegLd src) %{
#ifdef AARCH64
// already atomic for Aarch64
#else
predicate(!((StoreLNode*)n)->require_atomic_access());
#endif
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "str_64 $src,$mem\t! long\n\t" %}
*** 5479,5489 ****
--- 4445,4454 ----
__ str_64($src$$Register, $mem$$Address);
%}
ins_pipe(istore_mem_reg);
%}
#ifndef AARCH64
instruct storeL_2instr(memorylong mem, iRegL src) %{
predicate(!((StoreLNode*)n)->require_atomic_access());
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST);
*** 5512,5524 ****
--- 4477,4487 ----
set = set | reg_to_register_object($src$$reg + 1);
__ stmia(reg_to_register_object($mem$$base), set);
%}
ins_pipe(istore_mem_reg);
%}
#endif // !AARCH64
#ifndef AARCH64
instruct storeL_volatile_fp(memoryD mem, iRegL src) %{
predicate(((StoreLNode*)n)->require_atomic_access());
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST);
size(8);
*** 5528,5538 ****
--- 4491,4500 ----
__ fmdrr(S14, $src$$Register, $src$$Register->successor());
__ fstd(S14, $mem$$Address);
%}
ins_pipe(istore_mem_reg);
%}
#endif
#ifdef XXX
// Move SP Pointer
//instruct movSP(sp_ptr_RegP dst, SPRegP src) %{
//instruct movSP(iRegP dst, SPRegP src) %{
*** 5550,5659 ****
--- 4512,4541 ----
%}
ins_pipe(ialu_reg);
%}
#endif
#ifdef AARCH64
// FIXME
// Store SP Pointer
instruct storeSP(memoryP mem, SPRegP src, iRegP tmp) %{
match(Set mem (StoreP mem src));
predicate(_kids[1]->_leaf->is_Proj() && _kids[1]->_leaf->as_Proj()->_con == TypeFunc::FramePtr);
// Multiple StoreP rules, different only in register mask.
// Matcher makes the last always valid. The others will
// only be valid if they cost less than the last valid
// rule. So cost(rule1) < cost(rule2) < cost(last)
// Unlike immediates, register constraints are not checked
// at match time.
ins_cost(MEMORY_REF_COST+DEFAULT_COST+4);
effect(TEMP tmp);
size(8);
format %{ "MOV $tmp,$src\t! SP ptr\n\t"
"STR $tmp,$mem\t! SP ptr" %}
ins_encode %{
assert($src$$Register == SP, "SP expected");
__ mov($tmp$$Register, $src$$Register);
__ str($tmp$$Register, $mem$$Address);
%}
ins_pipe(istore_mem_spORreg); // FIXME
%}
#endif // AARCH64
// Store Pointer
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storePoff(store_ptr_RegP src, memoryScaledP mem, aimmX off, iRegP tmp) %{
predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
match(Set mem (StoreP (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "STR $src,$mem+$off\t! ptr temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ str($src$$Register, nmem);
%}
ins_pipe(istore_mem_reg);
%}
#endif
instruct storeP(memoryP mem, store_ptr_RegP src) %{
match(Set mem (StoreP mem src));
#ifdef AARCH64
predicate(!_kids[1]->_leaf->is_Proj() || _kids[1]->_leaf->as_Proj()->_con != TypeFunc::FramePtr);
#endif
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STR $src,$mem\t! ptr" %}
ins_encode %{
__ str($src$$Register, $mem$$Address);
%}
ins_pipe(istore_mem_spORreg);
%}
#ifdef AARCH64
// Store NULL Pointer
instruct storeP0(memoryP mem, immP0 src) %{
match(Set mem (StoreP mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STR ZR,$mem\t! ptr" %}
ins_encode %{
__ str(ZR, $mem$$Address);
%}
ins_pipe(istore_mem_spORreg);
%}
#endif // AARCH64
#ifdef _LP64
// Store Compressed Pointer
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storeNoff(store_RegN src, memoryScaledI mem, aimmX off, iRegP tmp) %{
match(Set mem (StoreN (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "str_32 $src,$mem+$off\t! compressed ptr temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ str_32($src$$Register, nmem);
%}
ins_pipe(istore_mem_reg);
%}
#endif
instruct storeN(memoryI mem, store_RegN src) %{
match(Set mem (StoreN mem src));
ins_cost(MEMORY_REF_COST);
size(4);
*** 5663,5686 ****
--- 4545,4554 ----
__ str_32($src$$Register, $mem$$Address);
%}
ins_pipe(istore_mem_reg);
%}
#ifdef AARCH64
// Store NULL Pointer
instruct storeN0(memoryI mem, immN0 src) %{
match(Set mem (StoreN mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "str_32 ZR,$mem\t! compressed ptr" %}
ins_encode %{
__ str_32(ZR, $mem$$Address);
%}
ins_pipe(istore_mem_reg);
%}
#endif
// Store Compressed Klass Pointer
instruct storeNKlass(memoryI mem, store_RegN src) %{
match(Set mem (StoreNKlass mem src));
ins_cost(MEMORY_REF_COST);
*** 5694,5721 ****
--- 4562,4571 ----
%}
#endif
// Store Double
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storeDoff(regD src, memoryScaledD mem, aimmX off, iRegP tmp) %{
match(Set mem (StoreD (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "STR $src,$mem+$off\t! double temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ str_d($src$$FloatRegister, nmem);
%}
ins_pipe(fstoreD_mem_reg);
%}
#endif
instruct storeD(memoryD mem, regD src) %{
match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST);
*** 5727,5780 ****
--- 4577,4589 ----
__ str_double($src$$FloatRegister, $mem$$Address);
%}
ins_pipe(fstoreD_mem_reg);
%}
#ifdef AARCH64
instruct movI2F(regF dst, iRegI src) %{
match(Set dst src);
size(4);
format %{ "FMOV_sw $dst,$src\t! movI2F" %}
ins_encode %{
__ fmov_sw($dst$$FloatRegister, $src$$Register);
%}
ins_pipe(ialu_reg); // FIXME
%}
instruct movF2I(iRegI dst, regF src) %{
match(Set dst src);
size(4);
format %{ "FMOV_ws $dst,$src\t! movF2I" %}
ins_encode %{
__ fmov_ws($dst$$Register, $src$$FloatRegister);
%}
ins_pipe(ialu_reg); // FIXME
%}
#endif
// Store Float
#ifdef AARCH64
// XXX This variant shouldn't be necessary if 6217251 is implemented
instruct storeFoff(regF src, memoryScaledF mem, aimmX off, iRegP tmp) %{
match(Set mem (StoreF (AddP mem off) src));
ins_cost(MEMORY_REF_COST + DEFAULT_COST); // assume shift/sign-extend is free
effect(TEMP tmp);
size(4 * 2);
format %{ "str_s $src,$mem+$off\t! float temp=$tmp" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
__ add($tmp$$Register, base, $off$$constant);
Address nmem = Address::make_raw($tmp$$reg, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none);
__ str_s($src$$FloatRegister, nmem);
%}
ins_pipe(fstoreF_mem_reg);
%}
#endif
instruct storeF( memoryF mem, regF src) %{
match(Set mem (StoreF mem src));
ins_cost(MEMORY_REF_COST);
*** 5784,5862 ****
--- 4593,4606 ----
__ str_float($src$$FloatRegister, $mem$$Address);
%}
ins_pipe(fstoreF_mem_reg);
%}
#ifdef AARCH64
// Convert oop pointer into compressed form
instruct encodeHeapOop(iRegN dst, iRegP src, flagsReg ccr) %{
predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
match(Set dst (EncodeP src));
effect(KILL ccr);
format %{ "encode_heap_oop $dst, $src" %}
ins_encode %{
__ encode_heap_oop($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
match(Set dst (EncodeP src));
format %{ "encode_heap_oop_not_null $dst, $src" %}
ins_encode %{
__ encode_heap_oop_not_null($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct decodeHeapOop(iRegP dst, iRegN src, flagsReg ccr) %{
predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
match(Set dst (DecodeN src));
effect(KILL ccr);
format %{ "decode_heap_oop $dst, $src" %}
ins_encode %{
__ decode_heap_oop($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
match(Set dst (DecodeN src));
format %{ "decode_heap_oop_not_null $dst, $src" %}
ins_encode %{
__ decode_heap_oop_not_null($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct encodeKlass_not_null(iRegN dst, iRegP src) %{
match(Set dst (EncodePKlass src));
format %{ "encode_klass_not_null $dst, $src" %}
ins_encode %{
__ encode_klass_not_null($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
instruct decodeKlass_not_null(iRegP dst, iRegN src) %{
match(Set dst (DecodeNKlass src));
format %{ "decode_klass_not_null $dst, $src" %}
ins_encode %{
__ decode_klass_not_null($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
#endif // AARCH64
//----------MemBar Instructions-----------------------------------------------
// Memory barrier flavors
// TODO: take advantage of Aarch64 load-acquire, store-release, etc
// pattern-match out unnecessary membars
instruct membar_storestore() %{
match(MemBarStoreStore);
ins_cost(4*MEMORY_REF_COST);
*** 5948,6004 ****
--- 4692,4701 ----
// match(Set dst (RoundFloat dst));
// ins_pipe(empty);
// %}
#ifdef AARCH64
// 0 constant in register
instruct zrImmI0(ZRRegI dst, immI0 imm) %{
match(Set dst imm);
size(0);
ins_cost(0);
format %{ "! ZR (int 0)" %}
ins_encode( /*empty encoding*/ );
ins_pipe(ialu_none);
%}
// 0 constant in register
instruct zrImmL0(ZRRegL dst, immL0 imm) %{
match(Set dst imm);
size(0);
ins_cost(0);
format %{ "! ZR (long 0)" %}
ins_encode( /*empty encoding*/ );
ins_pipe(ialu_none);
%}
#ifdef XXX
// 0 constant in register
instruct zrImmN0(ZRRegN dst, immN0 imm) %{
match(Set dst imm);
size(0);
ins_cost(0);
format %{ "! ZR (compressed pointer NULL)" %}
ins_encode( /*empty encoding*/ );
ins_pipe(ialu_none);
%}
// 0 constant in register
instruct zrImmP0(ZRRegP dst, immP0 imm) %{
match(Set dst imm);
size(0);
ins_cost(0);
format %{ "! ZR (NULL)" %}
ins_encode( /*empty encoding*/ );
ins_pipe(ialu_none);
%}
#endif
#endif // AARCH64
// Cast Index to Pointer for unsafe natives
instruct castX2P(iRegX src, iRegP dst) %{
match(Set dst (CastX2P src));
*** 6022,6032 ****
--- 4719,4728 ----
}
%}
ins_pipe(ialu_reg);
%}
#ifndef AARCH64
//----------Conditional Move---------------------------------------------------
// Conditional move
instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
ins_cost(150);
*** 6035,6225 ****
--- 4731,4742 ----
ins_encode %{
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#endif
#ifdef AARCH64
instruct cmovI_reg3(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovL_reg3(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovP_reg3(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src1, iRegP src2) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovN_reg3(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src1, iRegN src2) %{
match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovIP_reg3(cmpOpP cmp, flagsRegP icc, iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovLP_reg3(cmpOpP cmp, flagsRegP icc, iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovPP_reg3(cmpOpP cmp, flagsRegP icc, iRegP dst, iRegP src1, iRegP src2) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovNP_reg3(cmpOpP cmp, flagsRegP icc, iRegN dst, iRegN src1, iRegN src2) %{
match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovIU_reg3(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovLU_reg3(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovPU_reg3(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src1, iRegP src2) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovNU_reg3(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src1, iRegN src2) %{
match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovIZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! int" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovLZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (CMoveL (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! long" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovPZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, iRegP src1, iRegP src2) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
instruct cmovNZ_reg3(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegN dst, iRegN src1, iRegN src2) %{
match(Set dst (CMoveN (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "CSEL $dst,$src1,$src2,$cmp\t! compressed ptr" %}
ins_encode %{
__ csel($dst$$Register, $src1$$Register, $src2$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#endif // AARCH64
#ifndef AARCH64
instruct cmovIP_immMov(cmpOpP cmp, flagsRegP pcc, iRegI dst, immIMov src) %{
match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src)));
ins_cost(140);
size(4);
format %{ "MOV$cmp $dst,$src" %}
*** 6237,6247 ****
--- 4754,4763 ----
ins_encode %{
__ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_imm);
%}
#endif
instruct cmovI_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
*** 6250,6273 ****
--- 4766,4776 ----
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#ifdef AARCH64
instruct cmovL_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{
match(Set dst (CMoveL (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
format %{ "MOV$cmp $dst,$src\t! long" %}
ins_encode %{
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#endif
#ifndef AARCH64
instruct cmovI_immMov(cmpOp cmp, flagsReg icc, iRegI dst, immIMov src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);
format %{ "MOV$cmp $dst,$src" %}
*** 6285,6295 ****
--- 4788,4797 ----
ins_encode %{
__ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_imm);
%}
#endif
instruct cmovII_reg_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
*** 6302,6312 ****
--- 4804,4813 ----
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#ifndef AARCH64
instruct cmovII_immMov_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegI dst, immIMov src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
*** 6332,6342 ****
--- 4833,4842 ----
ins_encode %{
__ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_imm);
%}
#endif
instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
*** 6345,6355 ****
--- 4845,4854 ----
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#ifndef AARCH64
instruct cmovIIu_immMov(cmpOpU cmp, flagsRegU icc, iRegI dst, immIMov src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);
format %{ "MOV$cmp $dst,$src" %}
*** 6367,6377 ****
--- 4866,4875 ----
ins_encode %{
__ movw($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_imm);
%}
#endif
// Conditional move
instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
ins_cost(150);
*** 6385,6405 ****
--- 4883,4895 ----
instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
ins_cost(140);
size(4);
#ifdef AARCH64
format %{ "MOV$cmp $dst,ZR" %}
#else
format %{ "MOV$cmp $dst,$src" %}
#endif
ins_encode %{
#ifdef AARCH64
__ mov($dst$$Register, ZR, (AsmCondition)($cmp$$cmpcode));
#else
__ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
#endif
%}
ins_pipe(ialu_imm);
%}
// This instruction also works with CmpN so we don't need cmovPN_reg.
*** 6442,6605 ****
--- 4932,4980 ----
%}
ins_pipe(ialu_reg);
%}
instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);
#ifdef AARCH64
format %{ "MOV$cmp $dst,ZR\t! ptr" %}
#else
format %{ "MOV$cmp $dst,$src\t! ptr" %}
#endif
ins_encode %{
#ifdef AARCH64
__ mov($dst$$Register, ZR, (AsmCondition)($cmp$$cmpcode));
#else
__ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
#endif
%}
ins_pipe(ialu_imm);
%}
instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
ins_cost(140);
size(4);
#ifdef AARCH64
format %{ "MOV$cmp $dst,ZR\t! ptr" %}
#else
format %{ "MOV$cmp $dst,$src\t! ptr" %}
#endif
ins_encode %{
#ifdef AARCH64
__ mov($dst$$Register, ZR, (AsmCondition)($cmp$$cmpcode));
#else
__ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
#endif
%}
ins_pipe(ialu_imm);
%}
instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);
#ifdef AARCH64
format %{ "MOV$cmp $dst,ZR\t! ptr" %}
#else
format %{ "MOV$cmp $dst,$src\t! ptr" %}
#endif
ins_encode %{
#ifdef AARCH64
__ mov($dst$$Register, ZR, (AsmCondition)($cmp$$cmpcode));
#else
__ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
#endif
%}
ins_pipe(ialu_imm);
%}
#ifdef AARCH64
// Conditional move
instruct cmovF_reg(cmpOp cmp, flagsReg icc, regF dst, regF src1, regF src2) %{
match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
ins_encode %{
__ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(int_conditional_float_move);
%}
instruct cmovD_reg(cmpOp cmp, flagsReg icc, regD dst, regD src1, regD src2) %{
match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
ins_encode %{
__ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(int_conditional_float_move);
%}
instruct cmovFP_reg(cmpOpP cmp, flagsRegP icc, regF dst, regF src1, regF src2) %{
match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
ins_encode %{
__ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(int_conditional_float_move);
%}
instruct cmovDP_reg(cmpOpP cmp, flagsRegP icc, regD dst, regD src1, regD src2) %{
match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
ins_encode %{
__ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(int_conditional_float_move);
%}
instruct cmovFU_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src1, regF src2) %{
match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
ins_encode %{
__ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(int_conditional_float_move);
%}
+ match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
+ ins_cost(140);
instruct cmovDU_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src1, regD src2) %{
match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
size(4);
! format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
! format %{ "MOV$cmp $dst,$src\t! ptr" %}
ins_encode %{
! __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
! __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
! ins_pipe(int_conditional_float_move);
! ins_pipe(ialu_imm);
%}
! instruct cmovFZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regF dst, regF src1, regF src2) %{
! match(Set dst (CMoveF (Binary cmp icc) (Binary src2 src1)));
ins_cost(150);
! instruct cmovPI_imm_EQNELTGE(cmpOp0 cmp, flagsReg_EQNELTGE icc, iRegP dst, immP0 src) %{
! match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
+ predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
+ _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ||
+ _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt ||
+ _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge);
+ ins_cost(140);
+
size(4);
! format %{ "FCSEL_s $dst,$src1,$src2,$cmp" %}
! format %{ "MOV$cmp $dst,$src\t! ptr" %}
ins_encode %{
! __ fcsel_s($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
! __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
! ins_pipe(int_conditional_float_move);
! ins_pipe(ialu_imm);
%}
! instruct cmovDZ_reg(cmpOp0 cmp, flagsReg_EQNELTGE icc, regD dst, regD src1, regD src2) %{
! match(Set dst (CMoveD (Binary cmp icc) (Binary src2 src1)));
! ins_cost(150);
! instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{
! match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
! ins_cost(140);
+
size(4);
! format %{ "FCSEL_d $dst,$src1,$src2,$cmp" %}
! format %{ "MOV$cmp $dst,$src\t! ptr" %}
ins_encode %{
! __ fcsel_d($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
! __ mov($dst$$Register, $src$$constant, (AsmCondition)($cmp$$cmpcode));
%}
! ins_pipe(int_conditional_float_move);
! ins_pipe(ialu_imm);
%}
#else // !AARCH64
// Conditional move
instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{
match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src)));
ins_cost(150);
*** 6856,6866 ****
--- 5231,5240 ----
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
__ mov($dst$$Register->successor(), $src$$Register->successor(), (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#endif // !AARCH64
//----------OS and Locking Instructions----------------------------------------
// This name is KNOWN by the ADLC and cannot be changed.
*** 6913,6949 ****
--- 5287,5307 ----
__ add_32($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct addshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (AddI (LShiftI src1 src2) src3));
size(4);
format %{ "add_32 $dst,$src3,$src1<<$src2\t! int" %}
ins_encode %{
__ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
#ifdef AARCH64
#ifdef TODO
instruct addshlL_reg_imm_reg(iRegL dst, iRegL src1, immU6 src2, iRegL src3) %{
match(Set dst (AddL (LShiftL src1 src2) src3));
size(4);
format %{ "ADD $dst,$src3,$src1<<$src2\t! long" %}
ins_encode %{
__ add($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
#endif
instruct addshlI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
match(Set dst (AddI (LShiftI src1 src2) src3));
size(4);
*** 6952,6973 ****
--- 5310,5329 ----
__ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct addsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (AddI (RShiftI src1 src2) src3));
size(4);
format %{ "add_32 $dst,$src3,$src1>>$src2\t! int" %}
ins_encode %{
__ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct addsarI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
match(Set dst (AddI (RShiftI src1 src2) src3));
size(4);
*** 6976,6997 ****
--- 5332,5351 ----
__ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct addshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (AddI (URShiftI src1 src2) src3));
size(4);
format %{ "add_32 $dst,$src3,$src1>>>$src2\t! int" %}
ins_encode %{
__ add_32($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct addshrI_reg_imm_reg(iRegI dst, iRegI src1, immU5 src2, iRegI src3) %{
match(Set dst (AddI (URShiftI src1 src2) src3));
size(4);
*** 7024,7096 ****
--- 5378,5387 ----
__ add($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#ifdef AARCH64
// unshifted I2L operand
operand unshiftedI2L(iRegI src2) %{
//constraint(ALLOC_IN_RC(sp_ptr_reg));
match(ConvI2L src2);
op_cost(1);
format %{ "$src2.w" %}
interface(MEMORY_INTER) %{
base($src2);
index(0xff);
scale(0x0);
disp(0x0);
%}
%}
// shifted I2L operand
operand shiftedI2L(iRegI src2, immI_0_4 src3) %{
//constraint(ALLOC_IN_RC(sp_ptr_reg));
match(LShiftX (ConvI2L src2) src3);
op_cost(1);
format %{ "$src2.w << $src3" %}
interface(MEMORY_INTER) %{
base($src2);
index(0xff);
scale($src3);
disp(0x0);
%}
%}
opclass shiftedRegI(shiftedI2L, unshiftedI2L);
instruct shlL_reg_regI(iRegL dst, iRegI src1, immU6 src2) %{
match(Set dst (LShiftL (ConvI2L src1) src2));
size(4);
format %{ "LSL $dst,$src1.w,$src2\t! ptr" %}
ins_encode %{
int c = $src2$$constant;
int r = 64 - c;
int s = 31;
if (s >= r) {
s = r - 1;
}
__ sbfm($dst$$Register, $src1$$Register, r, s);
%}
ins_pipe(ialu_reg_reg);
%}
instruct addP_reg_regI(iRegP dst, iRegP src1, shiftedRegI src2) %{
match(Set dst (AddP src1 src2));
ins_cost(DEFAULT_COST * 3/2);
size(4);
format %{ "ADD $dst,$src1,$src2, sxtw\t! ptr" %}
ins_encode %{
Register base = reg_to_register_object($src2$$base);
__ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
%}
ins_pipe(ialu_reg_reg);
%}
#endif
// shifted iRegX operand
operand shiftedX(iRegX src2, shimmX src3) %{
//constraint(ALLOC_IN_RC(sp_ptr_reg));
match(LShiftX src2 src3);
*** 7129,7162 ****
--- 5420,5429 ----
%}
ins_pipe(ialu_reg_imm);
%}
// Long Addition
#ifdef AARCH64
instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (AddL src1 src2));
size(4);
format %{ "ADD $dst,$src1,$src2\t! long" %}
ins_encode %{
__ add($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
instruct addL_reg_regI(iRegL dst, iRegL src1, shiftedRegI src2) %{
match(Set dst (AddL src1 src2));
ins_cost(DEFAULT_COST * 3/2);
size(4);
format %{ "ADD $dst,$src1,$src2, sxtw\t! long" %}
ins_encode %{
Register base = reg_to_register_object($src2$$base);
__ add($dst$$Register, $src1$$Register, base, ex_sxtw, $src2$$scale);
%}
ins_pipe(ialu_reg_reg);
%}
#else
instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg ccr) %{
match(Set dst (AddL src1 src2));
effect(KILL ccr);
size(8);
format %{ "ADDS $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
*** 7165,7204 ****
--- 5432,5444 ----
__ adds($dst$$Register, $src1$$Register, $src2$$Register);
__ adc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
%}
ins_pipe(ialu_reg_reg);
%}
#endif
#ifdef AARCH64
// Immediate Addition
instruct addL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
match(Set dst (AddL src1 src2));
size(4);
format %{ "ADD $dst,$src1,$src2\t! long" %}
ins_encode %{
__ add($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
instruct addL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
match(Set dst (SubL src1 src2));
size(4);
format %{ "ADD $dst,$src1,-($src2)\t! long" %}
ins_encode %{
__ add($dst$$Register, $src1$$Register, -$src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
// TODO
#endif
#ifndef AARCH64
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct addL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg ccr) %{
match(Set dst (AddL src1 con));
effect(KILL ccr);
*** 7209,7238 ****
--- 5449,5471 ----
__ adds($dst$$Register, $src1$$Register, $con$$constant);
__ adc($dst$$Register->successor(), $src1$$Register->successor(), 0);
%}
ins_pipe(ialu_reg_imm);
%}
#endif
//----------Conditional_store--------------------------------------------------
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success.
// TODO: optimize out barriers with AArch64 load-acquire/store-release
// LoadP-locked.
instruct loadPLocked(iRegP dst, memoryex mem) %{
match(Set dst (LoadPLocked mem));
size(4);
format %{ "LDREX $dst,$mem" %}
ins_encode %{
#ifdef AARCH64
Register base = reg_to_register_object($mem$$base);
__ ldxr($dst$$Register, base);
#else
__ ldrex($dst$$Register,$mem$$Address);
#endif
%}
ins_pipe(iload_mem);
%}
instruct storePConditional( memoryex heap_top_ptr, iRegP oldval, iRegP newval, iRegI tmp, flagsRegP pcc ) %{
*** 7241,7277 ****
--- 5474,5491 ----
effect( TEMP tmp );
size(8);
format %{ "STREX $tmp,$newval,$heap_top_ptr\n\t"
"CMP $tmp, 0" %}
ins_encode %{
#ifdef AARCH64
Register base = reg_to_register_object($heap_top_ptr$$base);
__ stxr($tmp$$Register, $newval$$Register, base);
#else
__ strex($tmp$$Register, $newval$$Register, $heap_top_ptr$$Address);
#endif
__ cmp($tmp$$Register, 0);
%}
ins_pipe( long_memory_op );
%}
// Conditional-store of an intx value.
instruct storeXConditional( memoryex mem, iRegX oldval, iRegX newval, iRegX tmp, flagsReg icc ) %{
#ifdef AARCH64
match(Set icc (StoreLConditional mem (Binary oldval newval)));
effect( TEMP tmp );
size(28);
format %{ "loop:\n\t"
"LDXR $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
"SUBS $tmp, $tmp, $oldval\n\t"
"B.ne done\n\t"
"STXR $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop\n\t"
"CMP $tmp, 0\n\t"
"done:\n\t"
"membar LoadStore|LoadLoad" %}
#else
match(Set icc (StoreIConditional mem (Binary oldval newval)));
effect( TEMP tmp );
size(28);
format %{ "loop: \n\t"
"LDREX $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem], DOESN'T set $newval=[$mem] in any case\n\t"
*** 7279,7431 ****
--- 5493,5519 ----
"STREX.eq $tmp, $newval, $mem\n\t"
"CMP.eq $tmp, 1 \n\t"
"B.eq loop \n\t"
"TEQ $tmp, 0\n\t"
"membar LoadStore|LoadLoad" %}
#endif
ins_encode %{
Label loop;
__ bind(loop);
#ifdef AARCH64
// FIXME: use load-acquire/store-release, remove membar?
Label done;
Register base = reg_to_register_object($mem$$base);
__ ldxr($tmp$$Register, base);
__ subs($tmp$$Register, $tmp$$Register, $oldval$$Register);
__ b(done, ne);
__ stxr($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
__ cmp($tmp$$Register, 0);
__ bind(done);
#else
__ ldrex($tmp$$Register, $mem$$Address);
__ eors($tmp$$Register, $tmp$$Register, $oldval$$Register);
__ strex($tmp$$Register, $newval$$Register, $mem$$Address, eq);
__ cmp($tmp$$Register, 1, eq);
__ b(loop, eq);
__ teq($tmp$$Register, 0);
#endif
// used by biased locking only. Requires a membar.
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadStore | MacroAssembler::LoadLoad), noreg);
%}
ins_pipe( long_memory_op );
%}
// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
#ifdef AARCH64
// TODO: if combined with membar, elide membar and use
// load-acquire/store-release if appropriate
instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegL newval, iRegI res, iRegI tmp, flagsReg ccr) %{
match(Set res (CompareAndSwapL mem (Binary oldval newval)));
effect( KILL ccr, TEMP tmp);
size(24);
format %{ "loop:\n\t"
"LDXR $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
"CMP $tmp, $oldval\n\t"
"B.ne done\n\t"
"STXR $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop\n\t"
"done:\n\t"
"CSET_w $res, eq" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
Label loop, done;
__ bind(loop);
__ ldxr($tmp$$Register, base);
__ cmp($tmp$$Register, $oldval$$Register);
__ b(done, ne);
__ stxr($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
__ bind(done);
__ cset_w($res$$Register, eq);
%}
ins_pipe( long_memory_op );
%}
instruct compareAndSwapI_bool(memoryex mem, iRegI oldval, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
match(Set res (CompareAndSwapI mem (Binary oldval newval)));
effect( KILL ccr, TEMP tmp);
size(24);
format %{ "loop:\n\t"
"LDXR_w $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
"CMP_w $tmp, $oldval\n\t"
"B.ne done\n\t"
"STXR_w $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop\n\t"
"done:\n\t"
"CSET_w $res, eq" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
Label loop, done;
__ bind(loop);
__ ldxr_w($tmp$$Register, base);
__ cmp_w($tmp$$Register, $oldval$$Register);
__ b(done, ne);
__ stxr_w($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
__ bind(done);
__ cset_w($res$$Register, eq);
%}
ins_pipe( long_memory_op );
%}
// tmp must use iRegI instead of iRegN until 8051805 is fixed.
instruct compareAndSwapN_bool(memoryex mem, iRegN oldval, iRegN newval, iRegI res, iRegI tmp, flagsReg ccr) %{
match(Set res (CompareAndSwapN mem (Binary oldval newval)));
effect( KILL ccr, TEMP tmp);
size(24);
format %{ "loop:\n\t"
"LDXR_w $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
"CMP_w $tmp, $oldval\n\t"
"B.ne done\n\t"
"STXR_w $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop\n\t"
"done:\n\t"
"CSET_w $res, eq" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
Label loop, done;
__ bind(loop);
__ ldxr_w($tmp$$Register, base);
__ cmp_w($tmp$$Register, $oldval$$Register);
__ b(done, ne);
__ stxr_w($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
__ bind(done);
__ cset_w($res$$Register, eq);
%}
ins_pipe( long_memory_op );
%}
instruct compareAndSwapP_bool(memoryex mem, iRegP oldval, iRegP newval, iRegI res, iRegI tmp, flagsReg ccr) %{
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
effect( KILL ccr, TEMP tmp);
size(24);
format %{ "loop:\n\t"
"LDXR $tmp, $mem\t! If $oldval==[$mem] Then store $newval into [$mem]\n\t"
"CMP $tmp, $oldval\n\t"
"B.ne done\n\t"
"STXR $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop\n\t"
"done:\n\t"
"CSET_w $res, eq" %}
ins_encode %{
Register base = reg_to_register_object($mem$$base);
Label loop, done;
__ bind(loop);
__ ldxr($tmp$$Register, base);
__ cmp($tmp$$Register, $oldval$$Register);
__ b(done, ne);
__ stxr($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
__ bind(done);
__ cset_w($res$$Register, eq);
%}
ins_pipe( long_memory_op );
%}
#else // !AARCH64
instruct compareAndSwapL_bool(memoryex mem, iRegL oldval, iRegLd newval, iRegI res, iRegLd tmp, flagsReg ccr ) %{
match(Set res (CompareAndSwapL mem (Binary oldval newval)));
effect( KILL ccr, TEMP tmp);
size(32);
format %{ "loop: \n\t"
*** 7504,7539 ****
--- 5592,5602 ----
__ b(loop, eq);
__ mov($res$$Register, $tmp$$Register);
%}
ins_pipe( long_memory_op );
%}
#endif // !AARCH64
#ifdef AARCH64
instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add));
effect(TEMP tmp1, TEMP tmp2);
size(16);
format %{ "loop:\n\t"
"LDXR_w $tmp1, $mem\n\t"
"ADD_w $tmp1, $tmp1, $add\n\t"
"STXR_w $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr_w($tmp1$$Register, base);
__ add_w($tmp1$$Register, $tmp1$$Register, $add$$constant);
__ stxr_w($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xaddI_aimmI_no_res(memoryex mem, aimmI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add));
effect(KILL ccr, TEMP tmp1, TEMP tmp2);
size(20);
*** 7553,7588 ****
--- 5616,5626 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add));
effect(TEMP tmp1, TEMP tmp2);
size(16);
format %{ "loop:\n\t"
"LDXR_w $tmp1, $mem\n\t"
"ADD_w $tmp1, $tmp1, $add\n\t"
"STXR_w $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr_w($tmp1$$Register, base);
__ add_w($tmp1$$Register, $tmp1$$Register, $add$$Register);
__ stxr_w($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xaddI_reg_no_res(memoryex mem, iRegI add, Universe dummy, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add));
effect(KILL ccr, TEMP tmp1, TEMP tmp2);
size(20);
*** 7602,7636 ****
--- 5640,5650 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
match(Set res (GetAndAddI mem add));
effect(TEMP tmp1, TEMP tmp2, TEMP res);
size(16);
format %{ "loop:\n\t"
"LDXR_w $res, $mem\n\t"
"ADD_w $tmp1, $res, $add\n\t"
"STXR_w $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr_w($res$$Register, base);
__ add_w($tmp1$$Register, $res$$Register, $add$$constant);
__ stxr_w($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xaddI_aimmI(memoryex mem, aimmI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
match(Set res (GetAndAddI mem add));
effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
size(20);
format %{ "loop: \n\t"
*** 7649,7683 ****
--- 5663,5673 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2) %{
match(Set res (GetAndAddI mem add));
effect(TEMP tmp1, TEMP tmp2, TEMP res);
size(16);
format %{ "loop:\n\t"
"LDXR_w $res, $mem\n\t"
"ADD_w $tmp1, $res, $add\n\t"
"STXR_w $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr_w($res$$Register, base);
__ add_w($tmp1$$Register, $res$$Register, $add$$Register);
__ stxr_w($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xaddI_reg(memoryex mem, iRegI add, iRegI res, iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
match(Set res (GetAndAddI mem add));
effect(KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
size(20);
format %{ "loop: \n\t"
*** 7688,7731 ****
--- 5678,5696 ----
"B.ne loop \n\t" %}
ins_encode %{
Label loop;
__ bind(loop);
__ ldrex($res$$Register,$mem$$Address);
__ add($tmp1$$Register, $res$$Register, $add$$Register);
__ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddL mem add));
effect(TEMP tmp1, TEMP tmp2);
size(16);
format %{ "loop:\n\t"
"LDXR $tmp1, $mem\n\t"
"ADD $tmp1, $tmp1, $add\n\t"
"STXR $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr($tmp1$$Register, base);
__ add($tmp1$$Register, $tmp1$$Register, $add$$Register);
__ stxr($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
+ __ ldrex($res$$Register,$mem$$Address);
+ __ add($tmp1$$Register, $res$$Register, $add$$Register);
+ __ strex($tmp2$$Register, $tmp1$$Register, $mem$$Address);
+ __ cmp($tmp2$$Register, 0);
+ __ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#else
+
instruct xaddL_reg_no_res(memoryex mem, iRegL add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddL mem add));
effect( KILL ccr, TEMP tmp1, TEMP tmp2);
size(24);
*** 7747,7782 ****
--- 5712,5722 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddL_imm_no_res(memoryex mem, aimmL add, Universe dummy, iRegL tmp1, iRegI tmp2) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddL mem add));
effect(TEMP tmp1, TEMP tmp2);
size(16);
format %{ "loop:\n\t"
"LDXR $tmp1, $mem\n\t"
"ADD $tmp1, $tmp1, $add\n\t"
"STXR $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr($tmp1$$Register, base);
__ add($tmp1$$Register, $tmp1$$Register, $add$$constant);
__ stxr($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct xaddL_immRot_no_res(memoryex mem, immLlowRot add, Universe dummy, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddL mem add));
*** 7800,7834 ****
--- 5740,5750 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddL_reg(memoryex mem, iRegL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
match(Set res (GetAndAddL mem add));
effect(TEMP tmp1, TEMP tmp2, TEMP res);
size(16);
format %{ "loop:\n\t"
"LDXR $res, $mem\n\t"
"ADD $tmp1, $res, $add\n\t"
"STXR $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr($res$$Register, base);
__ add($tmp1$$Register, $res$$Register, $add$$Register);
__ stxr($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xaddL_reg(memoryex mem, iRegL add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
match(Set res (GetAndAddL mem add));
effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
size(24);
format %{ "loop: \n\t"
*** 7849,7883 ****
--- 5765,5775 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xaddL_imm(memoryex mem, aimmL add, iRegL res, iRegL tmp1, iRegI tmp2) %{
match(Set res (GetAndAddL mem add));
effect(TEMP tmp1, TEMP tmp2, TEMP res);
size(16);
format %{ "loop:\n\t"
"LDXR $res, $mem\n\t"
"ADD $tmp1, $res, $add\n\t"
"STXR $tmp2, $tmp1, $mem\n\t"
"CBNZ_w $tmp2, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr($res$$Register, base);
__ add($tmp1$$Register, $res$$Register, $add$$constant);
__ stxr($tmp2$$Register, $tmp1$$Register, base);
__ cbnz_w($tmp2$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct xaddL_immRot(memoryex mem, immLlowRot add, iRegLd res, iRegLd tmp1, iRegI tmp2, flagsReg ccr) %{
match(Set res (GetAndAddL mem add));
effect( KILL ccr, TEMP tmp1, TEMP tmp2, TEMP res);
*** 7900,7955 ****
--- 5792,5802 ----
__ cmp($tmp2$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp) %{
match(Set res (GetAndSetI mem newval));
effect(TEMP tmp, TEMP res);
size(12);
format %{ "loop:\n\t"
"LDXR_w $res, $mem\n\t"
"STXR_w $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr_w($res$$Register, base);
__ stxr_w($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#ifdef XXX
// Disabled until 8051805 is fixed.
instruct xchgN(memoryex mem, iRegN newval, iRegN res, iRegN tmp) %{
match(Set res (GetAndSetN mem newval));
effect(TEMP tmp, TEMP res);
size(12);
format %{ "loop:\n\t"
"LDXR_w $res, $mem\n\t"
"STXR_w $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr_w($res$$Register, base);
__ stxr_w($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#endif
#else
instruct xchgI(memoryex mem, iRegI newval, iRegI res, iRegI tmp, flagsReg ccr) %{
match(Set res (GetAndSetI mem newval));
effect(KILL ccr, TEMP tmp, TEMP res);
size(16);
format %{ "loop: \n\t"
*** 7966,7998 ****
--- 5813,5823 ----
__ cmp($tmp$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif
#ifdef AARCH64
instruct xchgL(memoryex mem, iRegL newval, iRegL res, iRegI tmp) %{
match(Set res (GetAndSetL mem newval));
effect(TEMP tmp, TEMP res);
size(12);
format %{ "loop:\n\t"
"LDXR $res, $mem\n\t"
"STXR $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldxr($res$$Register, base);
__ stxr($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xchgL(memoryex mem, iRegLd newval, iRegLd res, iRegI tmp, flagsReg ccr) %{
match(Set res (GetAndSetL mem newval));
effect( KILL ccr, TEMP tmp, TEMP res);
size(16);
format %{ "loop: \n\t"
*** 8009,8041 ****
--- 5834,5844 ----
__ cmp($tmp$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif // !AARCH64
#ifdef AARCH64
instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp) %{
match(Set res (GetAndSetP mem newval));
effect(TEMP tmp, TEMP res);
size(12);
format %{ "loop:\n\t"
"LDREX $res, $mem\n\t"
"STREX $tmp, $newval, $mem\n\t"
"CBNZ_w $tmp, loop" %}
ins_encode %{
Label loop;
Register base = reg_to_register_object($mem$$base);
__ bind(loop);
__ ldrex($res$$Register, base);
__ strex($tmp$$Register, $newval$$Register, base);
__ cbnz_w($tmp$$Register, loop);
%}
ins_pipe( long_memory_op );
%}
#else
instruct xchgP(memoryex mem, iRegP newval, iRegP res, iRegI tmp, flagsReg ccr) %{
match(Set res (GetAndSetP mem newval));
effect(KILL ccr, TEMP tmp, TEMP res);
size(16);
format %{ "loop: \n\t"
*** 8052,8062 ****
--- 5855,5864 ----
__ cmp($tmp$$Register, 0);
__ b(loop, ne);
%}
ins_pipe( long_memory_op );
%}
#endif // !AARCH64
//---------------------
// Subtraction Instructions
// Register Subtraction
instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
*** 8068,8089 ****
--- 5870,5889 ----
__ sub_32($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct subshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (SubI src1 (LShiftI src2 src3)));
size(4);
format %{ "SUB $dst,$src1,$src2<<$src3" %}
ins_encode %{
__ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct subshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (SubI src1 (LShiftI src2 src3)));
size(4);
*** 8092,8113 ****
--- 5892,5911 ----
__ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct subsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (SubI src1 (RShiftI src2 src3)));
size(4);
format %{ "SUB $dst,$src1,$src2>>$src3" %}
ins_encode %{
__ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct subsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (SubI src1 (RShiftI src2 src3)));
size(4);
*** 8116,8137 ****
--- 5914,5933 ----
__ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct subshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (SubI src1 (URShiftI src2 src3)));
size(4);
format %{ "SUB $dst,$src1,$src2>>>$src3" %}
ins_encode %{
__ sub($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct subshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (SubI src1 (URShiftI src2 src3)));
size(4);
*** 8140,8150 ****
--- 5936,5945 ----
__ sub_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct rsbshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (SubI (LShiftI src1 src2) src3));
size(4);
format %{ "RSB $dst,$src3,$src1<<$src2" %}
*** 8206,8216 ****
--- 6001,6010 ----
ins_encode %{
__ rsb($dst$$Register, $src3$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
// Immediate Subtraction
instruct subI_reg_aimmI(iRegI dst, iRegI src1, aimmI src2) %{
match(Set dst (SubI src1 src2));
*** 8231,8266 ****
--- 6025,6046 ----
__ sub_32($dst$$Register, $src1$$Register, -$src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#ifndef AARCH64
instruct subI_immRot_reg(iRegI dst, immIRot src1, iRegI src2) %{
match(Set dst (SubI src1 src2));
size(4);
format %{ "RSB $dst,$src2,src1" %}
ins_encode %{
__ rsb($dst$$Register, $src2$$Register, $src1$$constant);
%}
ins_pipe(ialu_zero_reg);
%}
#endif
// Register Subtraction
#ifdef AARCH64
instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (SubL src1 src2));
size(4);
format %{ "SUB $dst,$src1,$src2\t! long" %}
ins_encode %{
__ sub($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#else
instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2, flagsReg icc ) %{
match(Set dst (SubL src1 src2));
effect (KILL icc);
size(8);
*** 8270,8309 ****
--- 6050,6062 ----
__ subs($dst$$Register, $src1$$Register, $src2$$Register);
__ sbc($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
%}
ins_pipe(ialu_reg_reg);
%}
#endif
#ifdef AARCH64
// Immediate Subtraction
instruct subL_reg_aimm(iRegL dst, iRegL src1, aimmL src2) %{
match(Set dst (SubL src1 src2));
size(4);
format %{ "SUB $dst,$src1,$src2\t! long" %}
ins_encode %{
__ sub($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
instruct subL_reg_immLneg(iRegL dst, iRegL src1, aimmLneg src2) %{
match(Set dst (AddL src1 src2));
size(4);
format %{ "SUB $dst,$src1,-($src2)\t! long" %}
ins_encode %{
__ sub($dst$$Register, $src1$$Register, -$src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
// TODO
#endif
#ifndef AARCH64
// Immediate Subtraction
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct subL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con, flagsReg icc) %{
match(Set dst (SubL src1 con));
*** 8331,8341 ****
--- 6084,6093 ----
__ rsbs($dst$$Register, $src2$$Register, 0);
__ rsc($dst$$Register->successor(), $src2$$Register->successor(), 0);
%}
ins_pipe(ialu_zero_reg);
%}
#endif // !AARCH64
// Multiplication Instructions
// Integer Multiplication
// Register Multiplication
instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
*** 8347,8367 ****
--- 6099,6108 ----
__ mul_32($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(imul_reg_reg);
%}
#ifdef AARCH64
instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (MulL src1 src2));
size(4);
format %{ "MUL $dst,$src1,$src2\t! long" %}
ins_encode %{
__ mul($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(imul_reg_reg);
%}
#else
instruct mulL_lo1_hi2(iRegL dst, iRegL src1, iRegL src2) %{
effect(DEF dst, USE src1, USE src2);
size(4);
format %{ "MUL $dst.hi,$src1.lo,$src2.hi\t! long" %}
ins_encode %{
*** 8399,8424 ****
--- 6140,6152 ----
mulL_lo1_hi2(dst, src1, src2);
mulL_hi1_lo2(dst, src1, src2);
mulL_lo1_lo2(dst, src1, src2);
%}
%}
#endif // !AARCH64
// Integer Division
// Register Division
#ifdef AARCH64
instruct divI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (DivI src1 src2));
size(4);
format %{ "SDIV $dst,$src1,$src2\t! 32-bit" %}
ins_encode %{
__ sdiv_w($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg); // FIXME
%}
#else
instruct divI_reg_reg(R1RegI dst, R0RegI src1, R2RegI src2, LRRegP lr, flagsReg ccr) %{
match(Set dst (DivI src1 src2));
effect( KILL ccr, KILL src1, KILL src2, KILL lr);
ins_cost((2+71)*DEFAULT_COST);
*** 8426,8450 ****
--- 6154,6165 ----
ins_encode %{
__ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
%}
ins_pipe(sdiv_reg_reg);
%}
#endif
// Register Long Division
#ifdef AARCH64
instruct divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (DivL src1 src2));
size(4);
format %{ "SDIV $dst,$src1,$src2" %}
ins_encode %{
__ sdiv($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg); // FIXME
%}
#else
instruct divL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
match(Set dst (DivL src1 src2));
effect(CALL);
ins_cost(DEFAULT_COST*71);
format %{ "DIVL $src1,$src2,$dst\t! long ! call to SharedRuntime::ldiv" %}
*** 8452,8521 ****
--- 6167,6191 ----
address target = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
__ call(target, relocInfo::runtime_call_type);
%}
ins_pipe(divL_reg_reg);
%}
#endif
// Integer Remainder
// Register Remainder
#ifdef AARCH64
#ifdef TODO
instruct msubI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (SubI src1 (MulI src2 src3)));
size(4);
format %{ "MSUB $dst,$src2,$src3,$src1\t! 32-bit\n\t" %}
ins_encode %{
__ msub_w($dst$$Register, $src2$$Register, $src3$$Register, $src1$$Register);
%}
ins_pipe(ialu_reg_reg); // FIXME
%}
#endif
instruct modI_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp) %{
match(Set dst (ModI src1 src2));
effect(TEMP temp);
size(8);
format %{ "SDIV $temp,$src1,$src2\t! 32-bit\n\t"
"MSUB $dst,$src2,$temp,$src1\t! 32-bit\n\t" %}
ins_encode %{
__ sdiv_w($temp$$Register, $src1$$Register, $src2$$Register);
__ msub_w($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
%}
ins_pipe(ialu_reg_reg); // FIXME
%}
#else
instruct modI_reg_reg(R0RegI dst, R0RegI src1, R2RegI src2, R1RegI temp, LRRegP lr, flagsReg ccr ) %{
match(Set dst (ModI src1 src2));
effect( KILL ccr, KILL temp, KILL src2, KILL lr);
format %{ "MODI $dst,$src1,$src2\t ! call to StubRoutines::Arm::idiv_irem_entry" %}
ins_encode %{
__ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);
%}
ins_pipe(sdiv_reg_reg);
%}
#endif
// Register Long Remainder
#ifdef AARCH64
instruct modL_reg_reg(iRegL dst, iRegL src1, iRegL src2, iRegL temp) %{
match(Set dst (ModL src1 src2));
effect(TEMP temp);
size(8);
format %{ "SDIV $temp,$src1,$src2\n\t"
"MSUB $dst,$src2,$temp,$src1" %}
ins_encode %{
__ sdiv($temp$$Register, $src1$$Register, $src2$$Register);
__ msub($dst$$Register, $src2$$Register, $temp$$Register, $src1$$Register);
%}
ins_pipe(ialu_reg_reg); // FIXME
%}
#else
instruct modL_reg_reg(R0R1RegL dst, R2R3RegL src1, R0R1RegL src2) %{
match(Set dst (ModL src1 src2));
effect(CALL);
ins_cost(MEMORY_REF_COST); // FIXME
format %{ "modL $dst,$src1,$src2\t ! call to SharedRuntime::lrem" %}
*** 8523,8575 ****
--- 6193,6229 ----
address target = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
__ call(target, relocInfo::runtime_call_type);
%}
ins_pipe(divL_reg_reg);
%}
#endif
// Integer Shift Instructions
// Register Shift Left
instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (LShiftI src1 src2));
size(4);
#ifdef AARCH64
format %{ "LSLV $dst,$src1,$src2\t! int" %}
ins_encode %{
__ lslv_w($dst$$Register, $src1$$Register, $src2$$Register);
%}
#else
format %{ "LSL $dst,$src1,$src2 \n\t" %}
ins_encode %{
__ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$Register));
%}
#endif
ins_pipe(ialu_reg_reg);
%}
// Register Shift Left Immediate
instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
match(Set dst (LShiftI src1 src2));
size(4);
#ifdef AARCH64
format %{ "LSL_w $dst,$src1,$src2\t! int" %}
ins_encode %{
__ _lsl($dst$$Register, $src1$$Register, $src2$$constant);
%}
#else
format %{ "LSL $dst,$src1,$src2\t! int" %}
ins_encode %{
__ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
%}
#endif
ins_pipe(ialu_reg_imm);
%}
#ifndef AARCH64
instruct shlL_reg_reg_merge_hi(iRegL dst, iRegL src1, iRegI src2) %{
effect(USE_DEF dst, USE src1, USE src2);
size(4);
format %{"OR $dst.hi,$dst.hi,($src1.hi << $src2)" %}
ins_encode %{
*** 8603,8646 ****
--- 6257,6278 ----
__ rsb($dst$$Register->successor(), $dst$$Register->successor(), 0, mi);
__ mov($dst$$Register->successor(), AsmOperand($src1$$Register, lsr, $dst$$Register->successor()), mi);
%}
ins_pipe(ialu_reg_reg);
%}
#endif // !AARCH64
instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
match(Set dst (LShiftL src1 src2));
#ifdef AARCH64
size(4);
format %{ "LSLV $dst,$src1,$src2\t! long" %}
ins_encode %{
__ lslv($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
#else
expand %{
flagsReg ccr;
shlL_reg_reg_overlap(dst, src1, src2, ccr);
shlL_reg_reg_merge_hi(dst, src1, src2);
shlL_reg_reg_merge_lo(dst, src1, src2);
%}
#endif
%}
#ifdef AARCH64
instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
match(Set dst (LShiftL src1 src2));
size(4);
format %{ "LSL $dst,$src1,$src2\t! long" %}
ins_encode %{
__ logical_shift_left($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
// Register Shift Left Immediate
instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
match(Set dst (LShiftL src1 src2));
size(8);
*** 8671,8720 ****
--- 6303,6336 ----
__ orr($dst$$Register->successor(), $dst$$Register->successor(), AsmOperand($src1$$Register, lsr, 32-$src2$$constant));
__ mov($dst$$Register, AsmOperand($src1$$Register, lsl, $src2$$constant));
%}
ins_pipe(ialu_reg_imm);
%}
#endif // !AARCH64
// Register Arithmetic Shift Right
instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (RShiftI src1 src2));
size(4);
#ifdef AARCH64
format %{ "ASRV $dst,$src1,$src2\t! int" %}
ins_encode %{
__ asrv_w($dst$$Register, $src1$$Register, $src2$$Register);
%}
#else
format %{ "ASR $dst,$src1,$src2\t! int" %}
ins_encode %{
__ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$Register));
%}
#endif
ins_pipe(ialu_reg_reg);
%}
// Register Arithmetic Shift Right Immediate
instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
match(Set dst (RShiftI src1 src2));
size(4);
#ifdef AARCH64
format %{ "ASR_w $dst,$src1,$src2" %}
ins_encode %{
__ _asr_w($dst$$Register, $src1$$Register, $src2$$constant);
%}
#else
format %{ "ASR $dst,$src1,$src2" %}
ins_encode %{
__ mov($dst$$Register, AsmOperand($src1$$Register, asr, $src2$$constant));
%}
#endif
ins_pipe(ialu_reg_imm);
%}
#ifndef AARCH64
// Register Shift Right Arithmetic Long
instruct sarL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
effect(USE_DEF dst, USE src1, USE src2);
size(4);
format %{ "OR $dst.lo,$dst.lo,($src1.lo >> $src2)" %}
*** 8749,8793 ****
--- 6365,6387 ----
__ rsb($dst$$Register, $dst$$Register, 0, mi);
__ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
%}
ins_pipe(ialu_reg_reg);
%}
#endif // !AARCH64
instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
match(Set dst (RShiftL src1 src2));
#ifdef AARCH64
size(4);
format %{ "ASRV $dst,$src1,$src2\t! long" %}
ins_encode %{
__ asrv($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
#else
expand %{
flagsReg ccr;
sarL_reg_reg_overlap(dst, src1, src2, ccr);
sarL_reg_reg_merge_lo(dst, src1, src2);
sarL_reg_reg_merge_hi(dst, src1, src2);
%}
#endif
%}
// Register Shift Left Immediate
#ifdef AARCH64
instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
match(Set dst (RShiftL src1 src2));
size(4);
format %{ "ASR $dst,$src1,$src2\t! long" %}
ins_encode %{
__ _asr($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
match(Set dst (RShiftL src1 src2));
size(8);
format %{ "ASR $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
*** 8817,8866 ****
--- 6411,6444 ----
__ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
__ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), asr, $src2$$constant));
%}
ins_pipe(ialu_reg_imm);
%}
#endif
// Register Shift Right
instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (URShiftI src1 src2));
size(4);
#ifdef AARCH64
format %{ "LSRV $dst,$src1,$src2\t! int" %}
ins_encode %{
__ lsrv_w($dst$$Register, $src1$$Register, $src2$$Register);
%}
#else
format %{ "LSR $dst,$src1,$src2\t! int" %}
ins_encode %{
__ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$Register));
%}
#endif
ins_pipe(ialu_reg_reg);
%}
// Register Shift Right Immediate
instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{
match(Set dst (URShiftI src1 src2));
size(4);
#ifdef AARCH64
format %{ "LSR_w $dst,$src1,$src2" %}
ins_encode %{
__ _lsr_w($dst$$Register, $src1$$Register, $src2$$constant);
%}
#else
format %{ "LSR $dst,$src1,$src2" %}
ins_encode %{
__ mov($dst$$Register, AsmOperand($src1$$Register, lsr, $src2$$constant));
%}
#endif
ins_pipe(ialu_reg_imm);
%}
#ifndef AARCH64
// Register Shift Right
instruct shrL_reg_reg_merge_lo(iRegL dst, iRegL src1, iRegI src2) %{
effect(USE_DEF dst, USE src1, USE src2);
size(4);
format %{ "OR $dst.lo,$dst,($src1.lo >>> $src2)" %}
*** 8895,8939 ****
--- 6473,6495 ----
__ rsb($dst$$Register, $dst$$Register, 0, mi);
__ mov($dst$$Register, AsmOperand($src1$$Register->successor(), lsl, $dst$$Register), mi);
%}
ins_pipe(ialu_reg_reg);
%}
#endif // !AARCH64
instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{
match(Set dst (URShiftL src1 src2));
#ifdef AARCH64
size(4);
format %{ "LSRV $dst,$src1,$src2\t! long" %}
ins_encode %{
__ lsrv($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
#else
expand %{
flagsReg ccr;
shrL_reg_reg_overlap(dst, src1, src2, ccr);
shrL_reg_reg_merge_lo(dst, src1, src2);
shrL_reg_reg_merge_hi(dst, src1, src2);
%}
#endif
%}
// Register Shift Right Immediate
#ifdef AARCH64
instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{
match(Set dst (URShiftL src1 src2));
size(4);
format %{ "LSR $dst,$src1,$src2" %}
ins_encode %{
__ _lsr($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
+
+ // Register Shift Right Immediate
instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6Big src2) %{
match(Set dst (URShiftL src1 src2));
size(8);
format %{ "LSR $dst.lo,$src1.hi,$src2-32\t! or mov if $src2==32\n\t"
*** 8964,8974 ****
--- 6520,6529 ----
__ orr($dst$$Register, $dst$$Register, AsmOperand($src1$$Register->successor(), lsl, 32-$src2$$constant));
__ mov($dst$$Register->successor(), AsmOperand($src1$$Register->successor(), lsr, $src2$$constant));
%}
ins_pipe(ialu_reg_imm);
%}
#endif // !AARCH64
instruct shrP_reg_imm5(iRegX dst, iRegP src1, immU5 src2) %{
match(Set dst (URShiftI (CastP2X src1) src2));
size(4);
*** 9162,9183 ****
--- 6717,6736 ----
__ and_32($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct andshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (AndI src1 (LShiftI src2 src3)));
size(4);
format %{ "AND $dst,$src1,$src2<<$src3" %}
ins_encode %{
__ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct andshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (AndI src1 (LShiftI src2 src3)));
size(4);
*** 9186,9207 ****
--- 6739,6758 ----
__ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct andsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (AndI src1 (RShiftI src2 src3)));
size(4);
format %{ "AND $dst,$src1,$src2>>$src3" %}
ins_encode %{
__ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct andsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (AndI src1 (RShiftI src2 src3)));
size(4);
*** 9210,9231 ****
--- 6761,6780 ----
__ and_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct andshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (AndI src1 (URShiftI src2 src3)));
size(4);
format %{ "AND $dst,$src1,$src2>>>$src3" %}
ins_encode %{
__ andr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct andshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (AndI src1 (URShiftI src2 src3)));
size(4);
*** 9246,9303 ****
--- 6795,6829 ----
__ and_32($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#ifndef AARCH64
instruct andI_reg_limmn(iRegI dst, iRegI src1, limmIn src2) %{
match(Set dst (AndI src1 src2));
size(4);
format %{ "bic $dst,$src1,~$src2\t! int" %}
ins_encode %{
__ bic($dst$$Register, $src1$$Register, ~$src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#endif
// Register And Long
instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (AndL src1 src2));
ins_cost(DEFAULT_COST);
#ifdef AARCH64
size(4);
format %{ "AND $dst,$src1,$src2\t! long" %}
ins_encode %{
__ andr($dst$$Register, $src1$$Register, $src2$$Register);
%}
#else
size(8);
format %{ "AND $dst,$src1,$src2\t! long" %}
ins_encode %{
__ andr($dst$$Register, $src1$$Register, $src2$$Register);
__ andr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
%}
#endif
ins_pipe(ialu_reg_reg);
%}
#ifdef AARCH64
// Immediate And
instruct andL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
match(Set dst (AndL src1 src2));
size(4);
format %{ "AND $dst,$src1,$src2\t! long" %}
ins_encode %{
__ andr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct andL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
match(Set dst (AndL src1 con));
ins_cost(DEFAULT_COST);
*** 9307,9317 ****
--- 6833,6842 ----
__ andr($dst$$Register, $src1$$Register, $con$$constant);
__ andr($dst$$Register->successor(), $src1$$Register->successor(), 0);
%}
ins_pipe(ialu_reg_imm);
%}
#endif
// Or Instructions
// Register Or
instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (OrI src1 src2));
*** 9322,9343 ****
--- 6847,6866 ----
__ orr_32($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct orshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (OrI src1 (LShiftI src2 src3)));
size(4);
format %{ "OR $dst,$src1,$src2<<$src3" %}
ins_encode %{
__ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct orshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (OrI src1 (LShiftI src2 src3)));
size(4);
*** 9346,9367 ****
--- 6869,6888 ----
__ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct orsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (OrI src1 (RShiftI src2 src3)));
size(4);
format %{ "OR $dst,$src1,$src2>>$src3" %}
ins_encode %{
__ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct orsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (OrI src1 (RShiftI src2 src3)));
size(4);
*** 9370,9391 ****
--- 6891,6910 ----
__ orr_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct orshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (OrI src1 (URShiftI src2 src3)));
size(4);
format %{ "OR $dst,$src1,$src2>>>$src3" %}
ins_encode %{
__ orr($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct orshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (OrI src1 (URShiftI src2 src3)));
size(4);
*** 9412,9451 ****
--- 6931,6950 ----
// Register Or Long
instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (OrL src1 src2));
ins_cost(DEFAULT_COST);
#ifdef AARCH64
size(4);
format %{ "OR $dst,$src1,$src2\t! long" %}
ins_encode %{
__ orr($dst$$Register, $src1$$Register, $src2$$Register);
%}
#else
size(8);
format %{ "OR $dst.lo,$src1.lo,$src2.lo\t! long\n\t"
"OR $dst.hi,$src1.hi,$src2.hi" %}
ins_encode %{
__ orr($dst$$Register, $src1$$Register, $src2$$Register);
__ orr($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
%}
#endif
ins_pipe(ialu_reg_reg);
%}
#ifdef AARCH64
instruct orL_reg_limm(iRegL dst, iRegL src1, limmL src2) %{
match(Set dst (OrL src1 src2));
size(4);
format %{ "ORR $dst,$src1,$src2\t! long" %}
ins_encode %{
__ orr($dst$$Register, $src1$$Register, (uintx)$src2$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct orL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
match(Set dst (OrL src1 con));
ins_cost(DEFAULT_COST);
*** 9456,9466 ****
--- 6955,6964 ----
__ orr($dst$$Register, $src1$$Register, $con$$constant);
__ orr($dst$$Register->successor(), $src1$$Register->successor(), 0);
%}
ins_pipe(ialu_reg_imm);
%}
#endif
#ifdef TODO
// Use SPRegP to match Rthread (TLS register) without spilling.
// Use store_ptr_RegP to match Rthread (TLS register) without spilling.
// Use sp_ptr_RegP to match Rthread (TLS register) without spilling.
*** 9486,9507 ****
--- 6984,7003 ----
__ eor_32($dst$$Register, $src1$$Register, $src2$$Register);
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct xorshlI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (XorI src1 (LShiftI src2 src3)));
size(4);
format %{ "XOR $dst,$src1,$src2<<$src3" %}
ins_encode %{
__ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct xorshlI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (XorI src1 (LShiftI src2 src3)));
size(4);
*** 9510,9531 ****
--- 7006,7025 ----
__ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsl, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct xorsarI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (XorI src1 (RShiftI src2 src3)));
size(4);
format %{ "XOR $dst,$src1,$src2>>$src3" %}
ins_encode %{
__ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct xorsarI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (XorI src1 (RShiftI src2 src3)));
size(4);
*** 9534,9555 ****
--- 7028,7047 ----
__ eor_32($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, asr, $src3$$constant));
%}
ins_pipe(ialu_reg_reg);
%}
#ifndef AARCH64
instruct xorshrI_reg_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) %{
match(Set dst (XorI src1 (URShiftI src2 src3)));
size(4);
format %{ "XOR $dst,$src1,$src2>>>$src3" %}
ins_encode %{
__ eor($dst$$Register, $src1$$Register, AsmOperand($src2$$Register, lsr, $src3$$Register));
%}
ins_pipe(ialu_reg_reg);
%}
#endif
instruct xorshrI_reg_reg_imm(iRegI dst, iRegI src1, iRegI src2, immU5 src3) %{
match(Set dst (XorI src1 (URShiftI src2 src3)));
size(4);
*** 9574,9613 ****
--- 7066,7085 ----
// Register Xor Long
instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{
match(Set dst (XorL src1 src2));
ins_cost(DEFAULT_COST);
#ifdef AARCH64
size(4);
format %{ "XOR $dst,$src1,$src2\t! long" %}
ins_encode %{
__ eor($dst$$Register, $src1$$Register, $src2$$Register);
%}
#else
size(8);
format %{ "XOR $dst.hi,$src1.hi,$src2.hi\t! long\n\t"
"XOR $dst.lo,$src1.lo,$src2.lo\t! long" %}
ins_encode %{
__ eor($dst$$Register, $src1$$Register, $src2$$Register);
__ eor($dst$$Register->successor(), $src1$$Register->successor(), $src2$$Register->successor());
%}
#endif
ins_pipe(ialu_reg_reg);
%}
#ifdef AARCH64
instruct xorL_reg_limmL(iRegL dst, iRegL src1, limmL con) %{
match(Set dst (XorL src1 con));
ins_cost(DEFAULT_COST);
size(4);
format %{ "EOR $dst,$src1,$con\t! long" %}
ins_encode %{
__ eor($dst$$Register, $src1$$Register, (uintx)$con$$constant);
%}
ins_pipe(ialu_reg_imm);
%}
#else
// TODO: try immLRot2 instead, (0, $con$$constant) becomes
// (hi($con$$constant), lo($con$$constant)) becomes
instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
match(Set dst (XorL src1 con));
ins_cost(DEFAULT_COST);
*** 9618,9753 ****
--- 7090,7163 ----
__ eor($dst$$Register, $src1$$Register, $con$$constant);
__ eor($dst$$Register->successor(), $src1$$Register->successor(), 0);
%}
ins_pipe(ialu_reg_imm);
%}
#endif // AARCH64
//----------Convert to Boolean-------------------------------------------------
instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
match(Set dst (Conv2B src));
effect(KILL ccr);
#ifdef AARCH64
size(8);
ins_cost(DEFAULT_COST*2);
format %{ "cmp_32 $src,ZR\n\t"
"cset_w $dst, ne" %}
ins_encode %{
__ cmp_32($src$$Register, ZR);
__ cset_w($dst$$Register, ne);
%}
#else
size(12);
ins_cost(DEFAULT_COST*2);
format %{ "TST $src,$src \n\t"
"MOV $dst, 0 \n\t"
"MOV.ne $dst, 1" %}
ins_encode %{ // FIXME: can do better?
__ tst($src$$Register, $src$$Register);
__ mov($dst$$Register, 0);
__ mov($dst$$Register, 1, ne);
%}
#endif
ins_pipe(ialu_reg_ialu);
%}
instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
match(Set dst (Conv2B src));
effect(KILL ccr);
#ifdef AARCH64
size(8);
ins_cost(DEFAULT_COST*2);
format %{ "CMP $src,ZR\n\t"
"cset $dst, ne" %}
ins_encode %{
__ cmp($src$$Register, ZR);
__ cset($dst$$Register, ne);
%}
#else
size(12);
ins_cost(DEFAULT_COST*2);
format %{ "TST $src,$src \n\t"
"MOV $dst, 0 \n\t"
"MOV.ne $dst, 1" %}
ins_encode %{
__ tst($src$$Register, $src$$Register);
__ mov($dst$$Register, 0);
__ mov($dst$$Register, 1, ne);
%}
#endif
ins_pipe(ialu_reg_ialu);
%}
instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
match(Set dst (CmpLTMask p q));
effect( KILL ccr );
#ifdef AARCH64
size(8);
ins_cost(DEFAULT_COST*2);
format %{ "CMP_w $p,$q\n\t"
"CSETM_w $dst, lt" %}
ins_encode %{
__ cmp_w($p$$Register, $q$$Register);
__ csetm_w($dst$$Register, lt);
%}
#else
ins_cost(DEFAULT_COST*3);
format %{ "CMP $p,$q\n\t"
"MOV $dst, #0\n\t"
"MOV.lt $dst, #-1" %}
ins_encode %{
__ cmp($p$$Register, $q$$Register);
__ mov($dst$$Register, 0);
__ mvn($dst$$Register, 0, lt);
%}
#endif
ins_pipe(ialu_reg_reg_ialu);
%}
instruct cmpLTMask_reg_imm( iRegI dst, iRegI p, aimmI q, flagsReg ccr ) %{
match(Set dst (CmpLTMask p q));
effect( KILL ccr );
#ifdef AARCH64
size(8);
ins_cost(DEFAULT_COST*2);
format %{ "CMP_w $p,$q\n\t"
"CSETM_w $dst, lt" %}
ins_encode %{
__ cmp_w($p$$Register, $q$$constant);
__ csetm_w($dst$$Register, lt);
%}
#else
ins_cost(DEFAULT_COST*3);
format %{ "CMP $p,$q\n\t"
"MOV $dst, #0\n\t"
"MOV.lt $dst, #-1" %}
ins_encode %{
__ cmp($p$$Register, $q$$constant);
__ mov($dst$$Register, 0);
__ mvn($dst$$Register, 0, lt);
%}
#endif
ins_pipe(ialu_reg_reg_ialu);
%}
#ifdef AARCH64
instruct cadd_cmpLTMask3( iRegI dst, iRegI p, iRegI q, iRegI y, iRegI x, flagsReg ccr ) %{
match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
effect( TEMP dst, KILL ccr );
size(12);
ins_cost(DEFAULT_COST*3);
format %{ "CMP_w $p,$q\n\t"
"ADD_w $dst,$y,$x\n\t"
"CSEL_w $dst,$dst,$x,lt" %}
ins_encode %{
__ cmp_w($p$$Register, $q$$Register);
__ add_w($dst$$Register, $y$$Register, $x$$Register);
__ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
%}
ins_pipe( cadd_cmpltmask );
%}
#else
instruct cadd_cmpLTMask3( iRegI p, iRegI q, iRegI y, iRegI z, flagsReg ccr ) %{
match(Set z (AddI (AndI (CmpLTMask p q) y) z));
effect( KILL ccr );
ins_cost(DEFAULT_COST*2);
format %{ "CMP $p,$q\n\t"
*** 9756,9784 ****
--- 7166,7176 ----
__ cmp($p$$Register, $q$$Register);
__ add($z$$Register, $y$$Register, $z$$Register, lt);
%}
ins_pipe( cadd_cmpltmask );
%}
#endif
#ifdef AARCH64
instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI x, flagsReg ccr ) %{
match(Set dst (AddI (AndI (CmpLTMask p q) y) x));
effect( TEMP dst, KILL ccr );
size(12);
ins_cost(DEFAULT_COST*3);
format %{ "CMP_w $p,$q\n\t"
"ADD_w $dst,$y,$x\n\t"
"CSEL_w $dst,$dst,$x,lt" %}
ins_encode %{
__ cmp_w($p$$Register, $q$$constant);
__ add_w($dst$$Register, $y$$Register, $x$$Register);
__ csel_w($dst$$Register, $dst$$Register, $x$$Register, lt);
%}
ins_pipe( cadd_cmpltmask );
%}
#else
// FIXME: remove unused "dst"
instruct cadd_cmpLTMask4( iRegI dst, iRegI p, aimmI q, iRegI y, iRegI z, flagsReg ccr ) %{
match(Set z (AddI (AndI (CmpLTMask p q) y) z));
effect( KILL ccr );
ins_cost(DEFAULT_COST*2);
*** 9788,9816 ****
--- 7180,7190 ----
__ cmp($p$$Register, $q$$constant);
__ add($z$$Register, $y$$Register, $z$$Register, lt);
%}
ins_pipe( cadd_cmpltmask );
%}
#endif // !AARCH64
#ifdef AARCH64
instruct cadd_cmpLTMask( iRegI dst, iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
match(Set dst (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
effect( TEMP dst, KILL ccr );
size(12);
ins_cost(DEFAULT_COST*3);
format %{ "SUBS_w $p,$p,$q\n\t"
"ADD_w $dst,$y,$p\n\t"
"CSEL_w $dst,$dst,$p,lt" %}
ins_encode %{
__ subs_w($p$$Register, $p$$Register, $q$$Register);
__ add_w($dst$$Register, $y$$Register, $p$$Register);
__ csel_w($dst$$Register, $dst$$Register, $p$$Register, lt);
%}
ins_pipe( cadd_cmpltmask ); // FIXME
%}
#else
instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, flagsReg ccr ) %{
match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
effect( KILL ccr );
ins_cost(DEFAULT_COST*2);
format %{ "SUBS $p,$p,$q\n\t"
*** 9819,9829 ****
--- 7193,7202 ----
__ subs($p$$Register, $p$$Register, $q$$Register);
__ add($p$$Register, $y$$Register, $p$$Register, lt);
%}
ins_pipe( cadd_cmpltmask );
%}
#endif
//----------Arithmetic Conversion Instructions---------------------------------
// The conversions operations are all Alpha sorted. Please keep it that way!
instruct convD2F_reg(regF dst, regD src) %{
*** 9837,9867 ****
--- 7210,7219 ----
%}
// Convert a double to an int in a float register.
// If the double is a NAN, stuff a zero in instead.
#ifdef AARCH64
instruct convD2I_reg_reg(iRegI dst, regD src) %{
match(Set dst (ConvD2I src));
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
format %{ "FCVTZS_wd $dst, $src" %}
ins_encode %{
__ fcvtzs_wd($dst$$Register, $src$$FloatRegister);
%}
ins_pipe(fcvtD2I);
%}
instruct convD2L_reg_reg(iRegL dst, regD src) %{
match(Set dst (ConvD2L src));
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
format %{ "FCVTZS_xd $dst, $src" %}
ins_encode %{
__ fcvtzs_xd($dst$$Register, $src$$FloatRegister);
%}
ins_pipe(fcvtD2L);
%}
#else
instruct convD2I_reg_reg(iRegI dst, regD src, regF tmp) %{
match(Set dst (ConvD2I src));
effect( TEMP tmp );
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
format %{ "FTOSIZD $tmp,$src\n\t"
*** 9870,9885 ****
--- 7222,7235 ----
__ ftosizd($tmp$$FloatRegister, $src$$FloatRegister);
__ fmrs($dst$$Register, $tmp$$FloatRegister);
%}
ins_pipe(fcvtD2I);
%}
#endif
// Convert a double to a long in a double register.
// If the double is a NAN, stuff a zero in instead.
#ifndef AARCH64
// Double to Long conversion
instruct convD2L_reg(R0R1RegL dst, regD src) %{
match(Set dst (ConvD2L src));
effect(CALL);
ins_cost(MEMORY_REF_COST); // FIXME
*** 9895,9905 ****
--- 7245,7254 ----
address target = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
__ call(target, relocInfo::runtime_call_type);
%}
ins_pipe(fcvtD2L);
%}
#endif
instruct convF2D_reg(regD dst, regF src) %{
match(Set dst (ConvF2D src));
size(4);
format %{ "FCVTDS $dst,$src" %}
*** 9907,9939 ****
--- 7256,7265 ----
__ convert_f2d($dst$$FloatRegister, $src$$FloatRegister);
%}
ins_pipe(fcvtF2D);
%}
#ifdef AARCH64
instruct convF2I_reg_reg(iRegI dst, regF src) %{
match(Set dst (ConvF2I src));
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
size(4);
format %{ "FCVTZS_ws $dst, $src" %}
ins_encode %{
__ fcvtzs_ws($dst$$Register, $src$$FloatRegister);
%}
ins_pipe(fcvtF2I);
%}
instruct convF2L_reg_reg(iRegL dst, regF src) %{
match(Set dst (ConvF2L src));
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
size(4);
format %{ "FCVTZS_xs $dst, $src" %}
ins_encode %{
__ fcvtzs_xs($dst$$Register, $src$$FloatRegister);
%}
ins_pipe(fcvtF2L);
%}
#else
instruct convF2I_reg_reg(iRegI dst, regF src, regF tmp) %{
match(Set dst (ConvF2I src));
effect( TEMP tmp );
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
size(8);
*** 9963,9986 ****
--- 7289,7299 ----
address target = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
__ call(target, relocInfo::runtime_call_type);
%}
ins_pipe(fcvtF2L);
%}
#endif
#ifdef AARCH64
instruct convI2D_reg_reg(iRegI src, regD dst) %{
match(Set dst (ConvI2D src));
ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
size(4);
format %{ "SCVTF_dw $dst,$src" %}
ins_encode %{
__ scvtf_dw($dst$$FloatRegister, $src$$Register);
%}
ins_pipe(fcvtI2D);
%}
#else
instruct convI2D_reg_reg(iRegI src, regD_low dst) %{
match(Set dst (ConvI2D src));
ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
size(8);
format %{ "FMSR $dst,$src \n\t"
*** 9989,10080 ****
--- 7302,7360 ----
__ fmsr($dst$$FloatRegister, $src$$Register);
__ fsitod($dst$$FloatRegister, $dst$$FloatRegister);
%}
ins_pipe(fcvtI2D);
%}
#endif
instruct convI2F_reg_reg( regF dst, iRegI src ) %{
match(Set dst (ConvI2F src));
ins_cost(DEFAULT_COST + MEMORY_REF_COST); // FIXME
#ifdef AARCH64
size(4);
format %{ "SCVTF_sw $dst,$src" %}
ins_encode %{
__ scvtf_sw($dst$$FloatRegister, $src$$Register);
%}
#else
size(8);
format %{ "FMSR $dst,$src \n\t"
"FSITOS $dst, $dst"%}
ins_encode %{
__ fmsr($dst$$FloatRegister, $src$$Register);
__ fsitos($dst$$FloatRegister, $dst$$FloatRegister);
%}
#endif
ins_pipe(fcvtI2F);
%}
instruct convI2L_reg(iRegL dst, iRegI src) %{
match(Set dst (ConvI2L src));
#ifdef AARCH64
size(4);
format %{ "SXTW $dst,$src\t! int->long" %}
ins_encode %{
__ sxtw($dst$$Register, $src$$Register);
%}
#else
size(8);
format %{ "MOV $dst.lo, $src \n\t"
"ASR $dst.hi,$src,31\t! int->long" %}
ins_encode %{
__ mov($dst$$Register, $src$$Register);
__ mov($dst$$Register->successor(), AsmOperand($src$$Register, asr, 31));
%}
#endif
ins_pipe(ialu_reg_reg);
%}
// Zero-extend convert int to long
instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{
match(Set dst (AndL (ConvI2L src) mask) );
#ifdef AARCH64
size(4);
format %{ "mov_w $dst,$src\t! zero-extend int to long" %}
ins_encode %{
__ mov_w($dst$$Register, $src$$Register);
%}
#else
size(8);
format %{ "MOV $dst.lo,$src.lo\t! zero-extend int to long\n\t"
"MOV $dst.hi, 0"%}
ins_encode %{
__ mov($dst$$Register, $src$$Register);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(ialu_reg_reg);
%}
// Zero-extend long
instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{
match(Set dst (AndL src mask) );
#ifdef AARCH64
size(4);
format %{ "mov_w $dst,$src\t! zero-extend long" %}
ins_encode %{
__ mov_w($dst$$Register, $src$$Register);
%}
#else
size(8);
format %{ "MOV $dst.lo,$src.lo\t! zero-extend long\n\t"
"MOV $dst.hi, 0"%}
ins_encode %{
__ mov($dst$$Register, $src$$Register);
__ mov($dst$$Register->successor(), 0);
%}
#endif
ins_pipe(ialu_reg_reg);
%}
instruct MoveF2I_reg_reg(iRegI dst, regF src) %{
match(Set dst (MoveF2I src));
*** 10105,10174 ****
--- 7385,7417 ----
match(Set dst (MoveD2L src));
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); // FIXME
size(4);
#ifdef AARCH64
format %{ "FMOV_xd $dst,$src\t! MoveD2L" %}
ins_encode %{
__ fmov_xd($dst$$Register, $src$$FloatRegister);
%}
#else
format %{ "FMRRD $dst,$src\t! MoveD2L" %}
ins_encode %{
__ fmrrd($dst$$Register, $dst$$Register->successor(), $src$$FloatRegister);
%}
#endif
ins_pipe(iload_mem); // FIXME
%}
instruct MoveL2D_reg_reg(regD dst, iRegL src) %{
match(Set dst (MoveL2D src));
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); // FIXME
size(4);
#ifdef AARCH64
format %{ "FMOV_dx $dst,$src\t! MoveL2D" %}
ins_encode %{
__ fmov_dx($dst$$FloatRegister, $src$$Register);
%}
#else
format %{ "FMDRR $dst,$src\t! MoveL2D" %}
ins_encode %{
__ fmdrr($dst$$FloatRegister, $src$$Register, $src$$Register->successor());
%}
#endif
ins_pipe(ialu_reg_reg); // FIXME
%}
//-----------
// Long to Double conversion
#ifdef AARCH64
instruct convL2D(regD dst, iRegL src) %{
match(Set dst (ConvL2D src));
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
size(4);
format %{ "SCVTF_dx $dst, $src" %}
ins_encode %{
__ scvtf_dx($dst$$FloatRegister, $src$$Register);
%}
ins_pipe(fcvtL2D);
%}
instruct convL2F(regF dst, iRegL src) %{
match(Set dst (ConvL2F src));
ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); // FIXME
size(4);
format %{ "SCVTF_sx $dst, $src" %}
ins_encode %{
__ scvtf_sx($dst$$FloatRegister, $src$$Register);
%}
ins_pipe(fcvtL2F);
%}
#else
// Magic constant, 0x43300000
instruct loadConI_x43300000(iRegI dst) %{
effect(DEF dst);
size(8);
format %{ "MOV_SLOW $dst,0x43300000\t! 2^52" %}
*** 10210,10220 ****
--- 7453,7462 ----
__ fcpys($dst$$FloatRegister, $src2$$FloatRegister);
%}
ins_pipe(faddD_reg_reg);
%}
#ifndef AARCH64
// Convert integer in high half of a double register (in the lower half of
// the double register file) to double
instruct convI2D_regDHi_regD(regD dst, regD_low src) %{
effect(DEF dst, USE src);
size(4);
*** 10222,10232 ****
--- 7464,7473 ----
ins_encode %{
__ fsitod($dst$$FloatRegister, $src$$FloatRegister->successor());
%}
ins_pipe(fcvtLHi2D);
%}
#endif
// Add float double precision
instruct addD_regD_regD(regD dst, regD src1, regD src2) %{
effect(DEF dst, USE src1, USE src2);
size(4);
*** 10313,10342 ****
--- 7554,7574 ----
subD_regD_regD(tmp3, tmp2, dx43300000);
mulD_regD_regD(tmp4, tmp1, dx41f00000);
addD_regD_regD(dst, tmp3, tmp4);
%}
%}
#endif // !AARCH64
instruct convL2I_reg(iRegI dst, iRegL src) %{
match(Set dst (ConvL2I src));
size(4);
#ifdef AARCH64
format %{ "MOV_w $dst,$src\t! long->int" %}
ins_encode %{
__ mov_w($dst$$Register, $src$$Register);
%}
#else
format %{ "MOV $dst,$src.lo\t! long->int" %}
ins_encode %{
__ mov($dst$$Register, $src$$Register);
%}
#endif
ins_pipe(ialu_move_reg_I_to_L);
%}
#ifndef AARCH64
// Register Shift Right Immediate
instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
match(Set dst (ConvL2I (RShiftL src cnt)));
size(4);
format %{ "ASR $dst,$src.hi,($cnt - 32)\t! long->int or mov if $cnt==32" %}
*** 10347,10357 ****
--- 7579,7588 ----
__ mov($dst$$Register, AsmOperand($src$$Register->successor(), asr, $cnt$$constant - 32));
}
%}
ins_pipe(ialu_reg_imm);
%}
#endif
//----------Control Flow Instructions------------------------------------------
// Compare Instructions
// Compare Integers
*** 10426,10447 ****
--- 7657,7676 ----
__ tst_32($op1$$Register, $op2$$Register);
%}
ins_pipe(ialu_cconly_reg_reg_zero);
%}
#ifndef AARCH64
instruct testshlI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
size(4);
format %{ "TST $op2,$op1<<$op3" %}
ins_encode %{
__ tst($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$Register));
%}
ins_pipe(ialu_cconly_reg_reg_zero);
%}
#endif
instruct testshlI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
match(Set icc (CmpI (AndI op1 (LShiftI op2 op3)) zero));
size(4);
format %{ "tst_32 $op2,$op1<<$op3" %}
*** 10450,10471 ****
--- 7679,7698 ----
__ tst_32($op1$$Register, AsmOperand($op2$$Register, lsl, $op3$$constant));
%}
ins_pipe(ialu_cconly_reg_reg_zero);
%}
#ifndef AARCH64
instruct testsarI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
size(4);
format %{ "TST $op2,$op1<<$op3" %}
ins_encode %{
__ tst($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$Register));
%}
ins_pipe(ialu_cconly_reg_reg_zero);
%}
#endif
instruct testsarI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
match(Set icc (CmpI (AndI op1 (RShiftI op2 op3)) zero));
size(4);
format %{ "tst_32 $op2,$op1<<$op3" %}
*** 10474,10495 ****
--- 7701,7720 ----
__ tst_32($op1$$Register, AsmOperand($op2$$Register, asr, $op3$$constant));
%}
ins_pipe(ialu_cconly_reg_reg_zero);
%}
#ifndef AARCH64
instruct testshrI_reg_reg_reg( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, iRegI op3, immI0 zero ) %{
match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
size(4);
format %{ "TST $op2,$op1<<$op3" %}
ins_encode %{
__ tst($op1$$Register, AsmOperand($op2$$Register, lsr, $op3$$Register));
%}
ins_pipe(ialu_cconly_reg_reg_zero);
%}
#endif
instruct testshrI_reg_reg_imm( flagsReg_EQNELTGE icc, iRegI op1, iRegI op2, immU5 op3, immI0 zero ) %{
match(Set icc (CmpI (AndI op1 (URShiftI op2 op3)) zero));
size(4);
format %{ "tst_32 $op2,$op1<<$op3" %}
*** 10509,10543 ****
--- 7734,7743 ----
__ tst_32($op1$$Register, $op2$$constant);
%}
ins_pipe(ialu_cconly_reg_imm_zero);
%}
#ifdef AARCH64
instruct compL_reg_reg(flagsReg xcc, iRegL op1, iRegL op2)
%{
match(Set xcc (CmpL op1 op2));
effect( DEF xcc, USE op1, USE op2 );
size(4);
format %{ "CMP $op1,$op2\t! long" %}
ins_encode %{
__ cmp($op1$$Register, $op2$$Register);
%}
ins_pipe(ialu_cconly_reg_reg);
%}
instruct compUL_iReg(flagsRegU xcc, iRegL op1, iRegL op2) %{
match(Set xcc (CmpUL op1 op2));
size(4);
format %{ "CMP $op1,$op2\t! unsigned long" %}
ins_encode %{
__ cmp($op1$$Register, $op2$$Register);
%}
ins_pipe(ialu_cconly_reg_reg);
%}
#else
instruct compL_reg_reg_LTGE(flagsRegL_LTGE xcc, iRegL op1, iRegL op2, iRegL tmp) %{
match(Set xcc (CmpL op1 op2));
effect( DEF xcc, USE op1, USE op2, TEMP tmp );
size(8);
*** 10561,10599 ****
--- 7761,7771 ----
__ subs($tmp$$Register, $op1$$Register, $op2$$Register);
__ sbcs($tmp$$Register->successor(), $op1$$Register->successor(), $op2$$Register->successor());
%}
ins_pipe(ialu_cconly_reg_reg);
%}
#endif
#ifdef AARCH64
instruct compL_reg_con(flagsReg xcc, iRegL op1, aimmL con) %{
match(Set xcc (CmpL op1 con));
effect( DEF xcc, USE op1, USE con );
size(8);
format %{ "CMP $op1,$con\t\t! long" %}
ins_encode %{
__ cmp($op1$$Register, $con$$constant);
%}
ins_pipe(ialu_cconly_reg_imm);
%}
instruct compUL_reg_con(flagsRegU xcc, iRegL op1, aimmL con) %{
match(Set xcc (CmpUL op1 con));
effect(DEF xcc, USE op1, USE con);
size(8);
format %{ "CMP $op1,$con\t\t! unsigned long" %}
ins_encode %{
__ cmp($op1$$Register, $con$$constant);
%}
ins_pipe(ialu_cconly_reg_imm);
%}
#else
instruct compL_reg_reg_EQNE(flagsRegL_EQNE xcc, iRegL op1, iRegL op2) %{
match(Set xcc (CmpL op1 op2));
effect( DEF xcc, USE op1, USE op2 );
size(8);
*** 10747,10757 ****
--- 7919,7928 ----
__ rscs($tmp$$Register->successor(), $op1$$Register->successor(), 0);
%}
ins_pipe(ialu_cconly_reg_reg);
%}
#endif
/* instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ */
/* match(Set xcc (CmpL (AndL op1 op2) zero)); */
/* ins_encode %{ */
/* __ stop("testL_reg_reg unimplemented"); */
*** 10855,11025 ****
--- 8026,8087 ----
// Compare floating, generate condition code
instruct cmpF_cc(flagsRegF fcc, flagsReg icc, regF src1, regF src2) %{
match(Set icc (CmpF src1 src2));
effect(KILL fcc);
#ifdef AARCH64
size(4);
format %{ "FCMP_s $src1,$src2" %}
ins_encode %{
__ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
%}
#else
size(8);
format %{ "FCMPs $src1,$src2\n\t"
"FMSTAT" %}
ins_encode %{
__ fcmps($src1$$FloatRegister, $src2$$FloatRegister);
__ fmstat();
%}
#endif
ins_pipe(faddF_fcc_reg_reg_zero);
%}
instruct cmpF0_cc(flagsRegF fcc, flagsReg icc, regF src1, immF0 src2) %{
match(Set icc (CmpF src1 src2));
effect(KILL fcc);
#ifdef AARCH64
size(4);
format %{ "FCMP0_s $src1" %}
ins_encode %{
__ fcmp0_s($src1$$FloatRegister);
%}
#else
size(8);
format %{ "FCMPs $src1,$src2\n\t"
"FMSTAT" %}
ins_encode %{
__ fcmpzs($src1$$FloatRegister);
__ fmstat();
%}
#endif
ins_pipe(faddF_fcc_reg_reg_zero);
%}
instruct cmpD_cc(flagsRegF fcc, flagsReg icc, regD src1, regD src2) %{
match(Set icc (CmpD src1 src2));
effect(KILL fcc);
#ifdef AARCH64
size(4);
format %{ "FCMP_d $src1,$src2" %}
ins_encode %{
__ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
%}
#else
size(8);
format %{ "FCMPd $src1,$src2 \n\t"
"FMSTAT" %}
ins_encode %{
__ fcmpd($src1$$FloatRegister, $src2$$FloatRegister);
__ fmstat();
%}
#endif
ins_pipe(faddD_fcc_reg_reg_zero);
%}
instruct cmpD0_cc(flagsRegF fcc, flagsReg icc, regD src1, immD0 src2) %{
match(Set icc (CmpD src1 src2));
effect(KILL fcc);
#ifdef AARCH64
size(8);
format %{ "FCMP0_d $src1" %}
ins_encode %{
__ fcmp0_d($src1$$FloatRegister);
%}
#else
+
size(8);
format %{ "FCMPZd $src1,$src2 \n\t"
"FMSTAT" %}
ins_encode %{
__ fcmpzd($src1$$FloatRegister);
__ fmstat();
%}
#endif
ins_pipe(faddD_fcc_reg_reg_zero);
%}
#ifdef AARCH64
// Compare floating, generate -1,0,1
instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsReg icc) %{
match(Set dst (CmpF3 src1 src2));
// effect(KILL fcc); // nobody cares if flagsRegF is killed
effect(KILL icc);
ins_cost(DEFAULT_COST*3); // FIXME
size(12);
format %{ "FCMP_s $src1,$src2\n\t"
"CSET $dst, gt\n\t"
"CSINV $dst, $dst, ZR, ge" %}
ins_encode %{
Register dst = $dst$$Register;
__ fcmp_s($src1$$FloatRegister, $src2$$FloatRegister);
__ cset(dst, gt); // 1 if '>', else 0
__ csinv(dst, dst, ZR, ge); // previous value if '>=', else -1
%}
ins_pipe( floating_cmp ); // FIXME
%}
// Compare floating, generate -1,0,1
instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsReg icc) %{
match(Set dst (CmpD3 src1 src2));
// effect(KILL fcc); // nobody cares if flagsRegF is killed
effect(KILL icc);
ins_cost(DEFAULT_COST*3); // FIXME
size(12);
format %{ "FCMP_d $src1,$src2\n\t"
"CSET $dst, gt\n\t"
"CSINV $dst, $dst, ZR, ge" %}
ins_encode %{
Register dst = $dst$$Register;
__ fcmp_d($src1$$FloatRegister, $src2$$FloatRegister);
__ cset(dst, gt); // 1 if '>', else 0
__ csinv(dst, dst, ZR, ge); // previous value if '>=', else -1
%}
ins_pipe( floating_cmp ); // FIXME
%}
// Compare floating, generate -1,0,1
instruct cmpF0_reg(iRegI dst, regF src1, immF0 src2, flagsReg icc) %{
match(Set dst (CmpF3 src1 src2));
// effect(KILL fcc); // nobody cares if flagsRegF is killed
effect(KILL icc);
ins_cost(DEFAULT_COST*3); // FIXME
size(12);
format %{ "FCMP0_s $src1\n\t"
"CSET $dst, gt\n\t"
"CSINV $dst, $dst, ZR, ge" %}
ins_encode %{
Register dst = $dst$$Register;
__ fcmp0_s($src1$$FloatRegister);
__ cset(dst, gt); // 1 if '>', else 0
__ csinv(dst, dst, ZR, ge); // previous value if '>=', else -1
%}
ins_pipe( floating_cmp ); // FIXME
%}
// Compare floating, generate -1,0,1
instruct cmpD0_reg(iRegI dst, regD src1, immD0 src2, flagsReg icc) %{
match(Set dst (CmpD3 src1 src2));
// effect(KILL fcc); // nobody cares if flagsRegF is killed
effect(KILL icc);
ins_cost(DEFAULT_COST*3); // FIXME
size(12);
format %{ "FCMP0_d $src1\n\t"
"CSET $dst, gt\n\t"
"CSINV $dst, $dst, ZR, ge" %}
ins_encode %{
Register dst = $dst$$Register;
__ fcmp0_d($src1$$FloatRegister);
__ cset(dst, gt); // 1 if '>', else 0
__ csinv(dst, dst, ZR, ge); // previous value if '>=', else -1
%}
ins_pipe( floating_cmp ); // FIXME
%}
#else
// Compare floating, generate -1,0,1
instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF fcc) %{
match(Set dst (CmpF3 src1 src2));
effect(KILL fcc);
ins_cost(DEFAULT_COST*3+BRANCH_COST*3); // FIXME
*** 11092,11102 ****
--- 8154,8163 ----
__ fcmpzd($src1$$FloatRegister);
__ floating_cmp($dst$$Register);
%}
ins_pipe( floating_cmp );
%}
#endif // !AARCH64
//----------Branches---------------------------------------------------------
// Jump
// (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
// FIXME
*** 11174,11238 ****
--- 8235,8244 ----
%}
ins_pipe(br_cc);
%}
#endif
#ifdef AARCH64
instruct cbzI(cmpOp cmp, iRegI op1, immI0 op2, label labl) %{
match(If cmp (CmpI op1 op2));
effect(USE labl);
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
size(4);
ins_cost(BRANCH_COST);
format %{ "CB{N}Z $op1, $labl\t! int $cmp" %}
ins_encode %{
if ($cmp$$cmpcode == eq) {
__ cbz_w($op1$$Register, *($labl$$label));
} else {
__ cbnz_w($op1$$Register, *($labl$$label));
}
%}
ins_pipe(br_cc); // FIXME
%}
instruct cbzP(cmpOpP cmp, iRegP op1, immP0 op2, label labl) %{
match(If cmp (CmpP op1 op2));
effect(USE labl);
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
size(4);
ins_cost(BRANCH_COST);
format %{ "CB{N}Z $op1, $labl\t! ptr $cmp" %}
ins_encode %{
if ($cmp$$cmpcode == eq) {
__ cbz($op1$$Register, *($labl$$label));
} else {
__ cbnz($op1$$Register, *($labl$$label));
}
%}
ins_pipe(br_cc); // FIXME
%}
instruct cbzL(cmpOpL cmp, iRegL op1, immL0 op2, label labl) %{
match(If cmp (CmpL op1 op2));
effect(USE labl);
predicate(_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq ||
_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne);
size(4);
ins_cost(BRANCH_COST);
format %{ "CB{N}Z $op1, $labl\t! long $cmp" %}
ins_encode %{
if ($cmp$$cmpcode == eq) {
__ cbz($op1$$Register, *($labl$$label));
} else {
__ cbnz($op1$$Register, *($labl$$label));
}
%}
ins_pipe(br_cc); // FIXME
%}
#endif
instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
match(If cmp icc);
effect(USE labl);
*** 11256,11266 ****
--- 8262,8271 ----
__ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(br_cc);
%}
#ifndef AARCH64
instruct branchConL_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, label labl) %{
match(If cmp xcc);
effect(USE labl);
predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
*** 11340,11350 ****
--- 8345,8354 ----
ins_encode %{
__ b(*($labl$$label), (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(br_cc);
%}
#endif
instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
match(CountedLoopEnd cmp icc);
effect(USE labl);
*** 11388,11417 ****
--- 8392,8401 ----
// ins_pipe(br_cc);
// %}
// Manifest a CmpL3 result in an integer register. Very painful.
// This is the test to avoid.
#ifdef AARCH64
instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr) %{
match(Set dst (CmpL3 src1 src2));
// effect(KILL fcc); // nobody cares if flagsRegF is killed
effect(KILL ccr);
ins_cost(DEFAULT_COST*3); // FIXME
size(12);
format %{ "CMP $src1,$src2\n\t"
"CSET $dst, gt\n\t"
"CSINV $dst, $dst, ZR, ge" %}
ins_encode %{
Register dst = $dst$$Register;
__ cmp($src1$$Register, $src2$$Register);
__ cset(dst, gt); // 1 if '>', else 0
__ csinv(dst, dst, ZR, ge); // previous value if '>=', else -1
%}
ins_pipe( ialu_cconly_reg_reg ); // FIXME
%}
// TODO cmpL3_reg_imm
#else
instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{
match(Set dst (CmpL3 src1 src2) );
effect( KILL ccr );
ins_cost(6*DEFAULT_COST); // FIXME
size(32);
*** 11435,11447 ****
--- 8419,8429 ----
__ mvn($dst$$Register, 0, lo);
__ bind(done);
%}
ins_pipe(cmpL_reg);
%}
#endif
#ifndef AARCH64
// Conditional move
instruct cmovLL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegL dst, iRegL src) %{
match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src)));
predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
*** 11525,11537 ****
--- 8507,8517 ----
__ mov($dst$$Register, 0, (AsmCondition)($cmp$$cmpcode));
__ mov($dst$$Register->successor(), 0, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_imm);
%}
#endif // !AARCH64
#ifndef AARCH64
instruct cmovIL_reg_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
ins_cost(150);
*** 11566,11578 ****
--- 8546,8556 ----
ins_encode %{
__ mov($dst$$Register, $src$$Register, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(ialu_reg);
%}
#endif // !AARCH64
#ifndef AARCH64
instruct cmovIL_imm_LTGE(cmpOpL cmp, flagsRegL_LTGE xcc, iRegI dst, immI16 src) %{
match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src)));
predicate(_kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
ins_cost(140);
*** 11754,11782 ****
--- 8732,8744 ----
ins_encode %{
__ fcpyd($dst$$FloatRegister, $src$$FloatRegister, (AsmCondition)($cmp$$cmpcode));
%}
ins_pipe(int_conditional_float_move);
%}
#endif // !AARCH64
// ============================================================================
// Safepoint Instruction
#ifdef AARCH64
instruct safePoint_poll(iRegP poll, flagsReg icc, RtempRegP tmp) %{
match(SafePoint poll);
// The handler stub kills Rtemp
effect(USE poll, KILL tmp, KILL icc);
size(4);
format %{ "LDR ZR,[$poll]\t! Safepoint: poll for GC" %}
ins_encode %{
__ relocate(relocInfo::poll_type);
__ ldr(ZR, Address($poll$$Register));
%}
ins_pipe(loadPollP);
%}
#else
// rather than KILL R12, it would be better to use any reg as
// TEMP. Can't do that at this point because it crashes the compiler
instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
match(SafePoint poll);
effect(USE poll, KILL tmp, KILL icc);
*** 11787,11797 ****
--- 8749,8758 ----
__ relocate(relocInfo::poll_type);
__ ldr($tmp$$Register, Address($poll$$Register));
%}
ins_pipe(loadPollP);
%}
#endif
// ============================================================================
// Call Instructions
// Call Java Static Instruction
*** 11836,11852 ****
--- 8797,8808 ----
instruct CallRuntimeDirect(method meth) %{
match(CallRuntime);
effect(USE meth);
ins_cost(CALL_COST);
format %{ "CALL,runtime" %}
#ifdef AARCH64
ins_encode( save_last_PC, Java_To_Runtime( meth ),
call_epilog );
#else
ins_encode( Java_To_Runtime( meth ),
call_epilog );
#endif
ins_pipe(simple_call);
%}
// Call runtime without safepoint - same as CallRuntime
instruct CallLeafDirect(method meth) %{
*** 11968,11982 ****
--- 8924,8934 ----
size(4);
// Use the following format syntax
format %{ "ShouldNotReachHere" %}
ins_encode %{
#ifdef AARCH64
__ dpcs1(0xdead);
#else
__ udf(0xdead);
#endif
%}
ins_pipe(tail_call);
%}
// ============================================================================
*** 12002,12054 ****
--- 8954,8978 ----
// ============================================================================
// inlined locking and unlocking
#ifdef AARCH64
instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 )
#else
instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch )
#endif
%{
match(Set pcc (FastLock object box));
#ifdef AARCH64
effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
#else
effect(TEMP scratch, TEMP scratch2);
#endif
ins_cost(100);
#ifdef AARCH64
format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $scratch3" %}
ins_encode %{
__ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
%}
#else
format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2" %}
ins_encode %{
__ fast_lock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
%}
#endif
ins_pipe(long_memory_op);
%}
#ifdef AARCH64
instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch, iRegP scratch3 ) %{
match(Set pcc (FastUnlock object box));
effect(TEMP scratch, TEMP scratch2, TEMP scratch3);
ins_cost(100);
format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $scratch3" %}
ins_encode %{
__ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register, $scratch3$$Register);
%}
ins_pipe(long_memory_op);
%}
#else
instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, iRegP scratch ) %{
match(Set pcc (FastUnlock object box));
effect(TEMP scratch, TEMP scratch2);
ins_cost(100);
*** 12056,12107 ****
--- 8980,8990 ----
ins_encode %{
__ fast_unlock($object$$Register, $box$$Register, $scratch$$Register, $scratch2$$Register);
%}
ins_pipe(long_memory_op);
%}
#endif
#ifdef AARCH64
// TODO: add version that takes immI cnt?
instruct clear_array(iRegX cnt, iRegP base, iRegP ptr, iRegX temp, Universe dummy, flagsReg cpsr) %{
match(Set dummy (ClearArray cnt base));
effect(TEMP temp, TEMP ptr, KILL cpsr);
ins_cost(300);
format %{
" MOV $temp,$cnt\n"
" ADD $ptr,$base,$cnt\n"
" SUBS $temp,$temp,16\t! Count down dword pair in bytes\n"
" B.lt done16\n"
"loop: STP ZR,ZR,[$ptr,-16]!\n"
" SUBS $temp,$temp,16\t! Count down dword pair in bytes\n"
" B.ge loop\t! Clearing loop\n"
"done16: ADDS $temp,$temp,8\t! Room for 1 more long?\n"
" B.lt done\n"
" STR ZR,[$base+$temp]\n"
"done:"
%}
ins_encode %{
// TODO: preload?
__ mov($temp$$Register, $cnt$$Register);
__ add($ptr$$Register, $base$$Register, $cnt$$Register);
Label loop, done, done16;
__ subs($temp$$Register, $temp$$Register, 16);
__ b(done16, lt);
__ bind(loop);
__ stp(ZR, ZR, Address($ptr$$Register, -16, pre_indexed));
__ subs($temp$$Register, $temp$$Register, 16);
__ b(loop, ge);
__ bind(done16);
__ adds($temp$$Register, $temp$$Register, 8);
__ b(done, lt);
// $temp should be 0 here
__ str(ZR, Address($base$$Register, $temp$$Register));
__ bind(done);
%}
ins_pipe(long_memory_op);
%}
#else
// Count and Base registers are fixed because the allocator cannot
// kill unknown registers. The encodings are generic.
instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dummy, flagsReg cpsr) %{
match(Set dummy (ClearArray cnt base));
effect(TEMP temp, TEMP zero, KILL cpsr);
*** 12120,12130 ****
--- 9003,9012 ----
__ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
__ b(loop, gt);
%}
ins_pipe(long_memory_op);
%}
#endif
#ifdef XXX
// FIXME: Why R0/R1/R2/R3?
instruct string_compare(R0RegP str1, R1RegP str2, R2RegI cnt1, R3RegI cnt2, iRegI result,
iRegI tmp1, iRegI tmp2, flagsReg ccr) %{
*** 12175,12195 ****
--- 9057,9066 ----
__ clz_32($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
#ifdef AARCH64
instruct countLeadingZerosL(iRegI dst, iRegL src) %{
match(Set dst (CountLeadingZerosL src));
size(4);
format %{ "CLZ $dst,$src" %}
ins_encode %{
__ clz($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg);
%}
#else
instruct countLeadingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
match(Set dst (CountLeadingZerosL src));
effect(TEMP tmp, TEMP dst, KILL ccr);
size(16);
format %{ "CLZ $dst,$src.hi\n\t"
*** 12202,12212 ****
--- 9073,9082 ----
__ clz($tmp$$Register, $src$$Register, eq);
__ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
%}
ins_pipe(ialu_reg);
%}
#endif
instruct countTrailingZerosI(iRegI dst, iRegI src, iRegI tmp) %{
match(Set dst (CountTrailingZerosI src));
effect(TEMP tmp);
size(8);
*** 12217,12240 ****
--- 9087,9096 ----
__ clz_32($dst$$Register, $tmp$$Register);
%}
ins_pipe(ialu_reg);
%}
#ifdef AARCH64
instruct countTrailingZerosL(iRegI dst, iRegL src, iRegL tmp) %{
match(Set dst (CountTrailingZerosL src));
effect(TEMP tmp);
size(8);
format %{ "RBIT $tmp, $src\n\t"
"CLZ $dst,$tmp" %}
ins_encode %{
__ rbit($tmp$$Register, $src$$Register);
__ clz($dst$$Register, $tmp$$Register);
%}
ins_pipe(ialu_reg);
%}
#else
instruct countTrailingZerosL(iRegI dst, iRegL src, iRegI tmp, flagsReg ccr) %{
match(Set dst (CountTrailingZerosL src));
effect(TEMP tmp, TEMP dst, KILL ccr);
size(24);
format %{ "RBIT $tmp,$src.lo\n\t"
*** 12251,12291 ****
--- 9107,9120 ----
__ clz($tmp$$Register, $tmp$$Register, eq);
__ add($dst$$Register, $dst$$Register, $tmp$$Register, eq);
%}
ins_pipe(ialu_reg);
%}
#endif
//---------- Population Count Instructions -------------------------------------
#ifdef AARCH64
instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountI src));
effect(TEMP tmp);
size(20);
format %{ "MOV_W $dst,$src\n\t"
"FMOV_dx $tmp,$dst\n\t"
"VCNT $tmp.8B,$tmp.8B\n\t"
"ADDV $tmp.B,$tmp.8B\n\t"
"FMRS $dst,$tmp" %}
ins_encode %{
__ mov_w($dst$$Register, $src$$Register);
__ fmov_dx($tmp$$FloatRegister, $dst$$Register);
int quad = 0;
int cnt_size = 0; // VELEM_SIZE_8
__ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
int add_size = 0; // VELEM_SIZE_8
__ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
__ fmrs($dst$$Register, $tmp$$FloatRegister);
%}
ins_pipe(ialu_reg); // FIXME
%}
#else
instruct popCountI(iRegI dst, iRegI src, regD_low tmp) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountI src));
effect(TEMP tmp);
*** 12303,12338 ****
--- 9132,9142 ----
__ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 16, 0);
__ fmrs($dst$$Register, $tmp$$FloatRegister);
%}
ins_pipe(ialu_reg); // FIXME
%}
#endif
#ifdef AARCH64
instruct popCountL(iRegI dst, iRegL src, regD tmp) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountL src));
effect(TEMP tmp);
size(16);
format %{ "FMOV_dx $tmp,$src\n\t"
"VCNT $tmp.8B,$tmp.8B\n\t"
"ADDV $tmp.B,$tmp.8B\n\t"
"FMOV_ws $dst,$tmp" %}
ins_encode %{
__ fmov_dx($tmp$$FloatRegister, $src$$Register);
int quad = 0;
int cnt_size = 0;
__ vcnt($tmp$$FloatRegister, $tmp$$FloatRegister, quad, cnt_size);
int add_size = 0;
__ addv($tmp$$FloatRegister, $tmp$$FloatRegister, quad, add_size);
__ fmov_ws($dst$$Register, $tmp$$FloatRegister);
%}
ins_pipe(ialu_reg); // FIXME
%}
#else
// Note: Long.bitCount(long) returns an int.
instruct popCountL(iRegI dst, iRegL src, regD_low tmp) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountL src));
effect(TEMP tmp);
*** 12354,12364 ****
--- 9158,9167 ----
__ vpaddl($tmp$$FloatRegister, $tmp$$FloatRegister, 32, 0);
__ fmrs($dst$$Register, $tmp$$FloatRegister);
%}
ins_pipe(ialu_reg);
%}
#endif
// ============================================================================
//------------Bytes reverse--------------------------------------------------
*** 12366,12443 ****
--- 9169,9213 ----
match(Set dst (ReverseBytesI src));
size(4);
format %{ "REV32 $dst,$src" %}
ins_encode %{
#ifdef AARCH64
__ rev_w($dst$$Register, $src$$Register);
// high 32 bits zeroed, not sign extended
#else
__ rev($dst$$Register, $src$$Register);
#endif
%}
ins_pipe( iload_mem ); // FIXME
%}
instruct bytes_reverse_long(iRegL dst, iRegL src) %{
match(Set dst (ReverseBytesL src));
#ifdef AARCH64
//size(4);
format %{ "REV $dst,$src" %}
ins_encode %{
__ rev($dst$$Register, $src$$Register);
%}
ins_pipe(ialu_reg_reg); // FIXME
#else
effect(TEMP dst);
size(8);
format %{ "REV $dst.lo,$src.lo\n\t"
"REV $dst.hi,$src.hi" %}
ins_encode %{
__ rev($dst$$Register, $src$$Register->successor());
__ rev($dst$$Register->successor(), $src$$Register);
%}
ins_pipe( iload_mem ); // FIXME
#endif
%}
instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
match(Set dst (ReverseBytesUS src));
#ifdef AARCH64
size(4);
format %{ "REV16_W $dst,$src" %}
ins_encode %{
__ rev16_w($dst$$Register, $src$$Register);
// high 32 bits zeroed
%}
#else
size(4);
format %{ "REV16 $dst,$src" %}
ins_encode %{
__ rev16($dst$$Register, $src$$Register);
%}
#endif
ins_pipe( iload_mem ); // FIXME
%}
instruct bytes_reverse_short(iRegI dst, iRegI src) %{
match(Set dst (ReverseBytesS src));
#ifdef AARCH64
size(8);
format %{ "REV16_W $dst,$src\n\t"
"SIGN_EXT16 $dst" %}
ins_encode %{
__ rev16_w($dst$$Register, $src$$Register);
__ sign_extend($dst$$Register, $dst$$Register, 16);
%}
#else
size(4);
format %{ "REVSH $dst,$src" %}
ins_encode %{
__ revsh($dst$$Register, $src$$Register);
%}
#endif
ins_pipe( iload_mem ); // FIXME
%}
// ====================VECTOR INSTRUCTIONS=====================================
*** 12492,12502 ****
--- 9262,9271 ----
__ vst1($src$$FloatRegister, $mem$$Address, MacroAssembler::VELEM_SIZE_16, 128);
%}
ins_pipe(fstoreD_mem_reg); // FIXME
%}
#ifndef AARCH64
// Replicate scalar to packed byte values in Double register
instruct Repl8B_reg(vecD dst, iRegI src, iRegI tmp) %{
predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateB src));
ins_cost(DEFAULT_COST*4);
*** 12514,12524 ****
--- 9283,9292 ----
__ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
__ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
%}
ins_pipe(ialu_reg); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar to packed byte values in Double register
instruct Repl8B_reg_simd(vecD dst, iRegI src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
match(Set dst (ReplicateB src));
*** 12546,12556 ****
--- 9314,9323 ----
MacroAssembler::VELEM_SIZE_8, quad);
%}
ins_pipe(ialu_reg); // FIXME
%}
#ifndef AARCH64
// Replicate scalar constant to packed byte values in Double register
instruct Repl8B_immI(vecD dst, immI src, iRegI tmp) %{
predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateB src));
ins_cost(DEFAULT_COST*2);
*** 12560,12570 ****
--- 9327,9336 ----
format %{ "MOV $tmp, Repl4($src))\n\t"
"FMDRR $dst,$tmp,$tmp\t" %}
ins_encode( LdReplImmI(src, dst, tmp, (4), (1)) );
ins_pipe(loadConFD); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar constant to packed byte values in Double register
// TODO: support negative constants with MVNI?
instruct Repl8B_immU8(vecD dst, immU8 src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
*** 12593,12603 ****
--- 9359,9368 ----
MacroAssembler::VELEM_SIZE_8, quad);
%}
ins_pipe(loadConFD); // FIXME
%}
#ifndef AARCH64
// Replicate scalar to packed short/char values into Double register
instruct Repl4S_reg(vecD dst, iRegI src, iRegI tmp) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateS src));
ins_cost(DEFAULT_COST*3);
*** 12613,12623 ****
--- 9378,9387 ----
__ orr($tmp$$Register, $tmp$$Register, AsmOperand($tmp$$Register, lsr, 16));
__ fmdrr($dst$$FloatRegister, $tmp$$Register, $tmp$$Register);
%}
ins_pipe(ialu_reg); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar to packed byte values in Double register
instruct Repl4S_reg_simd(vecD dst, iRegI src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
match(Set dst (ReplicateS src));
*** 12646,12656 ****
--- 9410,9419 ----
%}
ins_pipe(ialu_reg); // FIXME
%}
#ifndef AARCH64
// Replicate scalar constant to packed short/char values in Double register
instruct Repl4S_immI(vecD dst, immI src, iRegP tmp) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateS src));
effect(TEMP tmp);
*** 12660,12670 ****
--- 9423,9432 ----
format %{ "MOV $tmp, Repl2($src))\n\t"
"FMDRR $dst,$tmp,$tmp\t" %}
ins_encode( LdReplImmI(src, dst, tmp, (2), (2)) );
ins_pipe(loadConFD); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar constant to packed byte values in Double register
instruct Repl4S_immU8(vecD dst, immU8 src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
match(Set dst (ReplicateS src));
*** 12692,12702 ****
--- 9454,9463 ----
MacroAssembler::VELEM_SIZE_16, quad);
%}
ins_pipe(loadConFD); // FIXME
%}
#ifndef AARCH64
// Replicate scalar to packed int values in Double register
instruct Repl2I_reg(vecD dst, iRegI src) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateI src));
size(4);
*** 12723,12733 ****
--- 9484,9493 ----
__ fmdrr($dst$$FloatRegister->successor()->successor(),
$src$$Register, $src$$Register);
%}
ins_pipe(ialu_reg); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar to packed int values in Double register
instruct Repl2I_reg_simd(vecD dst, iRegI src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
match(Set dst (ReplicateI src));
*** 12756,12766 ****
--- 9516,9525 ----
%}
ins_pipe(ialu_reg); // FIXME
%}
#ifndef AARCH64
// Replicate scalar zero constant to packed int values in Double register
instruct Repl2I_immI(vecD dst, immI src, iRegI tmp) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateI src));
effect(TEMP tmp);
*** 12770,12780 ****
--- 9529,9538 ----
format %{ "MOV $tmp, Repl1($src))\n\t"
"FMDRR $dst,$tmp,$tmp\t" %}
ins_encode( LdReplImmI(src, dst, tmp, (1), (4)) );
ins_pipe(loadConFD); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar constant to packed byte values in Double register
instruct Repl2I_immU8(vecD dst, immU8 src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
match(Set dst (ReplicateI src));
*** 12802,12828 ****
--- 9560,9569 ----
MacroAssembler::VELEM_SIZE_32, quad);
%}
ins_pipe(loadConFD); // FIXME
%}
#ifdef AARCH64
// Replicate scalar to packed byte values in Double register pair
instruct Repl2L_reg(vecX dst, iRegL src) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateL src));
size(4*1);
ins_cost(DEFAULT_COST*1); // FIXME
format %{ "VDUP.2D $dst.Q,$src\t" %}
ins_encode %{
bool quad = true;
__ vdupI($dst$$FloatRegister, $src$$Register,
MacroAssembler::VELEM_SIZE_64, quad);
%}
ins_pipe(ialu_reg); // FIXME
%}
#else /* !AARCH64 */
// Replicate scalar to packed byte values in Double register pair
instruct Repl2L_reg(vecX dst, iRegL src) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateL src));
size(8);
*** 12863,12873 ****
--- 9604,9613 ----
iRegI tmp;
MoveF2I_reg_reg(tmp, src);
Repl2F_regI(dst,tmp);
%}
%}
#endif /* !AARCH64 */
// Replicate scalar to packed float values in Double register
instruct Repl2F_reg_simd(vecD dst, regF src) %{
predicate(n->as_Vector()->length_in_bytes() == 8 && VM_Version::has_simd());
match(Set dst (ReplicateF src));
*** 12880,12890 ****
--- 9620,9629 ----
__ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
%}
ins_pipe(ialu_reg); // FIXME
%}
#ifndef AARCH64
// Replicate scalar to packed float values in Double register pair
instruct Repl4F_reg(vecX dst, regF src, iRegI tmp) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateF src));
effect(TEMP tmp);
*** 12900,12910 ****
--- 9639,9648 ----
__ fmdrr($dst$$FloatRegister->successor()->successor(),
$tmp$$Register, $tmp$$Register);
%}
ins_pipe(ialu_reg); // FIXME
%}
#endif /* !AARCH64 */
// Replicate scalar to packed float values in Double register pair
instruct Repl4F_reg_simd(vecX dst, regF src) %{
predicate(n->as_Vector()->length_in_bytes() == 16 && VM_Version::has_simd());
match(Set dst (ReplicateF src));
*** 12917,12927 ****
--- 9655,9664 ----
__ vdupF($dst$$FloatRegister, $src$$FloatRegister, quad);
%}
ins_pipe(ialu_reg); // FIXME
%}
#ifndef AARCH64
// Replicate scalar zero constant to packed float values in Double register
instruct Repl2F_immI(vecD dst, immF src, iRegI tmp) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateF src));
effect(TEMP tmp);
*** 12931,12956 ****
--- 9668,9680 ----
format %{ "MOV $tmp, Repl1($src))\n\t"
"FMDRR $dst,$tmp,$tmp\t" %}
ins_encode( LdReplImmF(src, dst, tmp) );
ins_pipe(loadConFD); // FIXME
%}
#endif /* !AAARCH64 */
// Replicate scalar to packed double float values in Double register pair
instruct Repl2D_reg(vecX dst, regD src) %{
#ifdef AARCH64
predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
match(Set dst (ReplicateD src));
size(4*1);
ins_cost(DEFAULT_COST*1); // FIXME
format %{ "VDUP $dst.2D,$src\t" %}
ins_encode %{
bool quad = true;
__ vdupD($dst$$FloatRegister, $src$$FloatRegister, quad);
%}
#else
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateD src));
size(4*2);
ins_cost(DEFAULT_COST*2); // FIXME
*** 12961,12971 ****
--- 9685,9694 ----
FloatRegister src = $src$$FloatRegister;
__ fcpyd(dsta, src);
FloatRegister dstb = dsta->successor()->successor();
__ fcpyd(dstb, src);
%}
#endif
ins_pipe(ialu_reg); // FIXME
%}
// ====================VECTOR ARITHMETIC=======================================
*** 13078,13088 ****
--- 9801,9810 ----
MacroAssembler::VFA_SIZE_F32, quad);
%}
ins_pipe( faddD_reg_reg ); // FIXME
%}
#ifndef AARCH64
instruct vadd2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
match(Set dst (AddVF src1 src2));
ins_cost(DEFAULT_COST*2); // FIXME
*** 13096,13106 ****
--- 9818,9827 ----
$src2$$FloatRegister->successor());
%}
ins_pipe(faddF_reg_reg); // FIXME
%}
#endif
instruct vadd4F_reg_simd(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
match(Set dst (AddVF src1 src2));
size(4);
*** 13111,13134 ****
--- 9832,9841 ----
MacroAssembler::VFA_SIZE_F32, quad);
%}
ins_pipe( faddD_reg_reg ); // FIXME
%}
#ifdef AARCH64
instruct vadd2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
match(Set dst (AddVD src1 src2));
size(4);
format %{ "VADD.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
ins_encode %{
bool quad = true;
__ vaddF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
MacroAssembler::VFA_SIZE_F64, quad);
%}
ins_pipe( faddD_reg_reg ); // FIXME
%}
#else
instruct vadd4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
match(Set dst (AddVF src1 src2));
size(4*4);
ins_cost(DEFAULT_COST*4); // FIXME
*** 13180,13190 ****
--- 9887,9896 ----
__ add_double(dstb, src1b, src2b);
%}
ins_pipe(faddF_reg_reg); // FIXME
%}
#endif
// Bytes vector sub
instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
predicate(n->as_Vector()->length() == 8);
*** 13292,13302 ****
--- 9998,10007 ----
MacroAssembler::VFA_SIZE_F32, quad);
%}
ins_pipe( faddF_reg_reg ); // FIXME
%}
#ifndef AARCH64
instruct vsub2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
match(Set dst (SubVF src1 src2));
size(4*2);
ins_cost(DEFAULT_COST*2); // FIXME
*** 13315,13325 ****
--- 10020,10029 ----
__ sub_float(dstb, src1b, src2b);
%}
ins_pipe(faddF_reg_reg); // FIXME
%}
#endif
instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
match(Set dst (SubVF src1 src2));
*** 13331,13354 ****
--- 10035,10044 ----
MacroAssembler::VFA_SIZE_F32, quad);
%}
ins_pipe( faddF_reg_reg ); // FIXME
%}
#ifdef AARCH64
instruct vsub2D_reg_simd(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 2 && VM_Version::simd_math_is_compliant());
match(Set dst (SubVD src1 src2));
size(4);
format %{ "VSUB.F64 $dst.Q,$src1.Q,$src2.Q\t! add packed2D" %}
ins_encode %{
bool quad = true;
__ vsubF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
MacroAssembler::VFA_SIZE_F64, quad);
%}
ins_pipe( faddD_reg_reg ); // FIXME
%}
#else
instruct vsub4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
match(Set dst (SubVF src1 src2));
size(4*4);
ins_cost(DEFAULT_COST*4); // FIXME
*** 13400,13410 ****
--- 10090,10099 ----
__ sub_double(dstb, src1b, src2b);
%}
ins_pipe(faddF_reg_reg); // FIXME
%}
#endif
// Shorts/Chars vector mul
instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (MulVS src1 src2));
*** 13465,13475 ****
--- 10154,10163 ----
MacroAssembler::VFA_SIZE_F32, 0);
%}
ins_pipe( fmulF_reg_reg ); // FIXME
%}
#ifndef AARCH64
instruct vmul2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
predicate(n->as_Vector()->length() == 2 && !VM_Version::simd_math_is_compliant());
match(Set dst (MulVF src1 src2));
size(4*2);
ins_cost(DEFAULT_COST*2); // FIXME
*** 13483,13493 ****
--- 10171,10180 ----
$src2$$FloatRegister->successor());
%}
ins_pipe(fmulF_reg_reg); // FIXME
%}
#endif
instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4 && VM_Version::simd_math_is_compliant());
match(Set dst (MulVF src1 src2));
size(4);
*** 13497,13507 ****
--- 10184,10193 ----
MacroAssembler::VFA_SIZE_F32, 1);
%}
ins_pipe( fmulF_reg_reg ); // FIXME
%}
#ifndef AARCH64
instruct vmul4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4 && !VM_Version::simd_math_is_compliant());
match(Set dst (MulVF src1 src2));
size(4*4);
ins_cost(DEFAULT_COST*4); // FIXME
*** 13530,13558 ****
--- 10216,10226 ----
__ mul_float(dstd, src1d, src2d);
%}
ins_pipe(fmulF_reg_reg); // FIXME
%}
#endif
#ifdef AARCH64
instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
match(Set dst (MulVD src1 src2));
size(4*1);
ins_cost(DEFAULT_COST*1); // FIXME
format %{ "FMUL.2D $dst,$src1,$src2\t! double[2]" %}
ins_encode %{
int quad = 1;
__ vmulF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
MacroAssembler::VFA_SIZE_F64, quad);
%}
ins_pipe(fdivF_reg_reg); // FIXME
%}
#else
instruct vmul2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (MulVD src1 src2));
size(4*2);
ins_cost(DEFAULT_COST*2); // FIXME
*** 13570,13599 ****
--- 10238,10253 ----
__ mul_double(dstb, src1b, src2b);
%}
ins_pipe(fmulD_reg_reg); // FIXME
%}
#endif
// Floats vector div
instruct vdiv2F_reg_vfp(vecD dst, vecD src1, vecD src2) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (DivVF src1 src2));
#ifdef AARCH64
size(4*1);
ins_cost(DEFAULT_COST*1); // FIXME
format %{ "FDIV.2S $dst,$src1,$src2\t! float[2]" %}
ins_encode %{
int quad = 0;
__ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
MacroAssembler::VFA_SIZE_F32, quad);
%}
ins_pipe(fdivF_reg_reg); // FIXME
#else
size(4*2);
ins_cost(DEFAULT_COST*2); // FIXME
format %{ "FDIVS $dst.a,$src1.a,$src2.a\n\t"
"FDIVS $dst.b,$src1.b,$src2.b" %}
*** 13603,13631 ****
--- 10257,10271 ----
$src1$$FloatRegister->successor(),
$src2$$FloatRegister->successor());
%}
ins_pipe(fdivF_reg_reg); // FIXME
#endif
%}
instruct vdiv4F_reg_vfp(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (DivVF src1 src2));
#ifdef AARCH64
size(4*1);
ins_cost(DEFAULT_COST*1); // FIXME
format %{ "FDIV.4S $dst,$src1,$src2\t! float[4]" %}
ins_encode %{
int quad = 1;
__ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
MacroAssembler::VFA_SIZE_F32, quad);
%}
ins_pipe(fdivF_reg_reg); // FIXME
#else
size(4*4);
ins_cost(DEFAULT_COST*4); // FIXME
format %{ "FDIVS $dst.a,$src1.a,$src2.a\n\t"
"FDIVS $dst.b,$src1.b,$src2.b\n\t"
*** 13650,13679 ****
--- 10290,10301 ----
FloatRegister src2d = src2c->successor();
__ div_float(dstd, src1d, src2d);
%}
ins_pipe(fdivF_reg_reg); // FIXME
#endif
%}
#ifdef AARCH64
instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 2 && VM_Version::has_simd());
match(Set dst (DivVD src1 src2));
size(4*1);
ins_cost(DEFAULT_COST*1); // FIXME
format %{ "FDIV.2D $dst,$src1,$src2\t! double[2]" %}
ins_encode %{
int quad = 1;
__ vdivF($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister,
MacroAssembler::VFA_SIZE_F64, quad);
%}
ins_pipe(fdivF_reg_reg); // FIXME
%}
#else
instruct vdiv2D_reg_vfp(vecX dst, vecX src1, vecX src2) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (DivVD src1 src2));
size(4*2);
ins_cost(DEFAULT_COST*2); // FIXME
*** 13691,13701 ****
--- 10313,10322 ----
__ div_double(dstb, src1b, src2b);
%}
ins_pipe(fdivD_reg_reg); // FIXME
%}
#endif
// --------------------------------- NEG --------------------------------------
instruct vneg8B_reg(vecD dst, vecD src) %{
predicate(n->as_Vector()->length_in_bytes() == 8);
src/hotspot/cpu/arm/arm.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File