< prev index next >

src/cpu/ppc/vm/ppc.ad

Print this page
rev 12397 : 8170991: PPC64: Bad code for initialization of short arrays
Summary: Implement special ClearArray nodes to improve initialization.
Reviewed-by:


 948 // condition code conversions
 949 
 950 static int cc_to_boint(int cc) {
 951   return Assembler::bcondCRbiIs0 | (cc & 8);
 952 }
 953 
 954 static int cc_to_inverse_boint(int cc) {
 955   return Assembler::bcondCRbiIs0 | (8-(cc & 8));
 956 }
 957 
 958 static int cc_to_biint(int cc, int flags_reg) {
 959   return (flags_reg << 2) | (cc & 3);
 960 }
 961 
 962 //=============================================================================
 963 
 964 // Compute padding required for nodes which need alignment. The padding
 965 // is the number of bytes (not instructions) which will be inserted before
 966 // the instruction. The padding must match the size of a NOP instruction.
 967 
 968 int inlineCallClearArrayNode::compute_padding(int current_offset) const {
 969   int desired_padding = (2*4-current_offset)&31; // see MacroAssembler::clear_memory_doubleword
 970   return (desired_padding <= 3*4) ? desired_padding : 0;
 971 }
 972 
 973 //=============================================================================
 974 
 975 // Indicate if the safepoint node needs the polling page as an input.
 976 bool SafePointNode::needs_polling_address_input() {
 977   // The address is loaded from thread by a seperate node.
 978   return true;
 979 }
 980 
 981 //=============================================================================
 982 
 983 // Emit an interrupt that is caught by the debugger (for debugging compiler).
 984 void emit_break(CodeBuffer &cbuf) {
 985   MacroAssembler _masm(&cbuf);
 986   __ illtrap();
 987 }
 988 
 989 #ifndef PRODUCT
 990 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 991   st->print("BREAKPOINT");


4049   format %{ %}
4050   interface(CONST_INTER);
4051 %}
4052 
4053 // pointer 0x0 or 0x1
4054 operand immP_0or1() %{
4055   predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4056   match(ConP);
4057   op_cost(0);
4058   format %{ %}
4059   interface(CONST_INTER);
4060 %}
4061 
4062 operand immL() %{
4063   match(ConL);
4064   op_cost(40);
4065   format %{ %}
4066   interface(CONST_INTER);
4067 %}
4068 
















4069 // Long Immediate: 16-bit
4070 operand immL16() %{
4071   predicate(Assembler::is_simm(n->get_long(), 16));
4072   match(ConL);
4073   op_cost(0);
4074   format %{ %}
4075   interface(CONST_INTER);
4076 %}
4077 
4078 // Long Immediate: 16-bit, 4-aligned
4079 operand immL16Alg4() %{
4080   predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4081   match(ConL);
4082   op_cost(0);
4083   format %{ %}
4084   interface(CONST_INTER);
4085 %}
4086 
4087 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4088 operand immL32hi16() %{


11718   ins_encode %{
11719     // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
11720     __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant));
11721   %}
11722   ins_pipe(pipe_class_default);
11723 %}
11724 
11725 // Array size computation.
11726 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11727   match(Set dst (SubL (CastP2X end) (CastP2X start)));
11728 
11729   format %{ "SUB     $dst, $end, $start \t// array size in bytes" %}
11730   size(4);
11731   ins_encode %{
11732     // TODO: PPC port $archOpcode(ppc64Opcode_subf);
11733     __ subf($dst$$Register, $start$$Register, $end$$Register);
11734   %}
11735   ins_pipe(pipe_class_default);
11736 %}
11737 
11738 // Clear-array with dynamic array-size.









































11739 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11740   match(Set dummy (ClearArray cnt base));
11741   effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11742   ins_cost(MEMORY_REF_COST);
11743 
11744   ins_alignment(4); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
11745 
11746   format %{ "ClearArray $cnt, $base" %}
11747   ins_encode %{
11748     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11749     __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0
11750   %}
11751   ins_pipe(pipe_class_default);
11752 %}
11753 
11754 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11755                          iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11756   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11757   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11758   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11759   ins_cost(300);
11760   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11761   ins_encode %{
11762     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11763     __ string_compare($str1$$Register, $str2$$Register,
11764                       $cnt1$$Register, $cnt2$$Register,
11765                       $tmp$$Register,
11766                       $result$$Register, StrIntrinsicNode::LL);
11767   %}
11768   ins_pipe(pipe_class_default);
11769 %}




 948 // condition code conversions
 949 
 950 static int cc_to_boint(int cc) {
 951   return Assembler::bcondCRbiIs0 | (cc & 8);
 952 }
 953 
 954 static int cc_to_inverse_boint(int cc) {
 955   return Assembler::bcondCRbiIs0 | (8-(cc & 8));
 956 }
 957 
 958 static int cc_to_biint(int cc, int flags_reg) {
 959   return (flags_reg << 2) | (cc & 3);
 960 }
 961 
 962 //=============================================================================
 963 
 964 // Compute padding required for nodes which need alignment. The padding
 965 // is the number of bytes (not instructions) which will be inserted before
 966 // the instruction. The padding must match the size of a NOP instruction.
 967 
 968 // Currently not used on this platform.



 969 
 970 //=============================================================================
 971 
 972 // Indicate if the safepoint node needs the polling page as an input.
 973 bool SafePointNode::needs_polling_address_input() {
 974   // The address is loaded from thread by a seperate node.
 975   return true;
 976 }
 977 
 978 //=============================================================================
 979 
 980 // Emit an interrupt that is caught by the debugger (for debugging compiler).
 981 void emit_break(CodeBuffer &cbuf) {
 982   MacroAssembler _masm(&cbuf);
 983   __ illtrap();
 984 }
 985 
 986 #ifndef PRODUCT
 987 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 988   st->print("BREAKPOINT");


4046   format %{ %}
4047   interface(CONST_INTER);
4048 %}
4049 
4050 // pointer 0x0 or 0x1
4051 operand immP_0or1() %{
4052   predicate((n->get_ptr() == 0) || (n->get_ptr() == 1));
4053   match(ConP);
4054   op_cost(0);
4055   format %{ %}
4056   interface(CONST_INTER);
4057 %}
4058 
4059 operand immL() %{
4060   match(ConL);
4061   op_cost(40);
4062   format %{ %}
4063   interface(CONST_INTER);
4064 %}
4065 
4066 operand immLmax15() %{
4067   predicate((n->get_long() <= 15));
4068   match(ConL);
4069   op_cost(0);
4070   format %{ %}
4071   interface(CONST_INTER);
4072 %}
4073 
4074 operand immLmax30() %{
4075   predicate((n->get_long() <= 30));
4076   match(ConL);
4077   op_cost(0);
4078   format %{ %}
4079   interface(CONST_INTER);
4080 %}
4081 
4082 // Long Immediate: 16-bit
4083 operand immL16() %{
4084   predicate(Assembler::is_simm(n->get_long(), 16));
4085   match(ConL);
4086   op_cost(0);
4087   format %{ %}
4088   interface(CONST_INTER);
4089 %}
4090 
4091 // Long Immediate: 16-bit, 4-aligned
4092 operand immL16Alg4() %{
4093   predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0));
4094   match(ConL);
4095   op_cost(0);
4096   format %{ %}
4097   interface(CONST_INTER);
4098 %}
4099 
4100 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000.
4101 operand immL32hi16() %{


11731   ins_encode %{
11732     // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
11733     __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant));
11734   %}
11735   ins_pipe(pipe_class_default);
11736 %}
11737 
11738 // Array size computation.
11739 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
11740   match(Set dst (SubL (CastP2X end) (CastP2X start)));
11741 
11742   format %{ "SUB     $dst, $end, $start \t// array size in bytes" %}
11743   size(4);
11744   ins_encode %{
11745     // TODO: PPC port $archOpcode(ppc64Opcode_subf);
11746     __ subf($dst$$Register, $start$$Register, $end$$Register);
11747   %}
11748   ins_pipe(pipe_class_default);
11749 %}
11750 
11751 // Clear-array with constant very short array length.
11752 instruct inlineCallClearArrayVeryShort(immLmax15 cnt, iRegPsrc base, immL offset, Universe dummy) %{
11753   match(Set dummy (ClearArray cnt (AddP base offset)));
11754   ins_cost(MEMORY_REF_COST);
11755 
11756   format %{ "ClearArray $cnt, $base" %}
11757   ins_encode %{
11758     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11759     __ clear_memory_unrolled($base$$Register, $cnt$$constant, R0, $offset$$constant); // kills R0
11760   %}
11761   ins_pipe(pipe_class_default);
11762 %}
11763 
11764 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30.
11765 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11766   match(Set dummy (ClearArray cnt base));
11767   effect(USE_KILL base, KILL ctr);
11768   ins_cost(2 * MEMORY_REF_COST);
11769 
11770   format %{ "ClearArray $cnt, $base" %}
11771   ins_encode %{
11772     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11773     __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
11774   %}
11775   ins_pipe(pipe_class_default);
11776 %}
11777 
11778 // Clear-array with constant large array length.
11779 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{
11780   match(Set dummy (ClearArray cnt base));
11781   effect(USE_KILL base, TEMP tmp, KILL ctr);
11782   ins_cost(3 * MEMORY_REF_COST);
11783 
11784   format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
11785   ins_encode %{
11786     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11787     __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
11788   %}
11789   ins_pipe(pipe_class_default);
11790 %}
11791 
11792 // Clear-array with dynamic array length.
11793 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{
11794   match(Set dummy (ClearArray cnt base));
11795   effect(USE_KILL cnt, USE_KILL base, KILL ctr);
11796   ins_cost(4 * MEMORY_REF_COST);


11797 
11798   format %{ "ClearArray $cnt, $base" %}
11799   ins_encode %{
11800     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11801     __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
11802   %}
11803   ins_pipe(pipe_class_default);
11804 %}
11805 
11806 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
11807                          iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
11808   predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
11809   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11810   effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
11811   ins_cost(300);
11812   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
11813   ins_encode %{
11814     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
11815     __ string_compare($str1$$Register, $str2$$Register,
11816                       $cnt1$$Register, $cnt2$$Register,
11817                       $tmp$$Register,
11818                       $result$$Register, StrIntrinsicNode::LL);
11819   %}
11820   ins_pipe(pipe_class_default);
11821 %}


< prev index next >