--- a/hotspot/src/cpu/x86/vm/x86_32.ad Thu Mar 12 10:37:46 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Fri Mar 13 11:35:17 2009 -0700
@@ -1483,16 +1483,20 @@
// main source block for now. In future, we can generalize this by
// adding a syntax that specifies the sizes of fields in an order,
// so that the adlc can build the emit functions automagically
- enc_class OpcP %{ // Emit opcode
- emit_opcode(cbuf,$primary);
- %}
-
- enc_class OpcS %{ // Emit opcode
- emit_opcode(cbuf,$secondary);
- %}
-
- enc_class Opcode(immI d8 ) %{ // Emit opcode
- emit_opcode(cbuf,$d8$$constant);
+
+ // Emit primary opcode
+ enc_class OpcP %{
+ emit_opcode(cbuf, $primary);
+ %}
+
+ // Emit secondary opcode
+ enc_class OpcS %{
+ emit_opcode(cbuf, $secondary);
+ %}
+
+ // Emit opcode directly
+ enc_class Opcode(immI d8) %{
+ emit_opcode(cbuf, $d8$$constant);
%}
enc_class SizePrefix %{
@@ -6387,6 +6391,67 @@
%}
+//---------- Population Count Instructions -------------------------------------
+
+instruct popCountI(eRegI dst, eRegI src) %{
+ predicate(UsePopCountInstruction);
+ match(Set dst (PopCountI src));
+
+ format %{ "POPCNT $dst, $src" %}
+ ins_encode %{
+ __ popcntl($dst$$Register, $src$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct popCountI_mem(eRegI dst, memory mem) %{
+ predicate(UsePopCountInstruction);
+ match(Set dst (PopCountI (LoadI mem)));
+
+ format %{ "POPCNT $dst, $mem" %}
+ ins_encode %{
+ __ popcntl($dst$$Register, $mem$$Address);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+// Note: Long.bitCount(long) returns an int.
+instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+ predicate(UsePopCountInstruction);
+ match(Set dst (PopCountL src));
+ effect(KILL cr, TEMP tmp, TEMP dst);
+
+ format %{ "POPCNT $dst, $src.lo\n\t"
+ "POPCNT $tmp, $src.hi\n\t"
+ "ADD $dst, $tmp" %}
+ ins_encode %{
+ __ popcntl($dst$$Register, $src$$Register);
+ __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
+ __ addl($dst$$Register, $tmp$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+// Note: Long.bitCount(long) returns an int.
+instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{
+ predicate(UsePopCountInstruction);
+ match(Set dst (PopCountL (LoadL mem)));
+ effect(KILL cr, TEMP tmp, TEMP dst);
+
+ format %{ "POPCNT $dst, $mem\n\t"
+ "POPCNT $tmp, $mem+4\n\t"
+ "ADD $dst, $tmp" %}
+ ins_encode %{
+ //__ popcntl($dst$$Register, $mem$$Address$$first);
+ //__ popcntl($tmp$$Register, $mem$$Address$$second);
+ __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false));
+ __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false));
+ __ addl($dst$$Register, $tmp$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+
//----------Load/Store/Move Instructions---------------------------------------
//----------Load Instructions--------------------------------------------------
// Load Byte (8bit signed)