changeset 415:4d9884b01ba6

6754519: don't emit flag fixup for NaN when condition being tested doesn't need it Reviewed-by: kvn, rasbold
author never
date Tue, 28 Oct 2008 09:31:30 -0700
parents ebfd4ae89bf6
children b6cfd754403d
files src/cpu/sparc/vm/sparc.ad src/cpu/x86/vm/x86_32.ad src/cpu/x86/vm/x86_64.ad src/share/vm/adlc/adlparse.cpp src/share/vm/adlc/adlparse.hpp src/share/vm/adlc/filebuff.cpp src/share/vm/adlc/filebuff.hpp src/share/vm/adlc/forms.cpp src/share/vm/adlc/forms.hpp src/share/vm/adlc/formssel.cpp src/share/vm/adlc/formssel.hpp src/share/vm/adlc/output_c.cpp src/share/vm/adlc/output_h.cpp src/share/vm/opto/matcher.hpp src/share/vm/opto/output.cpp src/share/vm/opto/reg_split.cpp
diffstat 16 files changed, 1125 insertions(+), 253 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/sparc.ad	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/cpu/sparc/vm/sparc.ad	Tue Oct 28 09:31:30 2008 -0700
@@ -1743,7 +1743,7 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
   return false;
 }
 
@@ -1926,18 +1926,23 @@
                        $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
   %}
 
+  enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
+                       $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
+  %}
+
   enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
-    emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
                      $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
   %}
 
   enc_class form3_mem_prefetch_read( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
   %}
 
   enc_class form3_mem_prefetch_write( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
   %}
 
@@ -1945,8 +1950,8 @@
     assert( Assembler::is_simm13($mem$$disp  ), "need disp and disp+4" );
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
     emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
     emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
   %}
@@ -1956,14 +1961,14 @@
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
     // Load long with 2 instructions
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
   %}
 
   //%%% form3_mem_plus_4_reg is a hack--get rid of it
   enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
     guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
   %}
 
   enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
@@ -5062,7 +5067,7 @@
   size(4);
   format %{ "LDF    $src,$dst\t! stkI to regF" %}
   opcode(Assembler::ldf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
@@ -5073,7 +5078,7 @@
   size(4);
   format %{ "LDDF   $src,$dst\t! stkL to regD" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -5084,7 +5089,7 @@
   size(4);
   format %{ "STF    $src,$dst\t! regF to stkI" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -5095,7 +5100,7 @@
   size(4);
   format %{ "STDF   $src,$dst\t! regD to stkL" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -5106,7 +5111,7 @@
   format %{ "STW    $src,$dst.hi\t! long\n\t"
             "STW    R_G0,$dst.lo" %}
   opcode(Assembler::stw_op3);
-  ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
+  ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
   ins_pipe(lstoreI_stk_reg);
 %}
 
@@ -5117,7 +5122,7 @@
   size(4);
   format %{ "STX    $src,$dst\t! regL to stkD" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_stk_reg);
 %}
 
@@ -5131,7 +5136,7 @@
   size(4);
   format %{ "LDUW   $src,$dst\t!stk" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5143,7 +5148,7 @@
   size(4);
   format %{ "STW    $src,$dst\t!stk" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5155,7 +5160,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5167,7 +5172,7 @@
   size(4);
   format %{ "STX    $src,$dst\t! long" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5179,7 +5184,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t!ptr" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5190,7 +5195,7 @@
   size(4);
   format %{ "STX    $src,$dst\t!ptr" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #else // _LP64
@@ -5200,7 +5205,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LDUW   $src,$dst\t!ptr" %}
   opcode(Assembler::lduw_op3, Assembler::ldst_op);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5210,7 +5215,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STW    $src,$dst\t!ptr" %}
   opcode(Assembler::stw_op3, Assembler::ldst_op);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #endif // _LP64
@@ -5273,7 +5278,7 @@
   size(4);
   format %{ "LDSB   $mem,$dst" %}
   opcode(Assembler::ldsb_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5285,7 +5290,7 @@
   size(4);
   format %{ "LDUB   $mem,$dst" %}
   opcode(Assembler::ldub_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5297,7 +5302,7 @@
   size(4);
   format %{ "LDUB   $mem,$dst" %}
   opcode(Assembler::ldub_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5309,7 +5314,7 @@
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5321,7 +5326,7 @@
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5333,7 +5338,7 @@
 
   format %{ "LDUW   $mem,$dst" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5344,7 +5349,7 @@
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5359,7 +5364,7 @@
           "\tSLLX   #32, $dst, $dst\n"
           "\tOR     $dst, R_O7, $dst" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
+  ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
   ins_pipe(iload_mem);
 %}
 
@@ -5370,7 +5375,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed8B" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5381,7 +5386,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4C" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5392,7 +5397,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4S" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5403,7 +5408,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed2I" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5415,7 +5420,7 @@
   size(4);
   format %{ "LDUW   $mem,$dst\t! range" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5427,7 +5432,7 @@
 
   format %{ "LDF    $mem,$dst\t! for fitos/fitod" %}
   opcode(Assembler::ldf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
@@ -5514,7 +5519,7 @@
   size(4);
   format %{ "LDSH   $mem,$dst" %}
   opcode(Assembler::ldsh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5526,7 +5531,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5550,7 +5555,7 @@
   size(4);
   format %{ "LDF    $mem,$dst" %}
   opcode(Assembler::ldf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
@@ -5719,7 +5724,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5730,7 +5735,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5741,7 +5746,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! CMS card-mark byte 0" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5753,7 +5758,7 @@
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5764,7 +5769,7 @@
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5776,7 +5781,7 @@
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5787,7 +5792,7 @@
   size(4);
   format %{ "STX    $src,$mem\t! long" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5798,7 +5803,7 @@
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5809,7 +5814,7 @@
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5821,7 +5826,7 @@
   size(4);
   format %{ "STF    $src,$mem\t! after fstoi/fdtoi" %}
   opcode(Assembler::stf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
@@ -5904,7 +5909,7 @@
   size(4);
   format %{ "STDF   $src,$mem" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -5915,7 +5920,7 @@
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -5927,7 +5932,7 @@
   size(4);
   format %{ "STF    $src,$mem" %}
   opcode(Assembler::stf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
@@ -5938,7 +5943,7 @@
   size(4);
   format %{ "STW    $src,$mem\t! storeF0" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreF_mem_zero);
 %}
 
@@ -5949,7 +5954,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed8B" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6004,7 +6009,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed8B" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6015,7 +6020,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed4C" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6026,7 +6031,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed4C" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6037,7 +6042,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed2I" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6048,7 +6053,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed2I" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6162,7 +6167,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STDF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -6172,7 +6177,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LDDF   $stkSlot,$dst\t!stk" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(stkSlot, dst));
+  ins_encode(simple_form3_mem_reg(stkSlot, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -6182,7 +6187,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -6584,7 +6589,7 @@
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7666,7 +7671,7 @@
   format %{ "LDF    $mem,$dst\n\t"
             "FITOD  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitod_opf);
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
@@ -7696,7 +7701,7 @@
   format %{ "LDF    $mem,$dst\n\t"
             "FITOS  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitos_opf);
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
@@ -7738,7 +7743,7 @@
   size(4);
   format %{ "LDUW   $src,$dst\t! MoveF2I" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7750,7 +7755,7 @@
   size(4);
   format %{ "LDF    $src,$dst\t! MoveI2F" %}
   opcode(Assembler::ldf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
@@ -7762,7 +7767,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t! MoveD2L" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7774,7 +7779,7 @@
   size(4);
   format %{ "LDDF   $src,$dst\t! MoveL2D" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -7786,7 +7791,7 @@
   size(4);
   format %{ "STF   $src,$dst\t!MoveF2I" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -7798,7 +7803,7 @@
   size(4);
   format %{ "STW    $src,$dst\t!MoveI2F" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -7810,7 +7815,7 @@
   size(4);
   format %{ "STDF   $src,$dst\t!MoveD2L" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -7822,7 +7827,7 @@
   size(4);
   format %{ "STX    $src,$dst\t!MoveL2D" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
--- a/src/cpu/x86/vm/x86_32.ad	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/cpu/x86/vm/x86_32.ad	Tue Oct 28 09:31:30 2008 -0700
@@ -495,8 +495,8 @@
 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
   Compile* C = ra_->C;
   if( C->in_24_bit_fp_mode() ) {
-    tty->print("FLDCW  24 bit fpu control word");
-    tty->print_cr(""); tty->print("\t");
+    st->print("FLDCW  24 bit fpu control word");
+    st->print_cr(""); st->print("\t");
   }
 
   int framesize = C->frame_slots() << LogBytesPerInt;
@@ -510,22 +510,22 @@
   // stack.  But the stack safety zone should account for that.
   // See bugs 4446381, 4468289, 4497237.
   if (C->need_stack_bang(framesize)) {
-    tty->print_cr("# stack bang"); tty->print("\t");
+    st->print_cr("# stack bang"); st->print("\t");
   }
-  tty->print_cr("PUSHL  EBP"); tty->print("\t");
+  st->print_cr("PUSHL  EBP"); st->print("\t");
 
   if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
-    tty->print("PUSH   0xBADB100D\t# Majik cookie for stack depth check");
-    tty->print_cr(""); tty->print("\t");
+    st->print("PUSH   0xBADB100D\t# Majik cookie for stack depth check");
+    st->print_cr(""); st->print("\t");
     framesize -= wordSize;
   }
 
   if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
     if (framesize) {
-      tty->print("SUB    ESP,%d\t# Create frame",framesize);
+      st->print("SUB    ESP,%d\t# Create frame",framesize);
     }
   } else {
-    tty->print("SUB    ESP,%d\t# Create frame",framesize);
+    st->print("SUB    ESP,%d\t# Create frame",framesize);
   }
 }
 #endif
@@ -725,18 +725,19 @@
   return rc_xmm;
 }
 
-static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) {
+static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
+                        int opcode, const char *op_str, int size, outputStream* st ) {
   if( cbuf ) {
     emit_opcode  (*cbuf, opcode );
     encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
+    if( size != 0 ) st->print("\n\t");
     if( opcode == 0x8B || opcode == 0x89 ) { // MOV
-      if( is_load ) tty->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
-      else          tty->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
+      if( is_load ) st->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
+      else          st->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
     } else { // FLD, FST, PUSH, POP
-      tty->print("%s [ESP + #%d]",op_str,offset);
+      st->print("%s [ESP + #%d]",op_str,offset);
     }
 #endif
   }
@@ -746,7 +747,7 @@
 
 // Helper for XMM registers.  Extra opcode bits, limited syntax.
 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
-                         int offset, int reg_lo, int reg_hi, int size ) {
+                         int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
   if( cbuf ) {
     if( reg_lo+1 == reg_hi ) { // double move?
       if( is_load && !UseXmmLoadAndClearUpper )
@@ -764,17 +765,17 @@
     encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
+    if( size != 0 ) st->print("\n\t");
     if( reg_lo+1 == reg_hi ) { // double move?
-      if( is_load ) tty->print("%s %s,[ESP + #%d]",
+      if( is_load ) st->print("%s %s,[ESP + #%d]",
                                UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
                                Matcher::regName[reg_lo], offset);
-      else          tty->print("MOVSD  [ESP + #%d],%s",
+      else          st->print("MOVSD  [ESP + #%d],%s",
                                offset, Matcher::regName[reg_lo]);
     } else {
-      if( is_load ) tty->print("MOVSS  %s,[ESP + #%d]",
+      if( is_load ) st->print("MOVSS  %s,[ESP + #%d]",
                                Matcher::regName[reg_lo], offset);
-      else          tty->print("MOVSS  [ESP + #%d],%s",
+      else          st->print("MOVSS  [ESP + #%d],%s",
                                offset, Matcher::regName[reg_lo]);
     }
 #endif
@@ -785,7 +786,7 @@
 
 
 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
-                            int src_hi, int dst_hi, int size ) {
+                            int src_hi, int dst_hi, int size, outputStream* st ) {
   if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
     if( cbuf ) {
       if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
@@ -796,11 +797,11 @@
       emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
+      if( size != 0 ) st->print("\n\t");
       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
-        tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       } else {
-        tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       }
 #endif
     }
@@ -813,11 +814,11 @@
       emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
+      if( size != 0 ) st->print("\n\t");
       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
-        tty->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       } else {
-        tty->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       }
 #endif
     }
@@ -825,28 +826,29 @@
   }
 }
 
-static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) {
+static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
   if( cbuf ) {
     emit_opcode(*cbuf, 0x8B );
     emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
-    tty->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
+    if( size != 0 ) st->print("\n\t");
+    st->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
 #endif
   }
   return size+2;
 }
 
-static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) {
+static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
+                                 int offset, int size, outputStream* st ) {
   if( src_lo != FPR1L_num ) {      // Move value to top of FP stack, if not already there
     if( cbuf ) {
       emit_opcode( *cbuf, 0xD9 );  // FLD (i.e., push it)
       emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
-      tty->print("FLD    %s",Matcher::regName[src_lo]);
+      if( size != 0 ) st->print("\n\t");
+      st->print("FLD    %s",Matcher::regName[src_lo]);
 #endif
     }
     size += 2;
@@ -864,7 +866,7 @@
     assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
   }
 
-  return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size);
+  return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
 }
 
 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
@@ -892,16 +894,16 @@
   if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
     if( src_second == dst_first ) { // overlapping stack copy ranges
       assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
-      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size);
-      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size);
+      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size, st);
+      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size, st);
       src_second_rc = dst_second_rc = rc_bad;  // flag as already moved the second bits
     }
     // move low bits
-    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH  ",size);
-    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP   ",size);
+    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH  ",size, st);
+    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP   ",size, st);
     if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
-      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size);
-      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size);
+      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size, st);
+      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size, st);
     }
     return size;
   }
@@ -909,15 +911,15 @@
   // --------------------------------------
   // Check for integer reg-reg copy
   if( src_first_rc == rc_int && dst_first_rc == rc_int )
-    size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size);
+    size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
 
   // Check for integer store
   if( src_first_rc == rc_int && dst_first_rc == rc_stack )
-    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size);
+    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
 
   // Check for integer load
   if( dst_first_rc == rc_int && src_first_rc == rc_stack )
-    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size);
+    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
 
   // --------------------------------------
   // Check for float reg-reg copy
@@ -951,7 +953,7 @@
 
   // Check for float store
   if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
-    return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size);
+    return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
   }
 
   // Check for float load
@@ -987,17 +989,17 @@
     assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
             (src_first+1 == src_second && dst_first+1 == dst_second),
             "no non-adjacent float-moves" );
-    return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size);
+    return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
   }
 
   // Check for xmm store
   if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
-    return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size);
+    return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
   }
 
   // Check for float xmm load
   if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
-    return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size);
+    return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
   }
 
   // Copy from float reg to xmm reg
@@ -1017,10 +1019,10 @@
     }
     size += 4;
 
-    size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size);
+    size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
 
     // Copy from the temp memory to the xmm reg.
-    size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size);
+    size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
 
     if( cbuf ) {
       emit_opcode(*cbuf,0x8D);  // LEA  ESP,[ESP+8]
@@ -1047,15 +1049,15 @@
 
   // Check for second word int-int move
   if( src_second_rc == rc_int && dst_second_rc == rc_int )
-    return impl_mov_helper(cbuf,do_size,src_second,dst_second,size);
+    return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
 
   // Check for second word integer store
   if( src_second_rc == rc_int && dst_second_rc == rc_stack )
-    return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size);
+    return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
 
   // Check for second word integer load
   if( dst_second_rc == rc_int && src_second_rc == rc_stack )
-    return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size);
+    return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
 
 
   Unimplemented();
@@ -1318,7 +1320,11 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+  // the short version of jmpConUCF2 contains multiple branches,
+  // making the reach slightly less
+  if (rule == jmpConUCF2_rule)
+    return (-126 <= offset && offset <= 125);
   return (-128 <= offset && offset <= 127);
 }
 
@@ -5272,6 +5278,15 @@
   interface(REG_INTER);
 %}
 
+operand eFlagsRegUCF() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  predicate(false);
+
+  format %{ "EFLAGS_U_CF" %}
+  interface(REG_INTER);
+%}
+
 // Condition Code Register used by long compare
 operand flagsReg_long_LTGE() %{
   constraint(ALLOC_IN_RC(int_flags));
@@ -5749,12 +5764,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xC);
-    greater_equal(0xD);
-    less_equal(0xE);
-    greater(0xF);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xC, "l");
+    greater_equal(0xD, "ge");
+    less_equal(0xE, "le");
+    greater(0xF, "g");
   %}
 %}
 
@@ -5766,12 +5781,47 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0x2);
-    greater_equal(0x3);
-    less_equal(0x6);
-    greater(0x7);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+            n->as_Bool()->_test._test == BoolTest::ge ||
+            n->as_Bool()->_test._test == BoolTest::le ||
+            n->as_Bool()->_test._test == BoolTest::gt);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+            n->as_Bool()->_test._test == BoolTest::eq);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
   %}
 %}
 
@@ -5796,12 +5846,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xF);
-    greater_equal(0xE);
-    less_equal(0xD);
-    greater(0xC);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xF, "g");
+    greater_equal(0xE, "le");
+    less_equal(0xD, "ge");
+    greater(0xC, "l");
   %}
 %}
 
@@ -7357,7 +7407,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7367,6 +7417,15 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
+instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovI_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
@@ -7379,7 +7438,7 @@
 %}
 
 // Conditional move
-instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
+instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -7389,6 +7448,15 @@
   ins_pipe( pipe_cmov_mem );
 %}
 
+instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+  ins_cost(250);
+  expand %{
+    cmovI_memU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
   predicate(VM_Version::supports_cmov() );
@@ -7416,7 +7484,7 @@
 %}
 
 // Conditional move
-instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7426,6 +7494,15 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
+instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovP_regU(cop, cr, dst, src);
+  %}
+%}
+
 // DISABLED: Requires the ADLC to emit a bottom_type call that
 // correctly meets the two pointer arguments; one is an incoming
 // register but the other is a memory operand.  ALSO appears to
@@ -7555,6 +7632,15 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
+  predicate (UseSSE>=1);
+  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    fcmovX_regU(cop, cr, dst, src);
+  %}
+%}
+
 // unsigned version
 instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
   predicate (UseSSE>=2);
@@ -7573,6 +7659,15 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
+  predicate (UseSSE>=2);
+  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    fcmovXD_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
@@ -7595,6 +7690,15 @@
   ins_pipe( pipe_cmov_reg_long );
 %}
 
+instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovL_regU(cop, cr, dst, src);
+  %}
+%}
+
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 // Integer Addition Instructions
@@ -9200,6 +9304,18 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
+  predicate(VM_Version::supports_cmov() && UseSSE <=1);
+  match(Set cr (CmpD src1 src2));
+  ins_cost(150);
+  format %{ "FLD    $src1\n\t"
+            "FUCOMIP ST,$src2  // P6 instruction" %}
+  opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+  ins_encode( Push_Reg_D(src1),
+              OpcP, RegOpc(src2));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare & branch
 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
   predicate(UseSSE<=1);
@@ -9264,6 +9380,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
+  predicate(UseSSE>=2);
+  match(Set cr (CmpD dst src));
+  ins_cost(100);
+  format %{ "COMISD $dst,$src" %}
+  opcode(0x66, 0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // float compare and set condition codes in EFLAGS by XMM regs
 instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
   predicate(UseSSE>=2);
@@ -9280,6 +9406,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
+  predicate(UseSSE>=2);
+  match(Set cr (CmpD dst (LoadD src)));
+  ins_cost(100);
+  format %{ "COMISD $dst,$src" %}
+  opcode(0x66, 0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare into -1,0,1 in XMM
 instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
   predicate(UseSSE>=2);
@@ -10167,6 +10303,18 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
+  predicate(VM_Version::supports_cmov() && UseSSE == 0);
+  match(Set cr (CmpF src1 src2));
+  ins_cost(100);
+  format %{ "FLD    $src1\n\t"
+            "FUCOMIP ST,$src2  // P6 instruction" %}
+  opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+  ins_encode( Push_Reg_D(src1),
+              OpcP, RegOpc(src2));
+  ins_pipe( pipe_slow );
+%}
+
 
 // Compare & branch
 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
@@ -10232,6 +10380,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
+  predicate(UseSSE>=1);
+  match(Set cr (CmpF dst src));
+  ins_cost(100);
+  format %{ "COMISS $dst,$src" %}
+  opcode(0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, RegReg(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // float compare and set condition codes in EFLAGS by XMM regs
 instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
   predicate(UseSSE>=1);
@@ -10248,6 +10406,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
+  predicate(UseSSE>=1);
+  match(Set cr (CmpF dst (LoadF src)));
+  ins_cost(100);
+  format %{ "COMISS $dst,$src" %}
+  opcode(0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, RegMem(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare into -1,0,1 in XMM
 instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
   predicate(UseSSE>=1);
@@ -12099,6 +12267,19 @@
   ins_pc_relative(1);
 %}
 
+instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "J$cop,u  $labl\t# Loop end" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode( Jcc( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+%}
+
 // Jump Direct Conditional - using unsigned comparison
 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
   match(If cop cmp);
@@ -12108,8 +12289,63 @@
   format %{ "J$cop,u  $labl" %}
   size(6);
   opcode(0x0F, 0x80);
-  ins_encode( Jcc( cop, labl) );
-  ins_pipe( pipe_jcc );
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "J$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"JP,u   $labl\n\t"
+      $$emit$$"J$cop,u   $labl"
+    } else {
+      $$emit$$"JP,u   done\n\t"
+      $$emit$$"J$cop,u   $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(12);
+  opcode(0x0F, 0x80);
+  ins_encode %{
+    Label* l = $labl$$label;
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, Assembler::parity);
+    int parity_disp = -1;
+    bool ok = false;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+       // the two jumps 6 bytes apart so the jump distances are too
+       parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+       parity_disp = 6;
+       ok = true;
+    } else {
+       ShouldNotReachHere();
+    }
+    emit_d32(cbuf, parity_disp);
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    emit_d32(cbuf, disp);
+  %}
+  ins_pipe(pipe_jcc);
   ins_pc_relative(1);
 %}
 
@@ -12208,7 +12444,7 @@
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "J$cop,s  $labl" %}
+  format %{ "J$cop,s  $labl\t# Loop end" %}
   size(2);
   opcode(0x70);
   ins_encode( JccShort( cop, labl) );
@@ -12223,7 +12459,21 @@
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "J$cop,us $labl" %}
+  format %{ "J$cop,us $labl\t# Loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode( JccShort( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "J$cop,us $labl\t# Loop end" %}
   size(2);
   opcode(0x70);
   ins_encode( JccShort( cop, labl) );
@@ -12247,6 +12497,60 @@
   ins_short_branch(1);
 %}
 
+instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "J$cop,us $labl" %}
+  size(2);
+  opcode(0x70);
+  ins_encode( JccShort( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"JP,u,s   $labl\n\t"
+      $$emit$$"J$cop,u,s   $labl"
+    } else {
+      $$emit$$"JP,u,s   done\n\t"
+      $$emit$$"J$cop,u,s  $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(4);
+  opcode(0x70);
+  ins_encode %{
+    Label* l = $labl$$label;
+    emit_cc(cbuf, $primary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+      parity_disp = 2;
+    } else {
+      ShouldNotReachHere();
+    }
+    emit_d8(cbuf, parity_disp);
+    emit_cc(cbuf, $primary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    emit_d8(cbuf, disp);
+    assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+    assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
 // ============================================================================
 // Long Compare
 //
--- a/src/cpu/x86/vm/x86_64.ad	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/cpu/x86/vm/x86_64.ad	Tue Oct 28 09:31:30 2008 -0700
@@ -2004,9 +2004,12 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset)
-{
-  return -0x80 <= offset && offset < 0x80;
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+  // the short version of jmpConUCF2 contains multiple branches,
+  // making the reach slightly less
+  if (rule == jmpConUCF2_rule)
+    return (-126 <= offset && offset <= 125);
+  return (-128 <= offset && offset <= 127);
 }
 
 const bool Matcher::isSimpleConstant64(jlong value) {
@@ -5134,6 +5137,15 @@
   interface(REG_INTER);
 %}
 
+operand rFlagsRegUCF() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  predicate(false);
+
+  format %{ "RFLAGS_U_CF" %}
+  interface(REG_INTER);
+%}
+
 // Float register operands
 operand regF()
 %{
@@ -5405,12 +5417,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xC);
-    greater_equal(0xD);
-    less_equal(0xE);
-    greater(0xF);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xC, "l");
+    greater_equal(0xD, "ge");
+    less_equal(0xE, "le");
+    greater(0xF, "g");
   %}
 %}
 
@@ -5423,12 +5435,48 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0x2);
-    greater_equal(0x3);
-    less_equal(0x6);
-    greater(0x7);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+            n->as_Bool()->_test._test == BoolTest::ge ||
+            n->as_Bool()->_test._test == BoolTest::le ||
+            n->as_Bool()->_test._test == BoolTest::gt);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+            n->as_Bool()->_test._test == BoolTest::eq);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
   %}
 %}
 
@@ -7176,8 +7224,7 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
-instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
-%{
+instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
 
   ins_cost(200); // XXX
@@ -7187,9 +7234,16 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
+instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovI_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
-instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src)
-%{
+instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
 
   ins_cost(250); // XXX
@@ -7211,6 +7265,14 @@
   ins_pipe(pipe_cmov_mem);
 %}
 
+instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+  ins_cost(250);
+  expand %{
+    cmovI_memU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
 %{
@@ -7224,7 +7286,7 @@
 %}
 
 // Conditional move
-instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
 %{
   match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
 
@@ -7235,6 +7297,14 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
+instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
+  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovN_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
 %{
@@ -7248,7 +7318,7 @@
 %}
 
 // Conditional move
-instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
 %{
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
 
@@ -7259,6 +7329,14 @@
   ins_pipe(pipe_cmov_reg); // XXX
 %}
 
+instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
+  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovP_regU(cop, cr, dst, src);
+  %}
+%}
+
 // DISABLED: Requires the ADLC to emit a bottom_type call that
 // correctly meets the two pointer arguments; one is an incoming
 // register but the other is a memory operand.  ALSO appears to
@@ -7319,6 +7397,14 @@
   ins_pipe(pipe_cmov_reg); // XXX
 %}
 
+instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovL_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
 %{
   match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
@@ -7330,6 +7416,14 @@
   ins_pipe(pipe_cmov_mem); // XXX
 %}
 
+instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
+  ins_cost(200);
+  expand %{
+    cmovL_memU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
 %{
   match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
@@ -7366,6 +7460,14 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
+  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovF_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
 %{
   match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
@@ -7390,6 +7492,14 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
+  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovD_regU(cop, cr, dst, src);
+  %}
+%}
+
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 
@@ -9716,6 +9826,17 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
+  match(Set cr (CmpF src1 src2));
+
+  ins_cost(145);
+  format %{ "ucomiss $src1, $src2" %}
+  ins_encode %{
+    __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
 %{
   match(Set cr (CmpF src1 (LoadF src2)));
@@ -9733,6 +9854,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
+  match(Set cr (CmpF src1 (LoadF src2)));
+
+  ins_cost(100);
+  format %{ "ucomiss $src1, $src2" %}
+  opcode(0x0F, 0x2E);
+  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
 %{
   match(Set cr (CmpF src1 src2));
@@ -9750,6 +9881,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
+  match(Set cr (CmpF src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomiss $src1, $src2" %}
+  opcode(0x0F, 0x2E);
+  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
 %{
   match(Set cr (CmpD src1 src2));
@@ -9767,6 +9908,17 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
+  match(Set cr (CmpD src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, $src2 test" %}
+  ins_encode %{
+    __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
 %{
   match(Set cr (CmpD src1 (LoadD src2)));
@@ -9784,6 +9936,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
+  match(Set cr (CmpD src1 (LoadD src2)));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, $src2" %}
+  opcode(0x66, 0x0F, 0x2E);
+  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
 %{
   match(Set cr (CmpD src1 src2));
@@ -9801,6 +9963,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
+  match(Set cr (CmpD src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, [$src2]" %}
+  opcode(0x66, 0x0F, 0x2E);
+  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 // Compare into -1,0,1
 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
 %{
@@ -11406,8 +11578,7 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
   match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
@@ -11420,14 +11591,39 @@
   ins_pc_relative(1);
 %}
 
+instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "j$cop,u   $labl\t# loop end" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
 // Jump Direct Conditional - using unsigned comparison
-instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
   match(If cop cmp);
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "j$cop,u   $labl" %}
+  format %{ "j$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "j$cop,u  $labl" %}
   size(6);
   opcode(0x0F, 0x80);
   ins_encode(Jcc(cop, labl));
@@ -11435,6 +11631,46 @@
   ins_pc_relative(1);
 %}
 
+instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"jp,u   $labl\n\t"
+      $$emit$$"j$cop,u   $labl"
+    } else {
+      $$emit$$"jp,u   done\n\t"
+      $$emit$$"j$cop,u   $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(12);
+  opcode(0x0F, 0x80);
+  ins_encode %{
+    Label* l = $labl$$label;
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+       // the two jumps 6 bytes apart so the jump distances are too
+       parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+       parity_disp = 6;
+    } else {
+       ShouldNotReachHere();
+    }
+    emit_d32(cbuf, parity_disp);
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    emit_d32(cbuf, disp);
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
 // ============================================================================
 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary
 // superklass array for an instance of the superklass.  Set a hidden
@@ -11505,8 +11741,7 @@
 // specific code section of the file.
 
 // Jump Direct - Label defines a relative address from JMP+1
-instruct jmpDir_short(label labl)
-%{
+instruct jmpDir_short(label labl) %{
   match(Goto);
   effect(USE labl);
 
@@ -11521,8 +11756,7 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
   match(If cop cr);
   effect(USE labl);
 
@@ -11537,13 +11771,12 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
   match(CountedLoopEnd cop cr);
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "j$cop,s   $labl" %}
+  format %{ "j$cop,s   $labl\t# loop end" %}
   size(2);
   opcode(0x70);
   ins_encode(JccShort(cop, labl));
@@ -11553,12 +11786,40 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "j$cop,us  $labl\t# loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode(JccShort(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
   match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
   ins_cost(300);
+  format %{ "j$cop,us  $labl\t# loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode(JccShort(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
   format %{ "j$cop,us  $labl" %}
   size(2);
   opcode(0x70);
@@ -11568,9 +11829,7 @@
   ins_short_branch(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
   match(If cop cmp);
   effect(USE labl);
 
@@ -11584,6 +11843,46 @@
   ins_short_branch(1);
 %}
 
+instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"jp,u,s   $labl\n\t"
+      $$emit$$"j$cop,u,s   $labl"
+    } else {
+      $$emit$$"jp,u,s   done\n\t"
+      $$emit$$"j$cop,u,s  $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(4);
+  opcode(0x70);
+  ins_encode %{
+    Label* l = $labl$$label;
+    emit_cc(cbuf, $primary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+      parity_disp = 2;
+    } else {
+      ShouldNotReachHere();
+    }
+    emit_d8(cbuf, parity_disp);
+    emit_cc(cbuf, $primary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    emit_d8(cbuf, disp);
+    assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+    assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
 // ============================================================================
 // inlined locking and unlocking
 
--- a/src/share/vm/adlc/adlparse.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/adlparse.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -33,7 +33,6 @@
     _globalNames(archDesc.globalNames()) {
   _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
   _AD._warnings    = 0;                      // No warnings either
-  _linenum         = 0;                      // Will increment to first line
   _curline         = _ptr = NULL;            // No pointers into buffer yet
 
   _preproc_depth = 0;
@@ -76,7 +75,7 @@
   }
   if (!_AD._quiet_mode)
     fprintf(stderr,"-----------------------------------------------------------------------------\n");
-  _AD._TotalLines += _linenum-1;     // -1 for overshoot in "nextline" routine
+  _AD._TotalLines += linenum()-1;     // -1 for overshoot in "nextline" routine
 
   // Write out information we have stored
   // // UNIXism == fsync(stderr);
@@ -148,7 +147,7 @@
   if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
     return;
   instr = new InstructForm(ident); // Create new instruction form
-  instr->_linenum = _linenum;
+  instr->_linenum = linenum();
   _globalNames.Insert(ident, instr); // Add name to the name table
   // Debugging Stuff
   if (_AD._adl_debug > 1)
@@ -404,7 +403,7 @@
   if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
     return;
   oper = new OperandForm(ident);        // Create new operand form
-  oper->_linenum = _linenum;
+  oper->_linenum = linenum();
   _globalNames.Insert(ident, oper); // Add name to the name table
 
   // Debugging Stuff
@@ -774,7 +773,7 @@
 
   // Create the RegisterForm for the architecture description.
   RegisterForm *regBlock = new RegisterForm();    // Build new Source object
-  regBlock->_linenum = _linenum;
+  regBlock->_linenum = linenum();
   _AD.addForm(regBlock);
 
   skipws();                       // Skip leading whitespace
@@ -847,7 +846,7 @@
   }
 
   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
-  encoding->_linenum = _linenum;
+  encoding->_linenum = linenum();
 
   skipws();                      // Skip leading whitespace
   // Check for optional parameter list
@@ -905,7 +904,7 @@
   // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
   if (_AD._adlocation_debug) {
     const char* file     = _AD._ADL_file._name;
-    int         line     = _linenum;
+    int         line     = linenum();
     char*       location = (char *)malloc(strlen(file) + 100);
     sprintf(location, "#line %d \"%s\"\n", line, file);
     encoding->add_code(location);
@@ -2776,7 +2775,7 @@
 
   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
-  encoding->_linenum = _linenum;
+  encoding->_linenum = linenum();
 
   // synthesize the arguments list for the enc_class from the
   // arguments to the instruct definition.
@@ -2852,7 +2851,7 @@
   skipws();
 
   InsEncode *encrule  = new InsEncode(); // Encode class for instruction
-  encrule->_linenum = _linenum;
+  encrule->_linenum = linenum();
   char      *ec_name  = NULL;      // String representation of encode rule
   // identifier is optional.
   while (_curchar != ')') {
@@ -3203,6 +3202,12 @@
   char *greater_equal;
   char *less_equal;
   char *greater;
+  const char *equal_format = "eq";
+  const char *not_equal_format = "ne";
+  const char *less_format = "lt";
+  const char *greater_equal_format = "ge";
+  const char *less_equal_format = "le";
+  const char *greater_format = "gt";
 
   if (_curchar != '%') {
     parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
@@ -3222,22 +3227,22 @@
       return NULL;
     }
     if ( strcmp(field,"equal") == 0 ) {
-      equal  = interface_field_parse();
+      equal  = interface_field_parse(&equal_format);
     }
     else if ( strcmp(field,"not_equal") == 0 ) {
-      not_equal = interface_field_parse();
+      not_equal = interface_field_parse(&not_equal_format);
     }
     else if ( strcmp(field,"less") == 0 ) {
-      less = interface_field_parse();
+      less = interface_field_parse(&less_format);
     }
     else if ( strcmp(field,"greater_equal") == 0 ) {
-      greater_equal  = interface_field_parse();
+      greater_equal  = interface_field_parse(&greater_equal_format);
     }
     else if ( strcmp(field,"less_equal") == 0 ) {
-      less_equal = interface_field_parse();
+      less_equal = interface_field_parse(&less_equal_format);
     }
     else if ( strcmp(field,"greater") == 0 ) {
-      greater = interface_field_parse();
+      greater = interface_field_parse(&greater_format);
     }
     else {
       parse_err(SYNERR, "Expected keyword, base|index|scale|disp,  or '%}' ending interface.\n");
@@ -3252,14 +3257,18 @@
   next_char();                  // Skip '}'
 
   // Construct desired object and return
-  Interface *inter = new CondInterface(equal, not_equal, less, greater_equal,
-                                       less_equal, greater);
+  Interface *inter = new CondInterface(equal,         equal_format,
+                                       not_equal,     not_equal_format,
+                                       less,          less_format,
+                                       greater_equal, greater_equal_format,
+                                       less_equal,    less_equal_format,
+                                       greater,       greater_format);
   return inter;
 }
 
 
 //------------------------------interface_field_parse--------------------------
-char *ADLParser::interface_field_parse(void) {
+char *ADLParser::interface_field_parse(const char ** format) {
   char *iface_field = NULL;
 
   // Get interface field
@@ -3280,6 +3289,32 @@
     return NULL;
   }
   skipws();
+  if (format != NULL && _curchar == ',') {
+    next_char();
+    skipws();
+    if (_curchar != '"') {
+      parse_err(SYNERR, "Missing '\"' in field format .\n");
+      return NULL;
+    }
+    next_char();
+    char *start = _ptr;       // Record start of the next string
+    while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+      if (_curchar == '\\')  next_char();  // superquote
+      if (_curchar == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
+      next_char();
+    }
+    if (_curchar != '"') {
+      parse_err(SYNERR, "Missing '\"' at end of field format .\n");
+      return NULL;
+    }
+    // If a string was found, terminate it and record in FormatRule
+    if ( start != _ptr ) {
+      *_ptr  = '\0';          // Terminate the string
+      *format = start;
+    }
+    next_char();
+    skipws();
+  }
   if (_curchar != ')') {
     parse_err(SYNERR, "Missing ')' after interface field.\n");
     return NULL;
@@ -3342,6 +3377,12 @@
     next_char();                  // Move past the '{'
 
     skipws();
+    if (_curchar == '$') {
+      char* ident = get_rep_var_ident();
+      if (strcmp(ident, "$$template") == 0) return template_parse();
+      parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
+      return NULL;
+    }
     // Check for the opening '"' inside the format description
     if ( _curchar == '"' ) {
       next_char();              // Move past the initial '"'
@@ -3433,6 +3474,131 @@
 }
 
 
+//------------------------------template_parse-----------------------------------
+FormatRule* ADLParser::template_parse(void) {
+  char       *desc   = NULL;
+  FormatRule *format = (new FormatRule(desc));
+
+  skipws();
+  while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
+
+    // (1)
+    // Check if there is a string to pass through to output
+    char *start = _ptr;       // Record start of the next string
+    while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
+      // If at the start of a comment, skip past it
+      if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
+        skipws_no_preproc();
+      } else {
+        // ELSE advance to the next character, or start of the next line
+        next_char_or_line();
+      }
+    }
+    // If a string was found, terminate it and record in EncClass
+    if ( start != _ptr ) {
+      *_ptr  = '\0';          // Terminate the string
+      // Add flag to _strings list indicating we should check _rep_vars
+      format->_strings.addName(NameList::_signal2);
+      format->_strings.addName(start);
+    }
+
+    // (2)
+    // If we are at a replacement variable,
+    // copy it and record in EncClass
+    if ( _curchar == '$' ) {
+      // Found replacement Variable
+      char *rep_var = get_rep_var_ident_dup();
+      if (strcmp(rep_var, "$emit") == 0) {
+        // switch to normal format parsing
+        next_char();
+        next_char();
+        skipws();
+        // Check for the opening '"' inside the format description
+        if ( _curchar == '"' ) {
+          next_char();              // Move past the initial '"'
+          if( _curchar == '"' ) {   // Handle empty format string case
+            *_ptr = '\0';           // Terminate empty string
+            format->_strings.addName(_ptr);
+          }
+
+          // Collect the parts of the format description
+          // (1) strings that are passed through to tty->print
+          // (2) replacement/substitution variable, preceeded by a '$'
+          // (3) multi-token ANSIY C style strings
+          while ( true ) {
+            if ( _curchar == '%' || _curchar == '\n' ) {
+              parse_err(SYNERR, "missing '\"' at end of format block");
+              return NULL;
+            }
+
+            // (1)
+            // Check if there is a string to pass through to output
+            char *start = _ptr;       // Record start of the next string
+            while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+              if (_curchar == '\\')  next_char();  // superquote
+              if (_curchar == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
+              next_char();
+            }
+            // If a string was found, terminate it and record in FormatRule
+            if ( start != _ptr ) {
+              *_ptr  = '\0';          // Terminate the string
+              format->_strings.addName(start);
+            }
+
+            // (2)
+            // If we are at a replacement variable,
+            // copy it and record in FormatRule
+            if ( _curchar == '$' ) {
+              next_char();          // Move past the '$'
+              char* rep_var = get_ident(); // Nil terminate the variable name
+              rep_var = strdup(rep_var);// Copy the string
+              *_ptr   = _curchar;     // and replace Nil with original character
+              format->_rep_vars.addName(rep_var);
+              // Add flag to _strings list indicating we should check _rep_vars
+              format->_strings.addName(NameList::_signal);
+            }
+
+            // (3)
+            // Allow very long strings to be broken up,
+            // using the ANSI C syntax "foo\n" <newline> "bar"
+            if ( _curchar == '"') {
+              next_char();           // Move past the '"'
+              skipws();              // Skip white space before next string token
+              if ( _curchar != '"') {
+                break;
+              } else {
+                // Found one.  Skip both " and the whitespace in between.
+                next_char();
+              }
+            }
+          } // end while part of format description
+        }
+      } else {
+        // Add flag to _strings list indicating we should check _rep_vars
+        format->_rep_vars.addName(rep_var);
+        // Add flag to _strings list indicating we should check _rep_vars
+        format->_strings.addName(NameList::_signal3);
+      }
+    } // end while part of format description
+  }
+
+  skipws();
+  // Past format description, at '%'
+  if ( _curchar != '%' || *(_ptr+1) != '}' ) {
+    parse_err(SYNERR, "missing '%}' at end of format block");
+    return NULL;
+  }
+  next_char();                  // Move past the '%'
+  next_char();                  // Move past the '}'
+
+  // Debug Stuff
+  if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
+
+  skipws();
+  return format;
+}
+
+
 //------------------------------effect_parse-----------------------------------
 void ADLParser::effect_parse(InstructForm *instr) {
   char* desc   = NULL;
@@ -3777,7 +3943,7 @@
     skipws_no_preproc();          // Skip leading whitespace
     cppBlock = _ptr;              // Point to start of expression
     const char* file = _AD._ADL_file._name;
-    int         line = _linenum;
+    int         line = linenum();
     next = _ptr + 1;
     while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
       next_char_or_line();
@@ -4297,11 +4463,11 @@
 
   va_start(args, fmt);
   if (flag == 1)
-    _AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
   else if (flag == 2)
-    _AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
   else
-    _AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
 
   int error_char = _curchar;
   char* error_ptr = _ptr+1;
@@ -4515,7 +4681,7 @@
 
 //---------------------------next_line-----------------------------------------
 void ADLParser::next_line() {
-  _curline = _buf.get_line(); _linenum++;
+  _curline = _buf.get_line();
 }
 
 //-------------------------is_literal_constant---------------------------------
--- a/src/share/vm/adlc/adlparse.hpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/adlparse.hpp	Tue Oct 28 09:31:30 2008 -0700
@@ -70,7 +70,6 @@
 protected:
   char     *_curline;           // Start of current line
   char     *_ptr;               // Pointer into current location in File Buffer
-  int       _linenum;           // Count of line numbers seen so far
   char      _curchar;           // Current character from buffer
   FormDict &_globalNames;       // Global names
 
@@ -160,9 +159,10 @@
   Interface     *interface_parse();      // Parse operand interface rule
   Interface     *mem_interface_parse();  // Parse memory interface rule
   Interface     *cond_interface_parse(); // Parse conditional interface rule
-  char          *interface_field_parse();// Parse field contents
+  char          *interface_field_parse(const char** format = NULL);// Parse field contents
 
   FormatRule    *format_parse(void);     // Parse format rule
+  FormatRule    *template_parse(void);     // Parse format rule
   void           effect_parse(InstructForm *instr); // Parse effect rule
   ExpandRule    *expand_parse(InstructForm *instr); // Parse expand rule
   RewriteRule   *rewrite_parse(void);    // Parse rewrite rule
@@ -263,7 +263,7 @@
 
   void parse(void);             // Do the parsing & build forms lists
 
-  int getlines( ) { return _linenum; }
+  int linenum() { return _buf.linenum(); }
 
   static bool is_literal_constant(const char *hex_string);
   static bool is_hex_digit(char digit);
--- a/src/share/vm/adlc/filebuff.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/filebuff.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -41,6 +41,7 @@
     exit(1);                    // Exit on seek error
   }
   _filepos = ftell(_fp->_fp);      // Reset current file position
+  _linenum = 0;
 
   _bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
   if( !_bigbuf ) {
@@ -76,6 +77,7 @@
   // Check for end of file & return NULL
   if (_bufeol >= _bufmax) return NULL;
 
+  _linenum++;
   retval = ++_bufeol;      // return character following end of previous line
   if (*retval == '\0') return NULL; // Check for EOF sentinal
   // Search for newline character which must end each line
--- a/src/share/vm/adlc/filebuff.hpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/filebuff.hpp	Tue Oct 28 09:31:30 2008 -0700
@@ -51,6 +51,7 @@
 
   int   _err;                   // Error flag for file seek/read operations
   long  _filepos;               // Current offset from start of file
+  int   _linenum;
 
   ArchDesc& _AD;                // Reference to Architecture Description
 
@@ -66,6 +67,7 @@
   // This returns a pointer to the start of the current line in the buffer,
   // and increments bufeol and filepos to point at the end of that line.
   char *get_line(void);
+  int linenum() const { return _linenum; }
 
   // This converts a pointer into the buffer to a file offset.  It only works
   // when the pointer is valid (i.e. just obtained from getline()).
--- a/src/share/vm/adlc/forms.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/forms.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -35,6 +35,8 @@
 //------------------------------NameList---------------------------------------
 // reserved user-defined string
 const char  *NameList::_signal   = "$$SIGNAL$$";
+const char  *NameList::_signal2  = "$$SIGNAL2$$";
+const char  *NameList::_signal3  = "$$SIGNAL3$$";
 
 // Constructor and Destructor
 NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
--- a/src/share/vm/adlc/forms.hpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/forms.hpp	Tue Oct 28 09:31:30 2008 -0700
@@ -329,6 +329,8 @@
 
 public:
   static const char *_signal;      // reserved user-defined string
+  static const char *_signal2;      // reserved user-defined string
+  static const char *_signal3;      // reserved user-defined string
   enum               { Not_in_list = -1 };
 
   void  addName(const char *name);
--- a/src/share/vm/adlc/formssel.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/formssel.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -1574,10 +1574,10 @@
   return Opcode::NOT_AN_OPCODE;
 }
 
-void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
+bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
   // Default values previously provided by MachNode::primary()...
-  const char *description = "default_opcode()";
-  const char *value       = "-1";
+  const char *description = NULL;
+  const char *value       = NULL;
   // Check if user provided any opcode definitions
   if( this != NULL ) {
     // Update 'value' if user provided a definition in the instruction
@@ -1599,7 +1599,10 @@
       break;
     }
   }
-  fprintf(fp, "(%s /*%s*/)", value, description);
+  if (value != NULL) {
+    fprintf(fp, "(%s /*%s*/)", value, description);
+  }
+  return value != NULL;
 }
 
 void Opcode::dump() {
@@ -2610,14 +2613,19 @@
 }
 
 //------------------------------CondInterface----------------------------------
-CondInterface::CondInterface(char *equal,      char *not_equal,
-                             char *less,       char *greater_equal,
-                             char *less_equal, char *greater)
+CondInterface::CondInterface(const char* equal,         const char* equal_format,
+                             const char* not_equal,     const char* not_equal_format,
+                             const char* less,          const char* less_format,
+                             const char* greater_equal, const char* greater_equal_format,
+                             const char* less_equal,    const char* less_equal_format,
+                             const char* greater,       const char* greater_format)
   : Interface("COND_INTER"),
-    _equal(equal), _not_equal(not_equal),
-    _less(less), _greater_equal(greater_equal),
-    _less_equal(less_equal), _greater(greater) {
-      //
+    _equal(equal),                 _equal_format(equal_format),
+    _not_equal(not_equal),         _not_equal_format(not_equal_format),
+    _less(less),                   _less_format(less_format),
+    _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
+    _less_equal(less_equal),       _less_equal_format(less_equal_format),
+    _greater(greater),             _greater_format(greater_format) {
 }
 CondInterface::~CondInterface() {
   // not owner of any character arrays
--- a/src/share/vm/adlc/formssel.hpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/formssel.hpp	Tue Oct 28 09:31:30 2008 -0700
@@ -397,7 +397,7 @@
   void output(FILE *fp);
 
   // --------------------------- FILE *output_routines
-  void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
+  bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
 };
 
 //------------------------------InsEncode--------------------------------------
@@ -779,10 +779,20 @@
   const char *_greater_equal;
   const char *_less_equal;
   const char *_greater;
+  const char *_equal_format;
+  const char *_not_equal_format;
+  const char *_less_format;
+  const char *_greater_equal_format;
+  const char *_less_equal_format;
+  const char *_greater_format;
 
   // Public Methods
-  CondInterface(char *equal, char *not_equal, char *less, char *greater_equal,
-                char *less_equal, char *greater);
+  CondInterface(const char* equal,         const char* equal_format,
+                const char* not_equal,     const char* not_equal_format,
+                const char* less,          const char* less_format,
+                const char* greater_equal, const char* greater_equal_format,
+                const char* less_equal,    const char* less_equal_format,
+                const char* greater,       const char* greater_format);
   ~CondInterface();
 
   void dump();
--- a/src/share/vm/adlc/output_c.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/output_c.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -1619,6 +1619,7 @@
       }
 
       // Iterate over the new instruction's operands
+      int prev_pos = -1;
       for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
         // Use 'parameter' at current position in list of new instruction's formals
         // instead of 'opid' when looking up info internal to new_inst
@@ -1642,6 +1643,18 @@
           // ins = (InstructForm *) _globalNames[new_id];
           exp_pos = node->operand_position_format(opid);
           assert(exp_pos != -1, "Bad expand rule");
+          if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
+            // For the add_req calls below to work correctly they need
+            // to added in the same order that a match would add them.
+            // This means that they would need to be in the order of
+            // the components list instead of the formal parameters.
+            // This is a sort of hidden invariant that previously
+            // wasn't checked and could lead to incorrectly
+            // constructed nodes.
+            syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
+                       node->_ident, new_inst->_ident);
+          }
+          prev_pos = exp_pos;
 
           new_pos = new_inst->operand_position(parameter,Component::USE);
           if (new_pos != -1) {
@@ -2306,7 +2319,12 @@
     _processing_noninput = false;
     // A replacement variable, originally '$'
     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
-      _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
+      if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
+        // Missing opcode
+        _AD.syntax_err( _inst._linenum,
+                        "Missing $%s opcode definition in %s, used by encoding %s\n",
+                        rep_var, _inst._ident, _encoding._name);
+      }
     }
     else {
       // Lookup its position in parameter list
@@ -2348,7 +2366,13 @@
       else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
         // else check if "primary", "secondary", "tertiary"
         assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
-        _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
+        if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
+          // Missing opcode
+          _AD.syntax_err( _inst._linenum,
+                          "Missing $%s opcode definition in %s\n",
+                          rep_var, _inst._ident);
+
+        }
         _constant_status = LITERAL_OUTPUT;
       }
       else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
--- a/src/share/vm/adlc/output_h.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/adlc/output_h.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -355,17 +355,19 @@
 // ---------------------------------------------------------------------------
 
 // Generate the format rule for condition codes
-static void defineCCodeDump(FILE *fp, int i) {
-  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i);
+static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
+  assert(oper != NULL, "what");
+  CondInterface* cond = oper->_interface->is_CondInterface();
+  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
 }
 
 // Output code that dumps constant values, increment "i" if type is constant
-static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
+static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
   if (!strcmp(ideal_type, "ConI")) {
     fprintf(fp,"   st->print(\"#%%d\", _c%d);\n", i);
     ++i;
@@ -391,7 +393,7 @@
     ++i;
   }
   else if (!strcmp(ideal_type, "Bool")) {
-    defineCCodeDump(fp,i);
+    defineCCodeDump(oper, fp,i);
     ++i;
   }
 
@@ -476,7 +478,7 @@
   }
   // ALWAYS! Provide a special case output for condition codes.
   if( oper.is_ideal_bool() ) {
-    defineCCodeDump(fp,0);
+    defineCCodeDump(&oper, fp,0);
   }
   fprintf(fp,"}\n");
 
@@ -549,7 +551,7 @@
   }
   // ALWAYS! Provide a special case output for condition codes.
   if( oper.is_ideal_bool() ) {
-    defineCCodeDump(fp,0);
+    defineCCodeDump(&oper, fp,0);
   }
   fprintf(fp, "}\n");
   fprintf(fp, "#endif\n");
@@ -583,10 +585,53 @@
     while( (string = inst._format->_strings.iter()) != NULL ) {
       fprintf(fp,"    ");
       // Check if this is a standard string or a replacement variable
-      if( string != NameList::_signal )  // Normal string.  Pass through.
+      if( string == NameList::_signal ) { // Replacement variable
+        const char* rep_var =  inst._format->_rep_vars.iter();
+        inst.rep_var_format( fp, rep_var);
+      } else if( string == NameList::_signal3 ) { // Replacement variable in raw text
+        const char* rep_var =  inst._format->_rep_vars.iter();
+        const Form *form   = inst._localNames[rep_var];
+        if (form == NULL) {
+          fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
+          assert(false, "ShouldNotReachHere()");
+        }
+        OpClassForm *opc   = form->is_opclass();
+        assert( opc, "replacement variable was not found in local names");
+        // Lookup the index position of the replacement variable
+        int idx  = inst.operand_position_format(rep_var);
+        if ( idx == -1 ) {
+          assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
+          assert( false, "ShouldNotReachHere()");
+        }
+
+        if (inst.is_noninput_operand(idx)) {
+          assert( false, "ShouldNotReachHere()");
+        } else {
+          // Output the format call for this operand
+          fprintf(fp,"opnd_array(%d)",idx);
+        }
+        rep_var =  inst._format->_rep_vars.iter();
+        inst._format->_strings.iter();
+        if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
+          Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
+          if ( constant_type == Form::idealD ) {
+            fprintf(fp,"->constantD()");
+          } else if ( constant_type == Form::idealF ) {
+            fprintf(fp,"->constantF()");
+          } else if ( constant_type == Form::idealL ) {
+            fprintf(fp,"->constantL()");
+          } else {
+            fprintf(fp,"->constant()");
+          }
+        } else if ( strcmp(rep_var,"$cmpcode") == 0) {
+            fprintf(fp,"->ccode()");
+        } else {
+          assert( false, "ShouldNotReachHere()");
+        }
+      } else if( string == NameList::_signal2 ) // Raw program text
+        fputs(inst._format->_strings.iter(), fp);
+      else
         fprintf(fp,"st->print(\"%s\");\n", string);
-      else                      // Replacement variable
-        inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
     } // Done with all format strings
   } // Done generating the user-defined portion of the format
 
@@ -1404,7 +1449,7 @@
       oper->_components.reset();
       if ((comp = oper->_components.iter()) == NULL) {
         assert(num_consts == 1, "Bad component list detected.\n");
-        i = dump_spec_constant( fp, type, i );
+        i = dump_spec_constant( fp, type, i, oper );
         // Check that type actually matched
         assert( i != 0, "Non-constant operand lacks component list.");
       } // end if NULL
@@ -1414,7 +1459,7 @@
         oper->_components.reset();
         while((comp = oper->_components.iter()) != NULL) {
           type = comp->base_type(_globalNames);
-          i = dump_spec_constant( fp, type, i );
+          i = dump_spec_constant( fp, type, i, NULL );
         }
       }
       // finish line (3)
--- a/src/share/vm/opto/matcher.hpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/opto/matcher.hpp	Tue Oct 28 09:31:30 2008 -0700
@@ -324,7 +324,7 @@
   virtual int      regnum_to_fpu_offset(int regnum);
 
   // Is this branch offset small enough to be addressed by a short branch?
-  bool is_short_branch_offset(int offset);
+  bool is_short_branch_offset(int rule, int offset);
 
   // Optional scaling for the parameter to the ClearArray/CopyArray node.
   static const bool init_array_count_is_in_bytes;
--- a/src/share/vm/opto/output.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/opto/output.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -332,6 +332,7 @@
   uint *jmp_end    = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
   uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
   DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
+  DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
   blk_starts[0]    = 0;
 
   // Initialize the sizes to 0
@@ -443,9 +444,9 @@
         uintptr_t target = blk_starts[bnum];
         if( mach->is_pc_relative() ) {
           int offset = target-(blk_starts[i] + jmp_end[i]);
-          if (_matcher->is_short_branch_offset(offset)) {
+          if (_matcher->is_short_branch_offset(mach->rule(), offset)) {
             // We've got a winner.  Replace this branch.
-            MachNode *replacement = mach->short_branch_version(this);
+            MachNode* replacement = mach->short_branch_version(this);
             b->_nodes.map(j, replacement);
             mach->subsume_by(replacement);
 
@@ -453,6 +454,7 @@
             // next pass.
             jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
             DEBUG_ONLY( jmp_target[i] = bnum; );
+            DEBUG_ONLY( jmp_rule[i] = mach->rule(); );
           }
         } else {
 #ifndef PRODUCT
@@ -524,10 +526,10 @@
   for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
     if( jmp_target[i] != 0 ) {
       int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
-      if (!_matcher->is_short_branch_offset(offset)) {
+      if (!_matcher->is_short_branch_offset(jmp_rule[i], offset)) {
         tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
       }
-      assert(_matcher->is_short_branch_offset(offset), "Displacement too large for short jmp");
+      assert(_matcher->is_short_branch_offset(jmp_rule[i], offset), "Displacement too large for short jmp");
     }
   }
 #endif
@@ -1069,7 +1071,7 @@
 
   // If this machine supports different size branch offsets, then pre-compute
   // the length of the blocks
-  if( _matcher->is_short_branch_offset(0) ) {
+  if( _matcher->is_short_branch_offset(-1, 0) ) {
     Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
     labels_not_set = false;
   }
--- a/src/share/vm/opto/reg_split.cpp	Tue Oct 21 11:23:52 2008 -0700
+++ b/src/share/vm/opto/reg_split.cpp	Tue Oct 28 09:31:30 2008 -0700
@@ -53,6 +53,7 @@
   // Bail rather than abort
   int ireg = def->ideal_reg();
   if( ireg == 0 || ireg == Op_RegFlags ) {
+    assert(false, "attempted to spill a non-spillable item");
     C->record_method_not_compilable("attempted to spill a non-spillable item");
     return NULL;
   }