8213754: PPC64: Add Intrinsics for isDigit/isLowerCase/isUpperCase/isWhitespace
Reviewed-by: kvn, rriggs, mdoerr, gromero
This commit is contained in:
parent
d1ef9b19d7
commit
31fbc28af5
@ -754,6 +754,21 @@ class CharacterData00 extends CharacterData {
|
||||
return retval;
|
||||
}
|
||||
|
||||
boolean isDigit(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
|
||||
}
|
||||
|
||||
boolean isLowerCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.LOWERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isUpperCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.UPPERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isWhitespace(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
|
||||
|
@ -460,6 +460,21 @@ class CharacterData01 extends CharacterData {
|
||||
return retval;
|
||||
}
|
||||
|
||||
boolean isDigit(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
|
||||
}
|
||||
|
||||
boolean isLowerCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.LOWERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isUpperCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.UPPERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isWhitespace(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -217,6 +217,21 @@ class CharacterData02 extends CharacterData {
|
||||
return retval;
|
||||
}
|
||||
|
||||
boolean isDigit(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
|
||||
}
|
||||
|
||||
boolean isLowerCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.LOWERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isUpperCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.UPPERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isWhitespace(int ch) {
|
||||
return (getProperties(ch) & $$maskIdentifierInfo) == $$valueJavaWhitespace;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -217,6 +217,21 @@ class CharacterData0E extends CharacterData {
|
||||
return retval;
|
||||
}
|
||||
|
||||
boolean isDigit(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.DECIMAL_DIGIT_NUMBER;
|
||||
}
|
||||
|
||||
boolean isLowerCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.LOWERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isUpperCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.UPPERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isWhitespace(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package java.lang;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
|
||||
/** The CharacterData class encapsulates the large tables found in
|
||||
Java.lang.Character. */
|
||||
|
||||
@ -78,6 +80,23 @@ class CharacterDataLatin1 extends CharacterData {
|
||||
return props;
|
||||
}
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
boolean isDigit(int ch) {
|
||||
return '0' <= ch && ch <= '9';
|
||||
}
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
boolean isLowerCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.LOWERCASE_LETTER;
|
||||
}
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
boolean isUpperCase(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return (props & $$maskType) == Character.UPPERCASE_LETTER;
|
||||
}
|
||||
|
||||
boolean isOtherLowercase(int ch) {
|
||||
int props = getPropertiesEx(ch);
|
||||
return (props & $$maskOtherLowercase) != 0;
|
||||
@ -214,6 +233,7 @@ class CharacterDataLatin1 extends CharacterData {
|
||||
return retval;
|
||||
}
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
boolean isWhitespace(int ch) {
|
||||
int props = getProperties(ch);
|
||||
return ((props & $$maskIdentifierInfo) == $$valueJavaWhitespace);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,47 +41,59 @@ class CharacterDataPrivateUse extends CharacterData {
|
||||
}
|
||||
|
||||
boolean isJavaIdentifierStart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isJavaIdentifierPart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isUnicodeIdentifierStart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isUnicodeIdentifierPart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isIdentifierIgnorable(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
int toLowerCase(int ch) {
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int toUpperCase(int ch) {
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int toTitleCase(int ch) {
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int digit(int ch, int radix) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getNumericValue(int ch) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
boolean isDigit(int ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isLowerCase(int ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isUpperCase(int ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isWhitespace(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte getDirectionality(int ch) {
|
||||
@ -91,7 +103,7 @@ class CharacterDataPrivateUse extends CharacterData {
|
||||
}
|
||||
|
||||
boolean isMirrored(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static final CharacterData instance = new CharacterDataPrivateUse();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,59 +35,71 @@ class CharacterDataUndefined extends CharacterData {
|
||||
}
|
||||
|
||||
int getType(int ch) {
|
||||
return Character.UNASSIGNED;
|
||||
return Character.UNASSIGNED;
|
||||
}
|
||||
|
||||
boolean isJavaIdentifierStart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isJavaIdentifierPart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isUnicodeIdentifierStart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isUnicodeIdentifierPart(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isIdentifierIgnorable(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
int toLowerCase(int ch) {
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int toUpperCase(int ch) {
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int toTitleCase(int ch) {
|
||||
return ch;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int digit(int ch, int radix) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getNumericValue(int ch) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
boolean isDigit(int ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isLowerCase(int ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isUpperCase(int ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isWhitespace(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte getDirectionality(int ch) {
|
||||
return Character.DIRECTIONALITY_UNDEFINED;
|
||||
return Character.DIRECTIONALITY_UNDEFINED;
|
||||
}
|
||||
|
||||
boolean isMirrored(int ch) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static final CharacterData instance = new CharacterDataUndefined();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -299,6 +299,8 @@ class Assembler : public AbstractAssembler {
|
||||
CMPI_OPCODE = (11u << OPCODE_SHIFT),
|
||||
CMPL_OPCODE = (31u << OPCODE_SHIFT | 32u << 1),
|
||||
CMPLI_OPCODE = (10u << OPCODE_SHIFT),
|
||||
CMPRB_OPCODE = (31u << OPCODE_SHIFT | 192u << 1),
|
||||
CMPEQB_OPCODE = (31u << OPCODE_SHIFT | 224u << 1),
|
||||
|
||||
ISEL_OPCODE = (31u << OPCODE_SHIFT | 15u << 1),
|
||||
|
||||
@ -336,6 +338,7 @@ class Assembler : public AbstractAssembler {
|
||||
MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1),
|
||||
MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1),
|
||||
MCRF_OPCODE = (19u << OPCODE_SHIFT | 0u << 1),
|
||||
SETB_OPCODE = (31u << OPCODE_SHIFT | 128u << 1),
|
||||
|
||||
// condition register logic instructions
|
||||
CRAND_OPCODE = (19u << OPCODE_SHIFT | 257u << 1),
|
||||
@ -1076,7 +1079,7 @@ class Assembler : public AbstractAssembler {
|
||||
static int frs( int x) { return opp_u_field(x, 10, 6); }
|
||||
static int frt( int x) { return opp_u_field(x, 10, 6); }
|
||||
static int fxm( int x) { return opp_u_field(x, 19, 12); }
|
||||
static int l10( int x) { return opp_u_field(x, 10, 10); }
|
||||
static int l10( int x) { assert(x == 0 || x == 1, "must be 0 or 1"); return opp_u_field(x, 10, 10); }
|
||||
static int l14( int x) { return opp_u_field(x, 15, 14); }
|
||||
static int l15( int x) { return opp_u_field(x, 15, 15); }
|
||||
static int l910( int x) { return opp_u_field(x, 10, 9); }
|
||||
@ -1443,6 +1446,10 @@ class Assembler : public AbstractAssembler {
|
||||
inline void cmplw( ConditionRegister crx, Register a, Register b);
|
||||
inline void cmpld( ConditionRegister crx, Register a, Register b);
|
||||
|
||||
// >= Power9
|
||||
inline void cmprb( ConditionRegister bf, int l, Register a, Register b);
|
||||
inline void cmpeqb(ConditionRegister bf, Register a, Register b);
|
||||
|
||||
inline void isel( Register d, Register a, Register b, int bc);
|
||||
// Convenient version which takes: Condition register, Condition code and invert flag. Omit b to keep old value.
|
||||
inline void isel( Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b = noreg);
|
||||
@ -1642,6 +1649,8 @@ class Assembler : public AbstractAssembler {
|
||||
inline void mfcr( Register d);
|
||||
inline void mcrf( ConditionRegister crd, ConditionRegister cra);
|
||||
inline void mtcr( Register s);
|
||||
// >= Power9
|
||||
inline void setb( Register d, ConditionRegister cra);
|
||||
|
||||
// Special purpose registers
|
||||
// Exception Register
|
||||
|
@ -171,6 +171,8 @@ inline void Assembler::cmpi( ConditionRegister f, int l, Register a, int si16)
|
||||
inline void Assembler::cmp( ConditionRegister f, int l, Register a, Register b) { emit_int32( CMP_OPCODE | bf(f) | l10(l) | ra(a) | rb(b)); }
|
||||
inline void Assembler::cmpli( ConditionRegister f, int l, Register a, int ui16) { emit_int32( CMPLI_OPCODE | bf(f) | l10(l) | ra(a) | uimm(ui16,16)); }
|
||||
inline void Assembler::cmpl( ConditionRegister f, int l, Register a, Register b) { emit_int32( CMPL_OPCODE | bf(f) | l10(l) | ra(a) | rb(b)); }
|
||||
inline void Assembler::cmprb( ConditionRegister f, int l, Register a, Register b) { emit_int32( CMPRB_OPCODE | bf(f) | l10(l) | ra(a) | rb(b)); }
|
||||
inline void Assembler::cmpeqb(ConditionRegister f, Register a, Register b) { emit_int32( CMPEQB_OPCODE| bf(f) | ra(a) | rb(b)); }
|
||||
|
||||
// extended mnemonics of Compare Instructions
|
||||
inline void Assembler::cmpwi( ConditionRegister crx, Register a, int si16) { Assembler::cmpi( crx, 0, a, si16); }
|
||||
@ -371,6 +373,8 @@ inline void Assembler::mfcr( Register d ) { emit_int32(MFCR_OPCODE | rt
|
||||
inline void Assembler::mcrf( ConditionRegister crd, ConditionRegister cra)
|
||||
{ emit_int32(MCRF_OPCODE | bf(crd) | bfa(cra)); }
|
||||
inline void Assembler::mtcr( Register s) { Assembler::mtcrf(0xff, s); }
|
||||
inline void Assembler::setb(Register d, ConditionRegister cra)
|
||||
{ emit_int32(SETB_OPCODE | rt(d) | bfa(cra)); }
|
||||
|
||||
// Special purpose registers
|
||||
// Exception Register
|
||||
|
@ -2257,6 +2257,11 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||
return SuperwordUseVSX;
|
||||
case Op_PopCountVI:
|
||||
return (SuperwordUseVSX && UsePopCountInstruction);
|
||||
case Op_Digit:
|
||||
case Op_LowerCase:
|
||||
case Op_UpperCase:
|
||||
case Op_Whitespace:
|
||||
return UseCharacterCompareIntrinsics;
|
||||
}
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
@ -12400,6 +12405,132 @@ instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{
|
||||
%}
|
||||
%}
|
||||
|
||||
// Compare char
|
||||
instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
|
||||
match(Set dst (Digit src1));
|
||||
effect(TEMP src2, TEMP crx);
|
||||
ins_cost(3 * DEFAULT_COST);
|
||||
|
||||
format %{ "LI $src2, 0x3930\n\t"
|
||||
"CMPRB $crx, 0, $src1, $src2\n\t"
|
||||
"SETB $dst, $crx" %}
|
||||
size(12);
|
||||
ins_encode %{
|
||||
// 0x30: 0, 0x39: 9
|
||||
__ li($src2$$Register, 0x3930);
|
||||
// compare src1 with ranges 0x30 to 0x39
|
||||
__ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
|
||||
__ setb($dst$$Register, $crx$$CondRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
|
||||
match(Set dst (LowerCase src1));
|
||||
effect(TEMP src2, TEMP crx);
|
||||
ins_cost(12 * DEFAULT_COST);
|
||||
|
||||
format %{ "LI $src2, 0x7A61\n\t"
|
||||
"CMPRB $crx, 0, $src1, $src2\n\t"
|
||||
"BGT $crx, done\n\t"
|
||||
"LIS $src2, (signed short)0xF6DF\n\t"
|
||||
"ORI $src2, $src2, 0xFFF8\n\t"
|
||||
"CMPRB $crx, 1, $src1, $src2\n\t"
|
||||
"BGT $crx, done\n\t"
|
||||
"LIS $src2, (signed short)0xAAB5\n\t"
|
||||
"ORI $src2, $src2, 0xBABA\n\t"
|
||||
"INSRDI $src2, $src2, 32, 0\n\t"
|
||||
"CMPEQB $crx, 1, $src1, $src2\n"
|
||||
"done:\n\t"
|
||||
"SETB $dst, $crx" %}
|
||||
|
||||
size(48);
|
||||
ins_encode %{
|
||||
Label done;
|
||||
// 0x61: a, 0x7A: z
|
||||
__ li($src2$$Register, 0x7A61);
|
||||
// compare src1 with ranges 0x61 to 0x7A
|
||||
__ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
|
||||
__ bgt($crx$$CondRegister, done);
|
||||
|
||||
// 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case
|
||||
__ lis($src2$$Register, (signed short)0xF6DF);
|
||||
__ ori($src2$$Register, $src2$$Register, 0xFFF8);
|
||||
// compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF
|
||||
__ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
|
||||
__ bgt($crx$$CondRegister, done);
|
||||
|
||||
// 0xAA: feminine ordinal indicator
|
||||
// 0xB5: micro sign
|
||||
// 0xBA: masculine ordinal indicator
|
||||
__ lis($src2$$Register, (signed short)0xAAB5);
|
||||
__ ori($src2$$Register, $src2$$Register, 0xBABA);
|
||||
__ insrdi($src2$$Register, $src2$$Register, 32, 0);
|
||||
// compare src1 with 0xAA, 0xB5, and 0xBA
|
||||
__ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register);
|
||||
|
||||
__ bind(done);
|
||||
__ setb($dst$$Register, $crx$$CondRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
|
||||
match(Set dst (UpperCase src1));
|
||||
effect(TEMP src2, TEMP crx);
|
||||
ins_cost(7 * DEFAULT_COST);
|
||||
|
||||
format %{ "LI $src2, 0x5A41\n\t"
|
||||
"CMPRB $crx, 0, $src1, $src2\n\t"
|
||||
"BGT $crx, done\n\t"
|
||||
"LIS $src2, (signed short)0xD6C0\n\t"
|
||||
"ORI $src2, $src2, 0xDED8\n\t"
|
||||
"CMPRB $crx, 1, $src1, $src2\n"
|
||||
"done:\n\t"
|
||||
"SETB $dst, $crx" %}
|
||||
|
||||
size(28);
|
||||
ins_encode %{
|
||||
Label done;
|
||||
// 0x41: A, 0x5A: Z
|
||||
__ li($src2$$Register, 0x5A41);
|
||||
// compare src1 with a range 0x41 to 0x5A
|
||||
__ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register);
|
||||
__ bgt($crx$$CondRegister, done);
|
||||
|
||||
// 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case
|
||||
__ lis($src2$$Register, (signed short)0xD6C0);
|
||||
__ ori($src2$$Register, $src2$$Register, 0xDED8);
|
||||
// compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE
|
||||
__ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
|
||||
|
||||
__ bind(done);
|
||||
__ setb($dst$$Register, $crx$$CondRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{
|
||||
match(Set dst (Whitespace src1));
|
||||
effect(TEMP src2, TEMP crx);
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
format %{ "LI $src2, 0x0D09\n\t"
|
||||
"ADDIS $src2, 0x201C\n\t"
|
||||
"CMPRB $crx, 1, $src1, $src2\n\t"
|
||||
"SETB $dst, $crx" %}
|
||||
size(16);
|
||||
ins_encode %{
|
||||
// 0x09 to 0x0D, 0x1C to 0x20
|
||||
__ li($src2$$Register, 0x0D09);
|
||||
__ addis($src2$$Register, $src2$$Register, 0x0201C);
|
||||
// compare src with ranges 0x09 to 0x0D and 0x1C to 0x20
|
||||
__ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register);
|
||||
__ setb($dst$$Register, $crx$$CondRegister);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
//----------Branches---------------------------------------------------------
|
||||
// Jump
|
||||
|
||||
|
@ -134,11 +134,18 @@ void VM_Version::initialize() {
|
||||
if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) {
|
||||
FLAG_SET_ERGO(bool, UseCountTrailingZerosInstructionsPPC64, true);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) {
|
||||
FLAG_SET_ERGO(bool, UseCharacterCompareIntrinsics, true);
|
||||
}
|
||||
} else {
|
||||
if (UseCountTrailingZerosInstructionsPPC64) {
|
||||
warning("UseCountTrailingZerosInstructionsPPC64 specified, but needs at least Power9.");
|
||||
FLAG_SET_DEFAULT(UseCountTrailingZerosInstructionsPPC64, false);
|
||||
}
|
||||
if (UseCharacterCompareIntrinsics) {
|
||||
warning("UseCharacterCompareIntrinsics specified, but needs at least Power9.");
|
||||
FLAG_SET_DEFAULT(UseCharacterCompareIntrinsics, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -379,6 +379,10 @@ bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
|
||||
case vmIntrinsics::_vectorizedMismatch:
|
||||
case vmIntrinsics::_fmaD:
|
||||
case vmIntrinsics::_fmaF:
|
||||
case vmIntrinsics::_isDigit:
|
||||
case vmIntrinsics::_isLowerCase:
|
||||
case vmIntrinsics::_isUpperCase:
|
||||
case vmIntrinsics::_isWhitespace:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -828,6 +832,12 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
|
||||
case vmIntrinsics::_subtractExactL:
|
||||
if (!UseMathExactIntrinsics || !InlineMathNatives) return true;
|
||||
break;
|
||||
case vmIntrinsics::_isDigit:
|
||||
case vmIntrinsics::_isLowerCase:
|
||||
case vmIntrinsics::_isUpperCase:
|
||||
case vmIntrinsics::_isWhitespace:
|
||||
if (!UseCharacterCompareIntrinsics) return true;
|
||||
break;
|
||||
#endif // COMPILER2
|
||||
default:
|
||||
return false;
|
||||
|
@ -71,6 +71,7 @@
|
||||
template(java_lang_Boolean, "java/lang/Boolean") \
|
||||
template(java_lang_Character, "java/lang/Character") \
|
||||
template(java_lang_Character_CharacterCache, "java/lang/Character$CharacterCache") \
|
||||
template(java_lang_CharacterDataLatin1, "java/lang/CharacterDataLatin1") \
|
||||
template(java_lang_Float, "java/lang/Float") \
|
||||
template(java_lang_Double, "java/lang/Double") \
|
||||
template(java_lang_Byte, "java/lang/Byte") \
|
||||
@ -933,6 +934,15 @@
|
||||
do_intrinsic(_equalsL, java_lang_StringLatin1,equals_name, equalsB_signature, F_S) \
|
||||
do_intrinsic(_equalsU, java_lang_StringUTF16, equals_name, equalsB_signature, F_S) \
|
||||
\
|
||||
do_intrinsic(_isDigit, java_lang_CharacterDataLatin1, isDigit_name, int_bool_signature, F_R) \
|
||||
do_name( isDigit_name, "isDigit") \
|
||||
do_intrinsic(_isLowerCase, java_lang_CharacterDataLatin1, isLowerCase_name, int_bool_signature, F_R) \
|
||||
do_name( isLowerCase_name, "isLowerCase") \
|
||||
do_intrinsic(_isUpperCase, java_lang_CharacterDataLatin1, isUpperCase_name, int_bool_signature, F_R) \
|
||||
do_name( isUpperCase_name, "isUpperCase") \
|
||||
do_intrinsic(_isWhitespace, java_lang_CharacterDataLatin1, isWhitespace_name, int_bool_signature, F_R) \
|
||||
do_name( isWhitespace_name, "isWhitespace") \
|
||||
\
|
||||
do_intrinsic(_Preconditions_checkIndex, jdk_internal_util_Preconditions, checkIndex_name, Preconditions_checkIndex_signature, F_S) \
|
||||
do_signature(Preconditions_checkIndex_signature, "(IILjava/util/function/BiFunction;)I") \
|
||||
\
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -710,6 +710,9 @@
|
||||
diagnostic(bool, UseMathExactIntrinsics, true, \
|
||||
"Enables intrinsification of various java.lang.Math functions") \
|
||||
\
|
||||
diagnostic(bool, UseCharacterCompareIntrinsics, false, \
|
||||
"Enables intrinsification of java.lang.Character functions") \
|
||||
\
|
||||
diagnostic(bool, UseMultiplyToLenIntrinsic, false, \
|
||||
"Enables intrinsification of BigInteger.multiplyToLen()") \
|
||||
\
|
||||
|
@ -428,6 +428,18 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
|
||||
case vmIntrinsics::_fmaF:
|
||||
if (!UseFMA || !Matcher::match_rule_supported(Op_FmaF)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_isDigit:
|
||||
if (!Matcher::match_rule_supported(Op_Digit)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_isLowerCase:
|
||||
if (!Matcher::match_rule_supported(Op_LowerCase)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_isUpperCase:
|
||||
if (!Matcher::match_rule_supported(Op_UpperCase)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_isWhitespace:
|
||||
if (!Matcher::match_rule_supported(Op_Whitespace)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_hashCode:
|
||||
case vmIntrinsics::_identityHashCode:
|
||||
case vmIntrinsics::_getClass:
|
||||
|
@ -394,3 +394,7 @@ macro(ExtractI)
|
||||
macro(ExtractL)
|
||||
macro(ExtractF)
|
||||
macro(ExtractD)
|
||||
macro(Digit)
|
||||
macro(LowerCase)
|
||||
macro(UpperCase)
|
||||
macro(Whitespace)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -180,4 +180,40 @@ class EncodeISOArrayNode: public Node {
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
};
|
||||
|
||||
//-------------------------------DigitNode----------------------------------------
|
||||
class DigitNode : public Node {
|
||||
public:
|
||||
DigitNode(Node* control, Node *in1) : Node(control, in1) {}
|
||||
virtual int Opcode() const;
|
||||
const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
//------------------------------LowerCaseNode------------------------------------
|
||||
class LowerCaseNode : public Node {
|
||||
public:
|
||||
LowerCaseNode(Node* control, Node *in1) : Node(control, in1) {}
|
||||
virtual int Opcode() const;
|
||||
const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
//------------------------------UpperCaseNode------------------------------------
|
||||
class UpperCaseNode : public Node {
|
||||
public:
|
||||
UpperCaseNode(Node* control, Node *in1) : Node(control, in1) {}
|
||||
virtual int Opcode() const;
|
||||
const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
//------------------------------WhitespaceCode-----------------------------------
|
||||
class WhitespaceNode : public Node {
|
||||
public:
|
||||
WhitespaceNode(Node* control, Node *in1) : Node(control, in1) {}
|
||||
virtual int Opcode() const;
|
||||
const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_OPTO_INTRINSICNODE_HPP
|
||||
|
@ -324,6 +324,7 @@ class LibraryCallKit : public GraphKit {
|
||||
bool inline_montgomerySquare();
|
||||
bool inline_vectorizedMismatch();
|
||||
bool inline_fma(vmIntrinsics::ID id);
|
||||
bool inline_character_compare(vmIntrinsics::ID id);
|
||||
|
||||
bool inline_profileBoolean();
|
||||
bool inline_isCompileConstant();
|
||||
@ -867,6 +868,12 @@ bool LibraryCallKit::try_to_inline(int predicate) {
|
||||
case vmIntrinsics::_fmaF:
|
||||
return inline_fma(intrinsic_id());
|
||||
|
||||
case vmIntrinsics::_isDigit:
|
||||
case vmIntrinsics::_isLowerCase:
|
||||
case vmIntrinsics::_isUpperCase:
|
||||
case vmIntrinsics::_isWhitespace:
|
||||
return inline_character_compare(intrinsic_id());
|
||||
|
||||
default:
|
||||
// If you get here, it may be that someone has added a new intrinsic
|
||||
// to the list in vmSymbols.hpp without implementing it here.
|
||||
@ -6555,6 +6562,32 @@ bool LibraryCallKit::inline_fma(vmIntrinsics::ID id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LibraryCallKit::inline_character_compare(vmIntrinsics::ID id) {
|
||||
// argument(0) is receiver
|
||||
Node* codePoint = argument(1);
|
||||
Node* n = NULL;
|
||||
|
||||
switch (id) {
|
||||
case vmIntrinsics::_isDigit :
|
||||
n = new DigitNode(control(), codePoint);
|
||||
break;
|
||||
case vmIntrinsics::_isLowerCase :
|
||||
n = new LowerCaseNode(control(), codePoint);
|
||||
break;
|
||||
case vmIntrinsics::_isUpperCase :
|
||||
n = new UpperCaseNode(control(), codePoint);
|
||||
break;
|
||||
case vmIntrinsics::_isWhitespace :
|
||||
n = new WhitespaceNode(control(), codePoint);
|
||||
break;
|
||||
default:
|
||||
fatal_unexpected_iid(id);
|
||||
}
|
||||
|
||||
set_result(_gvn.transform(n));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LibraryCallKit::inline_profileBoolean() {
|
||||
Node* counts = argument(1);
|
||||
const TypeAryPtr* ary = NULL;
|
||||
|
@ -9085,7 +9085,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* @since 1.5
|
||||
*/
|
||||
public static boolean isLowerCase(int codePoint) {
|
||||
return getType(codePoint) == Character.LOWERCASE_LETTER ||
|
||||
return CharacterData.of(codePoint).isLowerCase(codePoint) ||
|
||||
CharacterData.of(codePoint).isOtherLowercase(codePoint);
|
||||
}
|
||||
|
||||
@ -9151,7 +9151,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* @since 1.5
|
||||
*/
|
||||
public static boolean isUpperCase(int codePoint) {
|
||||
return getType(codePoint) == Character.UPPERCASE_LETTER ||
|
||||
return CharacterData.of(codePoint).isUpperCase(codePoint) ||
|
||||
CharacterData.of(codePoint).isOtherUppercase(codePoint);
|
||||
}
|
||||
|
||||
@ -9302,7 +9302,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
||||
* @since 1.5
|
||||
*/
|
||||
public static boolean isDigit(int codePoint) {
|
||||
return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
|
||||
return CharacterData.of(codePoint).isDigit(codePoint);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,6 +28,9 @@ package java.lang;
|
||||
abstract class CharacterData {
|
||||
abstract int getProperties(int ch);
|
||||
abstract int getType(int ch);
|
||||
abstract boolean isDigit(int ch);
|
||||
abstract boolean isLowerCase(int ch);
|
||||
abstract boolean isUpperCase(int ch);
|
||||
abstract boolean isWhitespace(int ch);
|
||||
abstract boolean isMirrored(int ch);
|
||||
abstract boolean isJavaIdentifierStart(int ch);
|
||||
|
64
test/micro/org/openjdk/bench/java/lang/Characters.java
Normal file
64
test/micro/org/openjdk/bench/java/lang/Characters.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.lang;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
public class Characters {
|
||||
|
||||
@Param({"9", "48", "65", "97", "128", "170", "192", "223"})
|
||||
private int codePoint;
|
||||
|
||||
@Benchmark
|
||||
public boolean isDigit() {
|
||||
return Character.isDigit(codePoint);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public boolean isLowerCase() {
|
||||
return Character.isLowerCase(codePoint);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public boolean isUpperCase() {
|
||||
return Character.isUpperCase(codePoint);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public boolean isWhitespace() {
|
||||
return Character.isWhitespace(codePoint);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user