This commit is contained in:
Peter Levart 2018-06-22 18:18:05 +02:00
commit 169fb73c0c
2 changed files with 29 additions and 40 deletions

View File

@ -1638,12 +1638,14 @@ void mvnw(Register Rd, Register Rm,
#undef INSN #undef INSN
// Conditional compare (both kinds) // Conditional compare (both kinds)
void conditional_compare(unsigned op, int o2, int o3, void conditional_compare(unsigned op, int o1, int o2, int o3,
Register Rn, unsigned imm5, unsigned nzcv, Register Rn, unsigned imm5, unsigned nzcv,
unsigned cond) { unsigned cond) {
starti;
f(op, 31, 29); f(op, 31, 29);
f(0b11010010, 28, 21); f(0b11010010, 28, 21);
f(cond, 15, 12); f(cond, 15, 12);
f(o1, 11);
f(o2, 10); f(o2, 10);
f(o3, 4); f(o3, 4);
f(nzcv, 3, 0); f(nzcv, 3, 0);
@ -1652,15 +1654,12 @@ void mvnw(Register Rd, Register Rm,
#define INSN(NAME, op) \ #define INSN(NAME, op) \
void NAME(Register Rn, Register Rm, int imm, Condition cond) { \ void NAME(Register Rn, Register Rm, int imm, Condition cond) { \
starti; \ int regNumber = (Rm == zr ? 31 : (uintptr_t)Rm); \
f(0, 11); \ conditional_compare(op, 0, 0, 0, Rn, regNumber, imm, cond); \
conditional_compare(op, 0, 0, Rn, (uintptr_t)Rm, imm, cond); \
} \ } \
\ \
void NAME(Register Rn, int imm5, int imm, Condition cond) { \ void NAME(Register Rn, int imm5, int imm, Condition cond) { \
starti; \ conditional_compare(op, 1, 0, 0, Rn, imm5, imm, cond); \
f(1, 11); \
conditional_compare(op, 0, 0, Rn, imm5, imm, cond); \
} }
INSN(ccmnw, 0b001); INSN(ccmnw, 0b001);

View File

@ -4928,9 +4928,8 @@ void MacroAssembler::has_negatives(Register ary1, Register len, Register result)
void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3, void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
Register tmp4, Register tmp5, Register result, Register tmp4, Register tmp5, Register result,
Register cnt1, int elem_size) Register cnt1, int elem_size) {
{ Label DONE, SAME;
Label DONE;
Register tmp1 = rscratch1; Register tmp1 = rscratch1;
Register tmp2 = rscratch2; Register tmp2 = rscratch2;
Register cnt2 = tmp2; // cnt2 only used in array length compare Register cnt2 = tmp2; // cnt2 only used in array length compare
@ -4952,21 +4951,21 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
BLOCK_COMMENT(comment); BLOCK_COMMENT(comment);
} }
#endif #endif
if (UseSimpleArrayEquals) {
Label NEXT_WORD, SHORT, SAME, TAIL03, TAIL01, A_MIGHT_BE_NULL, A_IS_NOT_NULL; // if (a1 == a2)
// if (a1==a2)
// return true; // return true;
// if (a==null || a2==null) cmpoop(a1, a2); // May have read barriers for a1 and a2.
br(EQ, SAME);
if (UseSimpleArrayEquals) {
Label NEXT_WORD, SHORT, TAIL03, TAIL01, A_MIGHT_BE_NULL, A_IS_NOT_NULL;
// if (a1 == null || a2 == null)
// return false; // return false;
// a1 & a2 == 0 means (some-pointer is null) or // a1 & a2 == 0 means (some-pointer is null) or
// (very-rare-or-even-probably-impossible-pointer-values) // (very-rare-or-even-probably-impossible-pointer-values)
// so, we can save one branch in most cases // so, we can save one branch in most cases
cmpoop(a1, a2);
br(EQ, SAME);
eor(rscratch1, a1, a2);
tst(a1, a2); tst(a1, a2);
mov(result, false); mov(result, false);
cbz(rscratch1, SAME);
br(EQ, A_MIGHT_BE_NULL); br(EQ, A_MIGHT_BE_NULL);
// if (a1.length != a2.length) // if (a1.length != a2.length)
// return false; // return false;
@ -5032,22 +5031,18 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
cbnzw(tmp5, DONE); cbnzw(tmp5, DONE);
} }
} }
bind(SAME);
mov(result, true);
} else { } else {
Label NEXT_DWORD, A_IS_NULL, SHORT, TAIL, TAIL2, STUB, EARLY_OUT, Label NEXT_DWORD, SHORT, TAIL, TAIL2, STUB, EARLY_OUT,
CSET_EQ, LAST_CHECK, LEN_IS_ZERO, SAME; CSET_EQ, LAST_CHECK;
cbz(a1, A_IS_NULL);
ldrw(cnt1, Address(a1, length_offset));
cbz(a2, A_IS_NULL);
ldrw(cnt2, Address(a2, length_offset));
mov(result, false); mov(result, false);
cbz(a1, DONE);
ldrw(cnt1, Address(a1, length_offset));
cbz(a2, DONE);
ldrw(cnt2, Address(a2, length_offset));
// on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's // on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's
// faster to perform another branch before comparing a1 and a2 // faster to perform another branch before comparing a1 and a2
cmp(cnt1, elem_per_word); cmp(cnt1, elem_per_word);
br(LE, SHORT); // short or same br(LE, SHORT); // short or same
cmpoop(a1, a2);
br(EQ, SAME);
ldr(tmp3, Address(pre(a1, base_offset))); ldr(tmp3, Address(pre(a1, base_offset)));
cmp(cnt1, stubBytesThreshold); cmp(cnt1, stubBytesThreshold);
br(GE, STUB); br(GE, STUB);
@ -5099,23 +5094,15 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
trampoline_call(stub); trampoline_call(stub);
b(DONE); b(DONE);
bind(SAME);
mov(result, true);
b(DONE);
bind(A_IS_NULL);
// a1 or a2 is null. if a2 == a2 then return true. else return false
cmp(a1, a2);
b(CSET_EQ);
bind(EARLY_OUT); bind(EARLY_OUT);
// (a1 != null && a2 == null) || (a1 != null && a2 != null && a1 == a2) // (a1 != null && a2 == null) || (a1 != null && a2 != null && a1 == a2)
// so, if a2 == null => return false(0), else return true, so we can return a2 // so, if a2 == null => return false(0), else return true, so we can return a2
mov(result, a2); mov(result, a2);
b(DONE); b(DONE);
bind(LEN_IS_ZERO);
cmp(cnt2, zr);
b(CSET_EQ);
bind(SHORT); bind(SHORT);
cbz(cnt1, LEN_IS_ZERO); cmp(cnt2, cnt1);
br(NE, DONE);
cbz(cnt1, SAME);
sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size); sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
ldr(tmp3, Address(a1, base_offset)); ldr(tmp3, Address(a1, base_offset));
ldr(tmp4, Address(a2, base_offset)); ldr(tmp4, Address(a2, base_offset));
@ -5125,8 +5112,11 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
cmp(tmp5, zr); cmp(tmp5, zr);
bind(CSET_EQ); bind(CSET_EQ);
cset(result, EQ); cset(result, EQ);
b(DONE);
} }
bind(SAME);
mov(result, true);
// That's it. // That's it.
bind(DONE); bind(DONE);