Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 11080:b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
Summary: add intrinsics using new instruction to interpreter, C1, C2, for suitable x86; add test
Reviewed-by: kvn, twisti
author | drchase |
---|---|
date | Tue, 02 Jul 2013 20:42:12 -0400 |
parents | 46f6f063b272 |
children | 7944aba7ba41 |
comparison
equal
deleted
inserted
replaced
11079:738e04fb1232 | 11080:b800986664f4 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
930 arraycopy_helper(x, &flags, &expected_type); | 930 arraycopy_helper(x, &flags, &expected_type); |
931 | 931 |
932 __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint | 932 __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint |
933 } | 933 } |
934 | 934 |
935 void LIRGenerator::do_update_CRC32(Intrinsic* x) { | |
936 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); | |
937 // Make all state_for calls early since they can emit code | |
938 LIR_Opr result = rlock_result(x); | |
939 int flags = 0; | |
940 switch (x->id()) { | |
941 case vmIntrinsics::_updateCRC32: { | |
942 LIRItem crc(x->argument_at(0), this); | |
943 LIRItem val(x->argument_at(1), this); | |
944 crc.load_item(); | |
945 val.load_item(); | |
946 __ update_crc32(crc.result(), val.result(), result); | |
947 break; | |
948 } | |
949 case vmIntrinsics::_updateBytesCRC32: | |
950 case vmIntrinsics::_updateByteBufferCRC32: { | |
951 bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32); | |
952 | |
953 LIRItem crc(x->argument_at(0), this); | |
954 LIRItem buf(x->argument_at(1), this); | |
955 LIRItem off(x->argument_at(2), this); | |
956 LIRItem len(x->argument_at(3), this); | |
957 buf.load_item(); | |
958 off.load_nonconstant(); | |
959 | |
960 LIR_Opr index = off.result(); | |
961 int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; | |
962 if(off.result()->is_constant()) { | |
963 index = LIR_OprFact::illegalOpr; | |
964 offset += off.result()->as_jint(); | |
965 } | |
966 LIR_Opr base_op = buf.result(); | |
967 | |
968 #ifndef _LP64 | |
969 if (!is_updateBytes) { // long b raw address | |
970 base_op = new_register(T_INT); | |
971 __ convert(Bytecodes::_l2i, buf.result(), base_op); | |
972 } | |
973 #else | |
974 if (index->is_valid()) { | |
975 LIR_Opr tmp = new_register(T_LONG); | |
976 __ convert(Bytecodes::_i2l, index, tmp); | |
977 index = tmp; | |
978 } | |
979 #endif | |
980 | |
981 LIR_Address* a = new LIR_Address(base_op, | |
982 index, | |
983 LIR_Address::times_1, | |
984 offset, | |
985 T_BYTE); | |
986 BasicTypeList signature(3); | |
987 signature.append(T_INT); | |
988 signature.append(T_ADDRESS); | |
989 signature.append(T_INT); | |
990 CallingConvention* cc = frame_map()->c_calling_convention(&signature); | |
991 const LIR_Opr result_reg = result_register_for(x->type()); | |
992 | |
993 LIR_Opr addr = new_pointer_register(); | |
994 __ leal(LIR_OprFact::address(a), addr); | |
995 | |
996 crc.load_item_force(cc->at(0)); | |
997 __ move(addr, cc->at(1)); | |
998 len.load_item_force(cc->at(2)); | |
999 | |
1000 __ call_runtime_leaf(StubRoutines::updateBytesCRC32(), getThreadTemp(), result_reg, cc->args()); | |
1001 __ move(result_reg, result); | |
1002 | |
1003 break; | |
1004 } | |
1005 default: { | |
1006 ShouldNotReachHere(); | |
1007 } | |
1008 } | |
1009 } | |
935 | 1010 |
936 // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f | 1011 // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f |
937 // _i2b, _i2c, _i2s | 1012 // _i2b, _i2c, _i2s |
938 LIR_Opr fixed_register_for(BasicType type) { | 1013 LIR_Opr fixed_register_for(BasicType type) { |
939 switch (type) { | 1014 switch (type) { |