src/cpu/mips/vm/mips_64.ad

Tue, 28 Mar 2017 16:09:10 -0400

author
fujie
date
Tue, 28 Mar 2017 16:09:10 -0400
changeset 389
76857a2c3534
parent 388
854749bf3dde
child 390
d3aefa77da6c
permissions
-rw-r--r--

Add UseCodeCacheAllocOpt for MIPS.

     1 //
     2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     3 // Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
     4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5 //
     6 // This code is free software; you can redistribute it and/or modify it
     7 // under the terms of the GNU General Public License version 2 only, as
     8 // published by the Free Software Foundation.
     9 //
    10 // This code is distributed in the hope that it will be useful, but WITHOUT
    11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13 // version 2 for more details (a copy is included in the LICENSE file that
    14 // accompanied this code).
    15 //
    16 // You should have received a copy of the GNU General Public License version
    17 // 2 along with this work; if not, write to the Free Software Foundation,
    18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19 //
    20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21 // or visit www.oracle.com if you need additional information or have any
    22 // questions.
    23 //
    24 //
    26 // GodSon3 Architecture Description File
    28 //----------REGISTER DEFINITION BLOCK------------------------------------------
    29 // This information is used by the matcher and the register allocator to
    30 // describe individual registers and classes of registers within the target
    31 // archtecture.
    33 // format:
    34 // reg_def name (call convention, c-call convention, ideal type, encoding);
    35 // 		call convention : 
    36 //			NS  = No-Save
    37 //			SOC = Save-On-Call
    38 //			SOE = Save-On-Entry
    39 //			AS  = Always-Save
    40 //		ideal type :
    41 //			see opto/opcodes.hpp for more info
    42 // reg_class name (reg, ...);
    43 // alloc_class name (reg, ...); 
    44 register %{
    46 // General Registers
    47 // Integer Registers
    48 	reg_def R0	    ( NS,  NS, 	Op_RegI,  0, VMRegImpl::Bad());
    49 	reg_def AT		( NS,  NS, 	Op_RegI,  1, AT->as_VMReg());
    50 	reg_def AT_H    ( NS,  NS,  Op_RegI,  1, AT->as_VMReg()->next());
    51 	reg_def V0		(SOC, SOC,	Op_RegI,  2, V0->as_VMReg());
    52 	reg_def V0_H	(SOC, SOC,	Op_RegI,  2, V0->as_VMReg()->next());
    53 	reg_def V1		(SOC, SOC,	Op_RegI,  3, V1->as_VMReg());
    54 	reg_def V1_H	(SOC, SOC,	Op_RegI,  3, V1->as_VMReg()->next());
    55 	reg_def A0		(SOC, SOC,	Op_RegI,  4, A0->as_VMReg());
    56 	reg_def A0_H	(SOC, SOC,	Op_RegI,  4, A0->as_VMReg()->next());
    57 	reg_def A1		(SOC, SOC,	Op_RegI,  5, A1->as_VMReg());
    58 	reg_def A1_H	(SOC, SOC,	Op_RegI,  5, A1->as_VMReg()->next());
    59 	reg_def A2		(SOC, SOC,	Op_RegI,  6, A2->as_VMReg());
    60 	reg_def A2_H	(SOC, SOC,	Op_RegI,  6, A2->as_VMReg()->next());
    61 	reg_def A3		(SOC, SOC,	Op_RegI,  7, A3->as_VMReg());
    62 	reg_def A3_H	(SOC, SOC,	Op_RegI,  7, A3->as_VMReg()->next());
    63 	reg_def A4		(SOC, SOC,	Op_RegI,  8, A4->as_VMReg());
    64 	reg_def A4_H	(SOC, SOC,	Op_RegI,  8, A4->as_VMReg()->next());
    65 	reg_def A5		(SOC, SOC,	Op_RegI,  9, A5->as_VMReg());
    66 	reg_def A5_H	(SOC, SOC,	Op_RegI,  9, A5->as_VMReg()->next());
    67 	reg_def A6		(SOC, SOC,	Op_RegI,  10, A6->as_VMReg());
    68 	reg_def A6_H	(SOC, SOC,	Op_RegI,  10, A6->as_VMReg()->next());
    69 	reg_def A7		(SOC, SOC,	Op_RegI,  11, A7->as_VMReg());
    70 	reg_def A7_H	(SOC, SOC,	Op_RegI,  11, A7->as_VMReg()->next());
    71 	reg_def T0		(SOC, SOC,	Op_RegI,  12, T0->as_VMReg());
    72 	reg_def T0_H	(SOC, SOC,	Op_RegI,  12, T0->as_VMReg()->next());
    73 	reg_def T1		(SOC, SOC,	Op_RegI,  13, T1->as_VMReg());
    74 	reg_def T1_H	(SOC, SOC,	Op_RegI,  13, T1->as_VMReg()->next());
    75 	reg_def T2		(SOC, SOC,	Op_RegI,  14, T2->as_VMReg());
    76 	reg_def T2_H	(SOC, SOC,	Op_RegI,  14, T2->as_VMReg()->next());
    77 	reg_def T3		(SOC, SOC,	Op_RegI,  15, T3->as_VMReg());
    78 	reg_def T3_H	(SOC, SOC,	Op_RegI,  15, T3->as_VMReg()->next());
    79 	reg_def S0		(SOC, SOE,	Op_RegI,  16, S0->as_VMReg());
    80 	reg_def S0_H	(SOC, SOE,	Op_RegI,  16, S0->as_VMReg()->next());
    81 	reg_def S1		(SOC, SOE,	Op_RegI,  17, S1->as_VMReg());
    82 	reg_def S1_H	(SOC, SOE,	Op_RegI,  17, S1->as_VMReg()->next());
    83 	reg_def S2		(SOC, SOE,	Op_RegI,  18, S2->as_VMReg());
    84 	reg_def S2_H	(SOC, SOE,	Op_RegI,  18, S2->as_VMReg()->next());
    85 	reg_def S3		(SOC, SOE,	Op_RegI,  19, S3->as_VMReg());
    86 	reg_def S3_H	(SOC, SOE,	Op_RegI,  19, S3->as_VMReg()->next());
    87 	reg_def S4		(SOC, SOE,	Op_RegI,  20, S4->as_VMReg());
    88 	reg_def S4_H	(SOC, SOE,	Op_RegI,  20, S4->as_VMReg()->next());
    89 	reg_def S5		(SOC, SOE,	Op_RegI,  21, S5->as_VMReg());
    90 	reg_def S5_H	(SOC, SOE,	Op_RegI,  21, S5->as_VMReg()->next());
    91 	reg_def S6		(SOC, SOE,	Op_RegI,  22, S6->as_VMReg());
    92 	reg_def S6_H	(SOC, SOE,	Op_RegI,  22, S6->as_VMReg()->next());
    93 	reg_def S7		(SOC, SOE,	Op_RegI,  23, S7->as_VMReg());
    94 	reg_def S7_H	(SOC, SOE,	Op_RegI,  23, S7->as_VMReg()->next());
    95 	reg_def T8		(SOC, SOC,	Op_RegI,  24, T8->as_VMReg());
    96 	reg_def T8_H	(SOC, SOC,	Op_RegI,  24, T8->as_VMReg()->next());
    97 	reg_def T9		(SOC, SOC,	Op_RegI,  25, T9->as_VMReg());
    98 	reg_def T9_H	(SOC, SOC,	Op_RegI,  25, T9->as_VMReg()->next());
   100 // Special Registers
   101 	reg_def K0		( NS,  NS,	Op_RegI, 26, K0->as_VMReg());
   102 	reg_def K1		( NS,  NS,	Op_RegI, 27, K1->as_VMReg());
   103 	reg_def GP		( NS,  NS,	Op_RegI, 28, GP->as_VMReg());
   104 	reg_def GP_H	( NS,  NS,	Op_RegI, 28, GP->as_VMReg()->next());
   105 	reg_def SP		( NS,  NS,	Op_RegI, 29, SP->as_VMReg());
   106 	reg_def SP_H	( NS,  NS,	Op_RegI, 29, SP->as_VMReg()->next());
   107 	reg_def FP		( NS,  NS,	Op_RegI, 30, FP->as_VMReg());
   108 	reg_def FP_H	( NS,  NS,	Op_RegI, 30, FP->as_VMReg()->next());
   109 	reg_def RA		( NS,  NS,	Op_RegI, 31, RA->as_VMReg());
   110 	reg_def RA_H	( NS,  NS,	Op_RegI, 31, RA->as_VMReg()->next());
   112 // Floating registers. 
   113 reg_def F0          ( SOC, SOC, Op_RegF, 0, F0->as_VMReg());
   114 reg_def F0_H        ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()->next());
   115 reg_def F1          ( SOC, SOC, Op_RegF, 1, F1->as_VMReg());
   116 reg_def F1_H        ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()->next());
   117 reg_def F2          ( SOC, SOC, Op_RegF, 2, F2->as_VMReg());
   118 reg_def F2_H        ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()->next());
   119 reg_def F3          ( SOC, SOC, Op_RegF, 3, F3->as_VMReg());
   120 reg_def F3_H        ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()->next());
   121 reg_def F4          ( SOC, SOC, Op_RegF, 4, F4->as_VMReg());
   122 reg_def F4_H        ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()->next());
   123 reg_def F5          ( SOC, SOC, Op_RegF, 5, F5->as_VMReg());
   124 reg_def F5_H        ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()->next());
   125 reg_def F6          ( SOC, SOC, Op_RegF, 6, F6->as_VMReg());
   126 reg_def F6_H        ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()->next());
   127 reg_def F7          ( SOC, SOC, Op_RegF, 7, F7->as_VMReg());
   128 reg_def F7_H        ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()->next());
   129 reg_def F8          ( SOC, SOC, Op_RegF, 8, F8->as_VMReg());
   130 reg_def F8_H        ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()->next());
   131 reg_def F9          ( SOC, SOC, Op_RegF, 9, F9->as_VMReg());
   132 reg_def F9_H        ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()->next());
   133 reg_def F10         ( SOC, SOC, Op_RegF, 10, F10->as_VMReg());
   134 reg_def F10_H       ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()->next());
   135 reg_def F11         ( SOC, SOC, Op_RegF, 11, F11->as_VMReg());
   136 reg_def F11_H       ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()->next());
   137 reg_def F12         ( SOC, SOC, Op_RegF, 12, F12->as_VMReg());
   138 reg_def F12_H       ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()->next());
   139 reg_def F13         ( SOC, SOC, Op_RegF, 13, F13->as_VMReg());
   140 reg_def F13_H       ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()->next());
   141 reg_def F14         ( SOC, SOC, Op_RegF, 14, F14->as_VMReg());
   142 reg_def F14_H       ( SOC, SOC, Op_RegF, 14, F14->as_VMReg()->next());
   143 reg_def F15         ( SOC, SOC, Op_RegF, 15, F15->as_VMReg());
   144 reg_def F15_H       ( SOC, SOC, Op_RegF, 15, F15->as_VMReg()->next());
   145 reg_def F16         ( SOC, SOC, Op_RegF, 16, F16->as_VMReg());
   146 reg_def F16_H       ( SOC, SOC, Op_RegF, 16, F16->as_VMReg()->next());
   147 reg_def F17         ( SOC, SOC, Op_RegF, 17, F17->as_VMReg());
   148 reg_def F17_H       ( SOC, SOC, Op_RegF, 17, F17->as_VMReg()->next());
   149 reg_def F18         ( SOC, SOC, Op_RegF, 18, F18->as_VMReg());
   150 reg_def F18_H       ( SOC, SOC, Op_RegF, 18, F18->as_VMReg()->next());
   151 reg_def F19         ( SOC, SOC, Op_RegF, 19, F19->as_VMReg());
   152 reg_def F19_H       ( SOC, SOC, Op_RegF, 19, F19->as_VMReg()->next());
   153 reg_def F20         ( SOC, SOC, Op_RegF, 20, F20->as_VMReg());
   154 reg_def F20_H       ( SOC, SOC, Op_RegF, 20, F20->as_VMReg()->next());
   155 reg_def F21         ( SOC, SOC, Op_RegF, 21, F21->as_VMReg());
   156 reg_def F21_H       ( SOC, SOC, Op_RegF, 21, F21->as_VMReg()->next());
   157 reg_def F22         ( SOC, SOC, Op_RegF, 22, F22->as_VMReg());
   158 reg_def F22_H       ( SOC, SOC, Op_RegF, 22, F22->as_VMReg()->next());
   159 reg_def F23         ( SOC, SOC, Op_RegF, 23, F23->as_VMReg());
   160 reg_def F23_H       ( SOC, SOC, Op_RegF, 23, F23->as_VMReg()->next());
   161 reg_def F24         ( SOC, SOC, Op_RegF, 24, F24->as_VMReg());
   162 reg_def F24_H       ( SOC, SOC, Op_RegF, 24, F24->as_VMReg()->next());
   163 reg_def F25         ( SOC, SOC, Op_RegF, 25, F25->as_VMReg());
   164 reg_def F25_H       ( SOC, SOC, Op_RegF, 25, F25->as_VMReg()->next());
   165 reg_def F26         ( SOC, SOC, Op_RegF, 26, F26->as_VMReg());
   166 reg_def F26_H       ( SOC, SOC, Op_RegF, 26, F26->as_VMReg()->next());
   167 reg_def F27         ( SOC, SOC, Op_RegF, 27, F27->as_VMReg());
   168 reg_def F27_H       ( SOC, SOC, Op_RegF, 27, F27->as_VMReg()->next());
   169 reg_def F28         ( SOC, SOC, Op_RegF, 28, F28->as_VMReg());
   170 reg_def F28_H       ( SOC, SOC, Op_RegF, 28, F28->as_VMReg()->next());
   171 reg_def F29         ( SOC, SOC, Op_RegF, 29, F29->as_VMReg());
   172 reg_def F29_H       ( SOC, SOC, Op_RegF, 29, F29->as_VMReg()->next());
   173 reg_def F30         ( SOC, SOC, Op_RegF, 30, F30->as_VMReg());
   174 reg_def F30_H       ( SOC, SOC, Op_RegF, 30, F30->as_VMReg()->next());
   175 reg_def F31         ( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
   176 reg_def F31_H       ( SOC, SOC, Op_RegF, 31, F31->as_VMReg()->next());
   179 // ----------------------------
   180 // Special Registers
   181 // Condition Codes Flag Registers
   182 reg_def MIPS_FLAG (SOC, SOC,  Op_RegFlags, 1, as_Register(1)->as_VMReg());
   183 //S6 is used for get_thread(S6)
   184 //S5 is uesd for heapbase of compressed oop
   185 alloc_class chunk0(  
   186                      S7, S7_H,
   187                      S0, S0_H,
   188                      S1, S1_H,
   189                      S2, S2_H,
   190                      S4, S4_H,
   191                      S5, S5_H,
   192                      S6, S6_H,
   193                      S3, S3_H,
   194                      T2, T2_H,
   195                      T3, T3_H,
   196                      T8, T8_H,
   197                      T9, T9_H,
   198                      T1, T1_H, // inline_cache_reg
   199                      V1, V1_H,
   200                      A7, A7_H,
   201                      A6, A6_H,
   202                      A5, A5_H,
   203                      A4, A4_H,
   204                      V0, V0_H,
   205                      A3, A3_H,
   206                      A2, A2_H,
   207                      A1, A1_H,
   208                      A0, A0_H,
   209                      T0, T0_H,
   210                      GP, GP_H 
   211                      RA, RA_H,
   212                      SP, SP_H, // stack_pointer
   213                      FP, FP_H  // frame_pointer
   214                  );
   216 alloc_class chunk1(  F0, F0_H,
   217                      F1, F1_H,
   218                      F2, F2_H,
   219                      F3, F3_H,
   220                      F4, F4_H,
   221                      F5, F5_H,
   222                      F6, F6_H,
   223                      F7, F7_H,
   224                      F8, F8_H,
   225                      F9, F9_H,
   226                      F10, F10_H,
   227                      F11, F11_H,
   228                      F20, F20_H,
   229                      F21, F21_H,
   230                      F22, F22_H,
   231                      F23, F23_H,
   232                      F24, F24_H,
   233                      F25, F25_H,
   234                      F26, F26_H,
   235                      F27, F27_H,
   236                      F28, F28_H,
   237                      F19, F19_H,
   238                      F18, F18_H,
   239                      F17, F17_H,
   240                      F16, F16_H,
   241                      F15, F15_H,
   242                      F14, F14_H,
   243                      F13, F13_H,
   244                      F12, F12_H,
   245                      F29, F29_H,
   246                      F30, F30_H,
   247                      F31, F31_H);
   249 alloc_class chunk2(MIPS_FLAG);
   251 reg_class s_reg( S0, S1, S2, S3, S4, S5, S6, S7 );
   252 reg_class s0_reg( S0 );
   253 reg_class s1_reg( S1 );
   254 reg_class s2_reg( S2 );
   255 reg_class s3_reg( S3 );
   256 reg_class s4_reg( S4 );
   257 reg_class s5_reg( S5 );
   258 reg_class s6_reg( S6 );
   259 reg_class s7_reg( S7 );
   261 reg_class t_reg( T0, T1, T2, T3, T8, T9 );
   262 reg_class t0_reg( T0 );
   263 reg_class t1_reg( T1 );
   264 reg_class t2_reg( T2 );
   265 reg_class t3_reg( T3 );
   266 reg_class t8_reg( T8 );
   267 reg_class t9_reg( T9 );
   269 reg_class a_reg( A0, A1, A2, A3, A4, A5, A6, A7 );
   270 reg_class a0_reg( A0 );
   271 reg_class a1_reg( A1 );
   272 reg_class a2_reg( A2 );
   273 reg_class a3_reg( A3 );
   274 reg_class a4_reg( A4 );
   275 reg_class a5_reg( A5 );
   276 reg_class a6_reg( A6 );
   277 reg_class a7_reg( A7 );
   279 reg_class v0_reg( V0 );
   280 reg_class v1_reg( V1 );
   282 reg_class sp_reg( SP, SP_H );
   283 reg_class fp_reg( FP, FP_H );
   285 reg_class mips_flags(MIPS_FLAG);
   287 reg_class v0_long_reg( V0, V0_H );
   288 reg_class v1_long_reg( V1, V1_H );
   289 reg_class a0_long_reg( A0, A0_H );
   290 reg_class a1_long_reg( A1, A1_H );
   291 reg_class a2_long_reg( A2, A2_H );
   292 reg_class a3_long_reg( A3, A3_H );
   293 reg_class a4_long_reg( A4, A4_H );
   294 reg_class a5_long_reg( A5, A5_H );
   295 reg_class a6_long_reg( A6, A6_H );
   296 reg_class a7_long_reg( A7, A7_H );
   297 reg_class t0_long_reg( T0, T0_H );
   298 reg_class t1_long_reg( T1, T1_H );
   299 reg_class t2_long_reg( T2, T2_H );
   300 reg_class t3_long_reg( T3, T3_H );
   301 reg_class t8_long_reg( T8, T8_H );
   302 reg_class t9_long_reg( T9, T9_H );
   303 reg_class s0_long_reg( S0, S0_H );
   304 reg_class s1_long_reg( S1, S1_H );
   305 reg_class s2_long_reg( S2, S2_H );
   306 reg_class s3_long_reg( S3, S3_H );
   307 reg_class s4_long_reg( S4, S4_H );
   308 reg_class s5_long_reg( S5, S5_H );
   309 reg_class s6_long_reg( S6, S6_H );
   310 reg_class s7_long_reg( S7, S7_H );
   312 reg_class int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, A7, A6, A5, A4, V0, A3, A2, A1, A0, T0 );
   314 reg_class no_Ax_int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, V0, T0 );
   316 reg_class p_reg( 
   317                  S7, S7_H,
   318                  S0, S0_H,
   319                  S1, S1_H,
   320                  S2, S2_H,
   321                  S4, S4_H,
   322                  S3, S3_H,
   323                  T8, T8_H,
   324                  T2, T2_H,
   325                  T3, T3_H,
   326                  T1, T1_H,
   327                  A7, A7_H,
   328                  A6, A6_H,
   329                  A5, A5_H,
   330                  A4, A4_H,
   331                  A3, A3_H,
   332                  A2, A2_H,
   333                  A1, A1_H,
   334                  A0, A0_H,
   335                  T0, T0_H
   336                );
   338 reg_class no_T8_p_reg( 
   339                  S7, S7_H,
   340                  S0, S0_H,
   341                  S1, S1_H,
   342                  S2, S2_H,
   343                  S4, S4_H,
   344                  S3, S3_H,
   345                  T2, T2_H,
   346                  T3, T3_H,
   347                  T1, T1_H,
   348                  A7, A7_H,
   349                  A6, A6_H,
   350                  A5, A5_H,
   351                  A4, A4_H,
   352                  A3, A3_H,
   353                  A2, A2_H,
   354                  A1, A1_H,
   355                  A0, A0_H,
   356                  T0, T0_H
   357                );
   359 reg_class long_reg( 
   360                     S7, S7_H,
   361                     S0, S0_H,
   362                     S1, S1_H,
   363                     S2, S2_H,
   364                     S4, S4_H,
   365                     S3, S3_H,
   366                     T8, T8_H,
   367                     T2, T2_H,
   368                     T3, T3_H,
   369                     T1, T1_H,
   370                     A7, A7_H,
   371                     A6, A6_H,
   372                     A5, A5_H,
   373                     A4, A4_H,
   374                     A3, A3_H,
   375                     A2, A2_H,
   376                     A1, A1_H,
   377                     A0, A0_H,
   378                     T0, T0_H
   379                   );
   382 // Floating point registers.
   383 // 2012/8/23 Fu: F30/F31 are used as temporary registers in D2I
   384 // 2016/12/1 aoqi: F31 are not used as temporary registers in D2I
   385 reg_class flt_reg( F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17 F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F31);
   386 reg_class dbl_reg( F0, F0_H,
   387                    F1, F1_H,
   388                    F2, F2_H,
   389                    F3, F3_H,
   390                    F4, F4_H,
   391                    F5, F5_H,
   392                    F6, F6_H,
   393                    F7, F7_H,
   394                    F8, F8_H,
   395                    F9, F9_H,
   396                    F10, F10_H, 
   397                    F11, F11_H, 
   398                    F12, F12_H, 
   399                    F13, F13_H, 
   400                    F14, F14_H, 
   401                    F15, F15_H, 
   402                    F16, F16_H, 
   403                    F17, F17_H, 
   404                    F18, F18_H, 
   405                    F19, F19_H, 
   406                    F20, F20_H, 
   407                    F21, F21_H, 
   408                    F22, F22_H, 
   409                    F23, F23_H, 
   410                    F24, F24_H, 
   411                    F25, F25_H, 
   412                    F26, F26_H, 
   413                    F27, F27_H, 
   414                    F28, F28_H, 
   415                    F29, F29_H, 
   416                    F31, F31_H);
   418 reg_class flt_arg0( F12 );
   419 reg_class dbl_arg0( F12, F12_H );
   420 reg_class dbl_arg1( F14, F14_H );
   422 %} 
   424 //----------DEFINITION BLOCK---------------------------------------------------
   425 // Define name --> value mappings to inform the ADLC of an integer valued name
   426 // Current support includes integer values in the range [0, 0x7FFFFFFF]
   427 // Format:
   428 //        int_def  <name>         ( <int_value>, <expression>);
   429 // Generated Code in ad_<arch>.hpp
   430 //        #define  <name>   (<expression>)
   431 //        // value == <int_value>
   432 // Generated code in ad_<arch>.cpp adlc_verification()
   433 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
   434 //
   435 definitions %{
   436 	int_def DEFAULT_COST      (    100,     100);
   437 	int_def HUGE_COST         (1000000, 1000000);
   439 	// Memory refs are twice as expensive as run-of-the-mill.
   440 	int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
   442 	// Branches are even more expensive.
   443 	int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
   444 	// we use jr instruction to construct call, so more expensive
   445 	// by yjl 2/28/2006
   446 	int_def CALL_COST         (    500, DEFAULT_COST * 5);
   447 /*
   448         int_def EQUAL             (   1, 1  );
   449         int_def NOT_EQUAL         (   2, 2  );
   450         int_def GREATER           (   3, 3  );
   451         int_def GREATER_EQUAL     (   4, 4  );
   452         int_def LESS              (   5, 5  );
   453         int_def LESS_EQUAL        (   6, 6  );
   454 */
   455 %}
   459 //----------SOURCE BLOCK-------------------------------------------------------
   460 // This is a block of C++ code which provides values, functions, and
   461 // definitions necessary in the rest of the architecture description
   463 source_hpp %{
   464 // Header information of the source block.
   465 // Method declarations/definitions which are used outside
   466 // the ad-scope can conveniently be defined here.
   467 //
   468 // To keep related declarations/definitions/uses close together,
   469 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
   471 class CallStubImpl {
   473   //--------------------------------------------------------------
   474   //---<  Used for optimization in Compile::shorten_branches  >---
   475   //--------------------------------------------------------------
   477  public:
   478   // Size of call trampoline stub.
   479   static uint size_call_trampoline() {
   480     return 0; // no call trampolines on this platform
   481   }
   483   // number of relocations needed by a call trampoline stub
   484   static uint reloc_call_trampoline() { 
   485     return 0; // no call trampolines on this platform
   486   }
   487 };
   489 class HandlerImpl {
   491  public:
   493   static int emit_exception_handler(CodeBuffer &cbuf);
   494   static int emit_deopt_handler(CodeBuffer& cbuf);
   496   static uint size_exception_handler() {
   497     // NativeCall instruction size is the same as NativeJump.
   498     // exception handler starts out as jump and can be patched to
   499     // a call be deoptimization.  (4932387)
   500     // Note that this value is also credited (in output.cpp) to
   501     // the size of the code section.
   502 //    return NativeJump::instruction_size;
   503     int size = NativeCall::instruction_size;
   504     return round_to(size, 16);
   505   }
   507 #ifdef _LP64
   508   static uint size_deopt_handler() {
   509     int size = NativeCall::instruction_size;
   510     return round_to(size, 16);
   511   }
   512 #else
   513   static uint size_deopt_handler() {
   514     // NativeCall instruction size is the same as NativeJump.
   515     // exception handler starts out as jump and can be patched to
   516     // a call be deoptimization.  (4932387)
   517     // Note that this value is also credited (in output.cpp) to
   518     // the size of the code section.
   519     return 5 + NativeJump::instruction_size; // pushl(); jmp;
   520   }
   521 #endif
   522 };
   524 %} // end source_hpp
   526 source %{
   528 #define   NO_INDEX    0
   529 #define   RELOC_IMM64    Assembler::imm_operand
   530 #define   RELOC_DISP32   Assembler::disp32_operand
   533 #define __ _masm.
   536 // Emit exception handler code.
   537 // Stuff framesize into a register and call a VM stub routine.
   538 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
   539   // Note that the code buffer's insts_mark is always relative to insts.
   540   // That's why we must use the macroassembler to generate a handler.
   541   MacroAssembler _masm(&cbuf);
   542   address base =
   543   __ start_a_stub(size_exception_handler());
   544   if (base == NULL)  return 0;  // CodeBuffer::expand failed
   545   int offset = __ offset();
   547   __ block_comment("; emit_exception_handler");
   549   cbuf.set_insts_mark();
   550   __ relocate(relocInfo::runtime_call_type);
   551   __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
   552   __ align(16);
   553   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
   554   __ end_a_stub();
   555   return offset;
   556 }
   558 // Emit deopt handler code.
   559 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
   560   // Note that the code buffer's insts_mark is always relative to insts.
   561   // That's why we must use the macroassembler to generate a handler.
   562   MacroAssembler _masm(&cbuf);
   563   address base =
   564   __ start_a_stub(size_deopt_handler());
   566   // FIXME
   567   if (base == NULL)  return 0;  // CodeBuffer::expand failed
   568   int offset = __ offset();
   570   __ block_comment("; emit_deopt_handler");
   572   cbuf.set_insts_mark();
   573   __ relocate(relocInfo::runtime_call_type);
   574   __ patchable_call(SharedRuntime::deopt_blob()->unpack());
   575   __ align(16);
   576   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
   577   __ end_a_stub();
   578   return offset;
   579 }
   582 const bool Matcher::match_rule_supported(int opcode) {
   583   if (!has_match_rule(opcode))
   584     return false;
   586   switch (opcode) {
   587     //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
   588     case Op_CountLeadingZerosI:
   589     case Op_CountLeadingZerosL:
   590       if (!UseCountLeadingZerosInstruction)
   591         return false;
   592       break;
   593     case Op_CountTrailingZerosI:
   594     case Op_CountTrailingZerosL:
   595       if (!UseCountTrailingZerosInstruction)
   596         return false;
   597       break;
   598   }
   600   return true;  // Per default match rules are supported.
   601 }
   603 //FIXME
   604 // emit call stub, compiled java to interpreter
   605 void emit_java_to_interp(CodeBuffer &cbuf ) {
   606   // Stub is fixed up when the corresponding call is converted from calling
   607   // compiled code to calling interpreted code.
   608   // mov rbx,0
   609   // jmp -1
   611   address mark = cbuf.insts_mark();  // get mark within main instrs section
   613   // Note that the code buffer's insts_mark is always relative to insts.
   614   // That's why we must use the macroassembler to generate a stub.
   615   MacroAssembler _masm(&cbuf);
   617   address base =
   618   __ start_a_stub(Compile::MAX_stubs_size);
   619   if (base == NULL)  return;  // CodeBuffer::expand failed
   620   // static stub relocation stores the instruction address of the call
   622   __ relocate(static_stub_Relocation::spec(mark), 0);
   624   // static stub relocation also tags the methodOop in the code-stream.
   625   __ patchable_set48(S3, (long)0);
   626   // This is recognized as unresolved by relocs/nativeInst/ic code
   628   __ relocate(relocInfo::runtime_call_type);
   630   cbuf.set_insts_mark();
   631   address call_pc = (address)-1;
   632   __ patchable_jump(call_pc);
   633   __ align(16);
   634   __ end_a_stub();
   635   // Update current stubs pointer and restore code_end.
   636 }
   638 // size of call stub, compiled java to interpretor
   639 uint size_java_to_interp() {
   640   int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
   641   return round_to(size, 16);
   642 }
   644 // relocation entries for call stub, compiled java to interpreter
   645 uint reloc_java_to_interp() {
   646   return 16;  //  in emit_java_to_interp +  in Java_Static_Call
   647 }
   649 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
   650   if( Assembler::is_simm16(offset) ) return true;
   651   else {
   652      assert(false, "Not implemented yet !" );
   653      Unimplemented();
   654   }
   655 }
   658 // No additional cost for CMOVL.
   659 const int Matcher::long_cmove_cost() { return 0; }
   661 // No CMOVF/CMOVD with SSE2
   662 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
   664 // Does the CPU require late expand (see block.cpp for description of late expand)?
   665 const bool Matcher::require_postalloc_expand = false;
   667 // Should the Matcher clone shifts on addressing modes, expecting them
   668 // to be subsumed into complex addressing expressions or compute them
   669 // into registers?  True for Intel but false for most RISCs
   670 const bool Matcher::clone_shift_expressions = false;
   672 // Do we need to mask the count passed to shift instructions or does
   673 // the cpu only look at the lower 5/6 bits anyway?
   674 const bool Matcher::need_masked_shift_count = false;
   676 bool Matcher::narrow_oop_use_complex_address() {
   677   NOT_LP64(ShouldNotCallThis());
   678   assert(UseCompressedOops, "only for compressed oops code");
   679   return false;
   680 }
   682 bool Matcher::narrow_klass_use_complex_address() {
   683   NOT_LP64(ShouldNotCallThis());
   684   assert(UseCompressedClassPointers, "only for compressed klass code");
   685   return false;
   686 }
   688 // This is UltraSparc specific, true just means we have fast l2f conversion
   689 const bool Matcher::convL2FSupported(void) {
   690   return true;
   691 }
   693 // Max vector size in bytes. 0 if not supported.
   694 const int Matcher::vector_width_in_bytes(BasicType bt) {
   695   assert(MaxVectorSize == 8, "");
   696   return 8;
   697 }
   699 // Vector ideal reg
   700 const int Matcher::vector_ideal_reg(int size) {
   701   assert(MaxVectorSize == 8, "");
   702   switch(size) {
   703     case  8: return Op_VecD;
   704   }
   705   ShouldNotReachHere();
   706   return 0;
   707 }
   709 // Only lowest bits of xmm reg are used for vector shift count.
   710 const int Matcher::vector_shift_count_ideal_reg(int size) {
   711   fatal("vector shift is not supported");
   712   return Node::NotAMachineReg;
   713 }
   715 // Limits on vector size (number of elements) loaded into vector.
   716 const int Matcher::max_vector_size(const BasicType bt) {
   717   assert(is_java_primitive(bt), "only primitive type vectors");
   718   return vector_width_in_bytes(bt)/type2aelembytes(bt);
   719 }
   721 const int Matcher::min_vector_size(const BasicType bt) {
   722   return max_vector_size(bt); // Same as max.
   723 }
   725 // MIPS supports misaligned vectors store/load? FIXME
   726 const bool Matcher::misaligned_vectors_ok() {
   727   return false;
   728   //return !AlignVector; // can be changed by flag
   729 }
   731 // Register for DIVI projection of divmodI
   732 RegMask Matcher::divI_proj_mask() {
   733   ShouldNotReachHere();
   734   return RegMask();
   735 }
   737 // Register for MODI projection of divmodI
   738 RegMask Matcher::modI_proj_mask() {
   739   ShouldNotReachHere();
   740   return RegMask();
   741 }
   743 // Register for DIVL projection of divmodL
   744 RegMask Matcher::divL_proj_mask() {
   745   ShouldNotReachHere();
   746   return RegMask();
   747 }
   749 int Matcher::regnum_to_fpu_offset(int regnum) {
   750   return regnum - 32; // The FP registers are in the second chunk
   751 }
   754 const bool Matcher::isSimpleConstant64(jlong value) {
   755   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
   756   return true;
   757 }
   760 // Return whether or not this register is ever used as an argument.  This
   761 // function is used on startup to build the trampoline stubs in generateOptoStub.
   762 // Registers not mentioned will be killed by the VM call in the trampoline, and
   763 // arguments in those registers not be available to the callee.
   764 bool Matcher::can_be_java_arg( int reg ) {
   765   /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
   766   if (    reg == T0_num || reg == T0_H_num
   767 	   || reg == A0_num || reg == A0_H_num 
   768        || reg == A1_num || reg == A1_H_num 
   769        || reg == A2_num || reg == A2_H_num 
   770        || reg == A3_num || reg == A3_H_num 
   771        || reg == A4_num || reg == A4_H_num 
   772        || reg == A5_num || reg == A5_H_num 
   773        || reg == A6_num || reg == A6_H_num 
   774        || reg == A7_num || reg == A7_H_num )
   775     return true;
   777   if (    reg == F12_num || reg == F12_H_num
   778        || reg == F13_num || reg == F13_H_num 
   779        || reg == F14_num || reg == F14_H_num 
   780        || reg == F15_num || reg == F15_H_num 
   781        || reg == F16_num || reg == F16_H_num 
   782        || reg == F17_num || reg == F17_H_num 
   783        || reg == F18_num || reg == F18_H_num 
   784        || reg == F19_num || reg == F19_H_num )
   785     return true;
   787   return false;
   788 }
   790 bool Matcher::is_spillable_arg( int reg ) {
   791   return can_be_java_arg(reg);
   792 }
   794 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
   795   return false;
   796 }
   798 // Register for MODL projection of divmodL
   799 RegMask Matcher::modL_proj_mask() {
   800   ShouldNotReachHere();
   801   return RegMask();
   802 }
   804 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
   805   return FP_REG_mask();
   806 }
   808 // MIPS doesn't support AES intrinsics
   809 const bool Matcher::pass_original_key_for_aes() {
   810   return false;
   811 }
   813 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
   814   //lui
   815   //ori
   816   //dsll
   817   //ori
   819   //jalr
   820   //nop
   822   return round_to(current_offset, alignment_required()) - current_offset;
   823 }
   825 int CallLeafDirectNode::compute_padding(int current_offset) const {
   826   //lui
   827   //ori
   828   //dsll
   829   //ori
   831   //jalr
   832   //nop
   834   return round_to(current_offset, alignment_required()) - current_offset;
   835 }
   837 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
   838   //lui
   839   //ori
   840   //dsll
   841   //ori
   843   //jalr
   844   //nop
   846   return round_to(current_offset, alignment_required()) - current_offset;
   847 }
   849 // If CPU can load and store mis-aligned doubles directly then no fixup is
   850 // needed.  Else we split the double into 2 integer pieces and move it
   851 // piece-by-piece.  Only happens when passing doubles into C code as the
   852 // Java calling convention forces doubles to be aligned.
   853 const bool Matcher::misaligned_doubles_ok = false;
   854 // Do floats take an entire double register or just half?
   855 //const bool Matcher::float_in_double = true;
   856 bool Matcher::float_in_double() { return false; }
   857 // Threshold size for cleararray.
   858 const int Matcher::init_array_short_size = 8 * BytesPerLong;
   859 // Do ints take an entire long register or just half?
   860 const bool Matcher::int_in_long = true;
   861 // Is it better to copy float constants, or load them directly from memory?
   862 // Intel can load a float constant from a direct address, requiring no
   863 // extra registers.  Most RISCs will have to materialize an address into a
   864 // register first, so they would do better to copy the constant from stack.
   865 const bool Matcher::rematerialize_float_constants = false;
   866 // Advertise here if the CPU requires explicit rounding operations
   867 // to implement the UseStrictFP mode.
   868 const bool Matcher::strict_fp_requires_explicit_rounding = false;
   869 // The ecx parameter to rep stos for the ClearArray node is in dwords.
   870 const bool Matcher::init_array_count_is_in_bytes = false;
   873 // Indicate if the safepoint node needs the polling page as an input.
   874 // Since MIPS doesn't have absolute addressing, it needs.
   875 bool SafePointNode::needs_polling_address_input() {
   876   return false;
   877 }
   879 // !!!!! Special hack to get all type of calls to specify the byte offset
   880 //       from the start of the call to the point where the return address
   881 //       will point.
   882 int MachCallStaticJavaNode::ret_addr_offset() {
   883   //lui
   884   //ori
   885   //nop
   886   //nop
   887   //jalr
   888   //nop
   889   return 24; 
   890 }
   892 int MachCallDynamicJavaNode::ret_addr_offset() {
   893   //lui IC_Klass,
   894   //ori IC_Klass,
   895   //dsll IC_Klass
   896   //ori IC_Klass
   898   //lui T9
   899   //ori T9
   900   //nop
   901   //nop
   902   //jalr T9
   903   //nop
   904   return 4 * 4 + 4 * 6; 
   905 }
   907 //=============================================================================
   909 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
   910 enum RC { rc_bad, rc_int, rc_float, rc_stack };
   911 static enum RC rc_class( OptoReg::Name reg ) {
   912   if( !OptoReg::is_valid(reg)  ) return rc_bad;
   913   if (OptoReg::is_stack(reg)) return rc_stack;
   914   VMReg r = OptoReg::as_VMReg(reg);
   915   if (r->is_Register()) return rc_int;
   916   assert(r->is_FloatRegister(), "must be");
   917   return rc_float;
   918 }
   920 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
   921   // Get registers to move
   922   OptoReg::Name src_second = ra_->get_reg_second(in(1));
   923   OptoReg::Name src_first = ra_->get_reg_first(in(1));
   924   OptoReg::Name dst_second = ra_->get_reg_second(this );
   925   OptoReg::Name dst_first = ra_->get_reg_first(this );
   927   enum RC src_second_rc = rc_class(src_second);
   928   enum RC src_first_rc = rc_class(src_first);
   929   enum RC dst_second_rc = rc_class(dst_second);
   930   enum RC dst_first_rc = rc_class(dst_first);
   932   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
   934   // Generate spill code!
   935   int size = 0;
   937   if( src_first == dst_first && src_second == dst_second )
   938     return 0;            // Self copy, no move
   940   if (src_first_rc == rc_stack) {
   941     // mem ->
   942     if (dst_first_rc == rc_stack) {
   943       // mem -> mem
   944       assert(src_second != dst_first, "overlap");
   945       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   946           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   947         // 64-bit
   948         int src_offset = ra_->reg2offset(src_first);
   949         int dst_offset = ra_->reg2offset(dst_first);
   950         if (cbuf) {
   951           MacroAssembler _masm(cbuf);
   952           __ ld(AT, Address(SP, src_offset));
   953           __ sd(AT, Address(SP, dst_offset));
   954 #ifndef PRODUCT
   955         } else {
   956 			if(!do_size){
   957 				if (size != 0) st->print("\n\t");
   958 				st->print("ld    AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
   959 						  "sd    AT, [SP + #%d]",
   960 						  src_offset, dst_offset);
   961 			}
   962 #endif
   963         }
   964 		size += 8;
   965       } else {
   966         // 32-bit
   967         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
   968         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
   969         // No pushl/popl, so:
   970         int src_offset = ra_->reg2offset(src_first);
   971         int dst_offset = ra_->reg2offset(dst_first);
   972         if (cbuf) {
   973           MacroAssembler _masm(cbuf);
   974           __ lw(AT, Address(SP, src_offset));
   975           __ sw(AT, Address(SP, dst_offset));
   976 #ifndef PRODUCT
   977         } else {
   978 			if(!do_size){
   979 				if (size != 0) st->print("\n\t");
   980 				st->print("lw    AT, [SP + #%d] spill 2\n\t"
   981 						  "sw    AT, [SP + #%d]\n\t",
   982 						  src_offset, dst_offset);
   983 			}
   984 #endif
   985         }
   986 		size += 8;
   987       }
   988       return size;
   989     } else if (dst_first_rc == rc_int) {
   990       // mem -> gpr
   991       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   992           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   993         // 64-bit
   994         int offset = ra_->reg2offset(src_first);
   995         if (cbuf) {
   996           MacroAssembler _masm(cbuf);
   997           __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
   998 #ifndef PRODUCT
   999         } else {
  1000 			if(!do_size){
  1001 				if (size != 0) st->print("\n\t");
  1002 				st->print("ld    %s, [SP + #%d]\t# spill 3",
  1003 						  Matcher::regName[dst_first],
  1004 						  offset);
  1006 #endif
  1008 		size += 4;
  1009       } else {
  1010         // 32-bit
  1011         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1012         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1013         int offset = ra_->reg2offset(src_first);
  1014         if (cbuf) {
  1015           MacroAssembler _masm(cbuf);
  1016           if (this->ideal_reg() == Op_RegI)
  1017             __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1018           else
  1019             __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1020 #ifndef PRODUCT
  1021         } else {
  1022 			if(!do_size){
  1023 				if (size != 0) st->print("\n\t");
  1024           if (this->ideal_reg() == Op_RegI)
  1025 				st->print("lw    %s, [SP + #%d]\t# spill 4",
  1026 						   Matcher::regName[dst_first],
  1027 						   offset);
  1028 		  else
  1029 				st->print("lwu    %s, [SP + #%d]\t# spill 5",
  1030 						   Matcher::regName[dst_first],
  1031 						   offset);
  1033 #endif
  1035 		size += 4;
  1037       return size;
  1038     } else if (dst_first_rc == rc_float) {
  1039       // mem-> xmm
  1040       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1041           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1042         // 64-bit
  1043         int offset = ra_->reg2offset(src_first);
  1044         if (cbuf) {
  1045           MacroAssembler _masm(cbuf);
  1046           __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1047 #ifndef PRODUCT
  1048         } else {
  1049 			if(!do_size){
  1050 				if (size != 0) st->print("\n\t");
  1051 				st->print("ldc1  %s, [SP + #%d]\t# spill 6",
  1052 						  Matcher::regName[dst_first],
  1053 						  offset);
  1055 #endif
  1057 		size += 4;
  1058       } else {
  1059         // 32-bit
  1060         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1061         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1062         int offset = ra_->reg2offset(src_first);
  1063         if (cbuf) {
  1064           MacroAssembler _masm(cbuf);
  1065           __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1066 #ifndef PRODUCT
  1067         } else {
  1068 			if(!do_size){
  1069 				if (size != 0) st->print("\n\t");
  1070 				st->print("lwc1   %s, [SP + #%d]\t# spill 7",
  1071 						  Matcher::regName[dst_first],
  1072 						  offset);
  1074 #endif
  1076 		size += 4;
  1078       return size;
  1080   } else if (src_first_rc == rc_int) {
  1081     // gpr ->
  1082     if (dst_first_rc == rc_stack) {
  1083       // gpr -> mem
  1084       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1085           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1086         // 64-bit
  1087         int offset = ra_->reg2offset(dst_first);
  1088         if (cbuf) {
  1089           MacroAssembler _masm(cbuf);
  1090           __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1091 #ifndef PRODUCT
  1092         } else {
  1093 			if(!do_size){
  1094 				if (size != 0) st->print("\n\t");
  1095 				st->print("sd    %s, [SP + #%d] # spill 8",
  1096 						  Matcher::regName[src_first],
  1097 						  offset);
  1099 #endif
  1101 		size += 4;
  1102       } else {
  1103         // 32-bit
  1104         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1105         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1106         int offset = ra_->reg2offset(dst_first);
  1107         if (cbuf) {
  1108           MacroAssembler _masm(cbuf);
  1109           __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1110 #ifndef PRODUCT
  1111         } else {
  1112 			if(!do_size){
  1113 				if (size != 0) st->print("\n\t");
  1114 				st->print("sw    %s, [SP + #%d]\t# spill 9",
  1115 						Matcher::regName[src_first], offset);
  1117 #endif
  1119 		size += 4;
  1121       return size;
  1122     } else if (dst_first_rc == rc_int) {
  1123       // gpr -> gpr
  1124       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1125           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1126         // 64-bit
  1127         if (cbuf) {
  1128           MacroAssembler _masm(cbuf);
  1129           __ move(as_Register(Matcher::_regEncode[dst_first]),
  1130                   as_Register(Matcher::_regEncode[src_first]));
  1131 #ifndef PRODUCT
  1132         } else {
  1133 			if(!do_size){
  1134 				if (size != 0) st->print("\n\t");
  1135 				st->print("move(64bit)    %s <-- %s\t# spill 10",
  1136 						  Matcher::regName[dst_first],
  1137 						  Matcher::regName[src_first]);
  1139 #endif
  1141 		size += 4;
  1142         return size;
  1143       } else {
  1144         // 32-bit
  1145         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1146         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1147         if (cbuf) {
  1148           MacroAssembler _masm(cbuf);
  1149           if (this->ideal_reg() == Op_RegI)
  1150               __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
  1151           else
  1152               __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
  1154 #ifndef PRODUCT
  1155         } else {
  1156 			if(!do_size){
  1157 				if (size != 0) st->print("\n\t");
  1158 				st->print("move(32-bit)    %s <-- %s\t# spill 11",
  1159 						  Matcher::regName[dst_first],
  1160 						  Matcher::regName[src_first]);
  1162 #endif
  1164 		size += 4;	
  1165         return size;
  1167     } else if (dst_first_rc == rc_float) {
  1168       // gpr -> xmm
  1169       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1170           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1171         // 64-bit
  1172         if (cbuf) {
  1173           MacroAssembler _masm(cbuf);
  1174           __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
  1175 #ifndef PRODUCT
  1176         } else {
  1177 			if(!do_size){
  1178 				if (size != 0) st->print("\n\t");
  1179 				st->print("dmtc1   %s, %s\t# spill 12",
  1180 						  Matcher::regName[dst_first],
  1181 						  Matcher::regName[src_first]);
  1183 #endif
  1185 		size += 4;
  1186       } else {
  1187         // 32-bit
  1188         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1189         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1190         if (cbuf) {
  1191           MacroAssembler _masm(cbuf);
  1192           __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
  1193 #ifndef PRODUCT
  1194         } else {
  1195 			if(!do_size){
  1196 				if (size != 0) st->print("\n\t");
  1197 				st->print("mtc1   %s, %s\t# spill 13",
  1198 						  Matcher::regName[dst_first],
  1199 						  Matcher::regName[src_first]);
  1201 #endif
  1203 		size += 4;
  1205       return size;
  1207   } else if (src_first_rc == rc_float) {
  1208     // xmm ->
  1209     if (dst_first_rc == rc_stack) {
  1210       // xmm -> mem
  1211       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1212           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1213         // 64-bit
  1214         int offset = ra_->reg2offset(dst_first);
  1215         if (cbuf) {
  1216           MacroAssembler _masm(cbuf);
  1217           __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
  1218 #ifndef PRODUCT
  1219         } else {
  1220 			if(!do_size){
  1221 				if (size != 0) st->print("\n\t");
  1222 				st->print("sdc1   %s, [SP + #%d]\t# spill 14",
  1223 						  Matcher::regName[src_first],
  1224 						  offset);
  1226 #endif
  1228 		size += 4;
  1229       } else {
  1230         // 32-bit
  1231         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1232         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1233         int offset = ra_->reg2offset(dst_first);
  1234         if (cbuf) {
  1235           MacroAssembler _masm(cbuf);
  1236           __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
  1237 #ifndef PRODUCT
  1238         } else {
  1239 			if(!do_size){
  1240 				if (size != 0) st->print("\n\t");
  1241 				st->print("swc1   %s, [SP + #%d]\t# spill 15",
  1242 						Matcher::regName[src_first],
  1243 						offset);
  1245 #endif
  1247 		size += 4;
  1249       return size;
  1250     } else if (dst_first_rc == rc_int) {
  1251       // xmm -> gpr
  1252       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1253           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1254         // 64-bit
  1255         if (cbuf) {
  1256           MacroAssembler _masm(cbuf);
  1257           __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1258 #ifndef PRODUCT
  1259         } else {
  1260 			if(!do_size){
  1261 				if (size != 0) st->print("\n\t");
  1262 				st->print("dmfc1   %s, %s\t# spill 16",
  1263 						  Matcher::regName[dst_first],
  1264 						  Matcher::regName[src_first]);
  1266 #endif
  1268 		size += 4;
  1269       } else {
  1270         // 32-bit
  1271         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1272         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1273         if (cbuf) {
  1274           MacroAssembler _masm(cbuf);
  1275           __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1276 #ifndef PRODUCT
  1277         } else {
  1278 			if(!do_size){
  1279 				if (size != 0) st->print("\n\t");
  1280 				st->print("mfc1   %s, %s\t# spill 17",
  1281 						  Matcher::regName[dst_first],
  1282 						  Matcher::regName[src_first]);
  1284 #endif
  1286 		size += 4;
  1288       return size;
  1289     } else if (dst_first_rc == rc_float) {
  1290       // xmm -> xmm
  1291       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1292           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1293         // 64-bit
  1294         if (cbuf) {
  1295           MacroAssembler _masm(cbuf);
  1296           __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1297 #ifndef PRODUCT
  1298         } else {
  1299 			if(!do_size){
  1300 				if (size != 0) st->print("\n\t");
  1301 				st->print("mov_d  %s <-- %s\t# spill 18",
  1302 						  Matcher::regName[dst_first],
  1303 						  Matcher::regName[src_first]);
  1305 #endif
  1307 		size += 4;
  1308       } else {
  1309         // 32-bit
  1310         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1311         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1312         if (cbuf) {
  1313           MacroAssembler _masm(cbuf);
  1314           __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1315 #ifndef PRODUCT
  1316         } else {
  1317 			if(!do_size){
  1318 				if (size != 0) st->print("\n\t");
  1319 				st->print("mov_s  %s <-- %s\t# spill 19",
  1320 						  Matcher::regName[dst_first],
  1321 						  Matcher::regName[src_first]);
  1323 #endif
  1325 		size += 4;
  1327       return size;
  1331   assert(0," foo ");
  1332   Unimplemented();
  1333   return size;
  1337 #ifndef PRODUCT
  1338 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1339   implementation( NULL, ra_, false, st );
  1341 #endif
  1343 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1344   implementation( &cbuf, ra_, false, NULL );
  1347 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  1348   return implementation( NULL, ra_, true, NULL );
  1351 //=============================================================================
  1354 #ifndef PRODUCT
  1355 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1356   st->print("INT3");
  1358 #endif
  1360 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
  1361   MacroAssembler _masm(&cbuf);
  1362   __ int3();
  1365 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
  1366   return MachNode::size(ra_);
  1370 //=============================================================================
  1371 #ifndef PRODUCT
  1372 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1373   Compile *C = ra_->C;
  1374   int framesize = C->frame_size_in_bytes();
  1376   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1378   st->print("daddiu   SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
  1379   st->cr(); st->print("\t");
  1380   if (UseLoongsonISA) {
  1381      st->print("gslq  RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
  1382   } else {
  1383      st->print("ld    RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
  1384      st->cr(); st->print("\t");
  1385      st->print("ld    FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
  1388   if( do_polling() && C->is_method_compilation() ) {
  1389     st->print("Poll Safepoint # MachEpilogNode");
  1392 #endif
  1394 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1395   Compile *C = ra_->C;
  1396   MacroAssembler _masm(&cbuf);
  1397   int framesize = C->frame_size_in_bytes();
  1399   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1401   __ daddiu(SP, SP, framesize);
  1403   if (UseLoongsonISA) {
  1404     __ gslq(RA, FP, SP, -wordSize*2);
  1405   } else {
  1406     __ ld(RA, SP, -wordSize );
  1407     __ ld(FP, SP, -wordSize*2 );
  1410   if( do_polling() && C->is_method_compilation() ) {
  1411     __ set64(AT, (long)os::get_polling_page());
  1412     __ relocate(relocInfo::poll_return_type);
  1413     __ lw(AT, AT, 0);
  1417 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  1418   return MachNode::size(ra_); // too many variables; just compute it the hard way  fujie debug
  1421 int MachEpilogNode::reloc() const {
  1422   return 0; // a large enough number
  1425 const Pipeline * MachEpilogNode::pipeline() const {
  1426   return MachNode::pipeline_class();
  1429 int MachEpilogNode::safepoint_offset() const { return 0; }
  1431 //=============================================================================
  1433 #ifndef PRODUCT
  1434 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1435   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1436   int reg = ra_->get_reg_first(this);
  1437   st->print("ADDI %s, SP, %d   @BoxLockNode",Matcher::regName[reg],offset);
  1439 #endif
  1442 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  1443   return 4;
  1446 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1447   MacroAssembler _masm(&cbuf);
  1448   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1449   int reg = ra_->get_encode(this);
  1451   __ addi(as_Register(reg), SP, offset);
  1452 /*
  1453   if( offset >= 128 ) {
  1454     emit_opcode(cbuf, 0x8D);      // LEA  reg,[SP+offset]
  1455     emit_rm(cbuf, 0x2, reg, 0x04);
  1456     emit_rm(cbuf, 0x0, 0x04, SP_enc);
  1457     emit_d32(cbuf, offset);
  1459   else {
  1460     emit_opcode(cbuf, 0x8D);      // LEA  reg,[SP+offset]
  1461     emit_rm(cbuf, 0x1, reg, 0x04);
  1462     emit_rm(cbuf, 0x0, 0x04, SP_enc);
  1463     emit_d8(cbuf, offset);
  1465 */
  1469 //static int sizeof_FFree_Float_Stack_All = -1;
  1471 int MachCallRuntimeNode::ret_addr_offset() {
  1472   //lui
  1473   //ori
  1474   //dsll
  1475   //ori
  1476   //jalr
  1477   //nop
  1478   assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
  1479   return NativeCall::instruction_size;
  1480 //  return 16;
  1487 //=============================================================================
  1488 #ifndef PRODUCT
  1489 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1490   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  1492 #endif
  1494 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  1495   MacroAssembler _masm(&cbuf);
  1496   int i = 0;
  1497   for(i = 0; i < _count; i++)
  1498      __ nop();
  1501 uint MachNopNode::size(PhaseRegAlloc *) const {
  1502   return 4 * _count; 
  1504 const Pipeline* MachNopNode::pipeline() const {
  1505   return MachNode::pipeline_class();
  1508 //=============================================================================
  1510 //=============================================================================
  1511 #ifndef PRODUCT
  1512 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1513   st->print_cr("load_klass(T9, T0)");
  1514   st->print_cr("\tbeq(T9, iCache, L)");
  1515   st->print_cr("\tnop");
  1516   st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
  1517   st->print_cr("\tnop");
  1518   st->print_cr("\tnop");
  1519   st->print_cr("    L:");
  1521 #endif
  1524 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1525   MacroAssembler _masm(&cbuf);
  1526 #ifdef ASSERT
  1527   //uint code_size = cbuf.code_size();
  1528 #endif
  1529   int  ic_reg = Matcher::inline_cache_reg_encode();
  1530   Label L;
  1531   Register receiver = T0;
  1532   Register   iCache = as_Register(ic_reg);
  1533   __ load_klass(T9, receiver);
  1534   __ beq(T9, iCache, L);
  1535   __ nop();
  1537   __ relocate(relocInfo::runtime_call_type);
  1538   __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
  1540   /* WARNING these NOPs are critical so that verified entry point is properly
  1541    *      8 bytes aligned for patching by NativeJump::patch_verified_entry() */
  1542   __ align(CodeEntryAlignment);
  1543   __ bind(L);
  1546 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  1547   return MachNode::size(ra_); 
  1552 //=============================================================================
  1554 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
  1556 int Compile::ConstantTable::calculate_table_base_offset() const {
  1557   return 0;  // absolute addressing, no offset
  1560 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  1561 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  1562   ShouldNotReachHere();
  1565 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  1566   Compile* C = ra_->C;
  1567   Compile::ConstantTable& constant_table = C->constant_table();
  1568   MacroAssembler _masm(&cbuf);
  1570   Register Rtoc = as_Register(ra_->get_encode(this));
  1571   CodeSection* consts_section = __ code()->consts();
  1572   int consts_size = consts_section->align_at_start(consts_section->size());
  1573   assert(constant_table.size() == consts_size, "must be equal");
  1575   if (consts_section->size()) {
  1576     // Materialize the constant table base.
  1577     address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  1578     // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  1579     __ relocate(relocInfo::internal_pc_type);
  1580     __ patchable_set48(Rtoc, (long)baseaddr);
  1584 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
  1585   // patchable_set48 (4 insts)
  1586   return 4 * 4;
  1589 #ifndef PRODUCT
  1590 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  1591   Register r = as_Register(ra_->get_encode(this));
  1592   st->print("patchable_set48    %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
  1594 #endif
  1597 //=============================================================================
  1598 #ifndef PRODUCT
  1599 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1600   Compile* C = ra_->C;
  1602   int framesize = C->frame_size_in_bytes();
  1603   int bangsize = C->bang_size_in_bytes();
  1604   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1606   // Calls to C2R adapters often do not accept exceptional returns.
  1607   // We require that their callers must bang for them.  But be careful, because
  1608   // some VM calls (such as call site linkage) can use several kilobytes of
  1609   // stack.  But the stack safety zone should account for that.
  1610   // See bugs 4446381, 4468289, 4497237.
  1611   if (C->need_stack_bang(bangsize)) {
  1612     st->print_cr("# stack bang"); st->print("\t");
  1614     if (UseLoongsonISA) {
  1615        st->print("gssq     RA, FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1616     } else {
  1617        st->print("sd       RA, %d(SP)  @ MachPrologNode\n\t", -wordSize);
  1618        st->print("sd       FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1620     st->print("daddiu   FP, SP, -%d \n\t", wordSize*2);
  1621     st->print("daddiu   SP, SP, -%d \t",framesize);
  1623 #endif
  1626 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1627   Compile* C = ra_->C;
  1628   MacroAssembler _masm(&cbuf);
  1630   int framesize = C->frame_size_in_bytes();
  1631   int bangsize = C->bang_size_in_bytes();
  1633 //  __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false);
  1635   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1637   if (C->need_stack_bang(framesize)) {
  1638     __ generate_stack_overflow_check(framesize);
  1641   if (UseLoongsonISA) {
  1642      __ gssq(RA, FP, SP, -wordSize*2); 
  1643   } else {
  1644      __ sd(RA, SP, -wordSize);
  1645      __ sd(FP, SP, -wordSize*2);
  1647   __ daddiu(FP, SP, -wordSize*2);
  1648   __ daddiu(SP, SP, -framesize);
  1649   __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
  1650   __ nop();
  1652   C->set_frame_complete(cbuf.insts_size());
  1653   if (C->has_mach_constant_base_node()) {
  1654 	  // NOTE: We set the table base offset here because users might be
  1655 	  // emitted before MachConstantBaseNode.
  1656 	  Compile::ConstantTable& constant_table = C->constant_table();
  1657 	  constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  1663 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  1664 //fprintf(stderr, "\nPrologNode::size(ra_)= %d \n", MachNode::size(ra_));//fujie debug
  1665   return MachNode::size(ra_); // too many variables; just compute it the hard way
  1668 int MachPrologNode::reloc() const {
  1669   return 0; // a large enough number
  1672 %}
  1674 //----------ENCODING BLOCK-----------------------------------------------------
  1675 // This block specifies the encoding classes used by the compiler to output
  1676 // byte streams.  Encoding classes generate functions which are called by
  1677 // Machine Instruction Nodes in order to generate the bit encoding of the
  1678 // instruction.  Operands specify their base encoding interface with the
  1679 // interface keyword.  There are currently supported four interfaces,
  1680 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
  1681 // operand to generate a function which returns its register number when
  1682 // queried.   CONST_INTER causes an operand to generate a function which
  1683 // returns the value of the constant when queried.  MEMORY_INTER causes an
  1684 // operand to generate four functions which return the Base Register, the
  1685 // Index Register, the Scale Value, and the Offset Value of the operand when
  1686 // queried.  COND_INTER causes an operand to generate six functions which
  1687 // return the encoding code (ie - encoding bits for the instruction)
  1688 // associated with each basic boolean condition for a conditional instruction.
  1689 // Instructions specify two basic values for encoding.  They use the
  1690 // ins_encode keyword to specify their encoding class (which must be one of
  1691 // the class names specified in the encoding block), and they use the
  1692 // opcode keyword to specify, in order, their primary, secondary, and
  1693 // tertiary opcode.  Only the opcode sections which a particular instruction
  1694 // needs for encoding need to be specified.
  1695 encode %{
  1697   //Load byte signed
  1698   enc_class load_B_enc (mRegI dst, memory mem) %{
  1699      MacroAssembler _masm(&cbuf);
  1700      int  dst = $dst$$reg;
  1701      int  base = $mem$$base;
  1702      int  index = $mem$$index;
  1703      int  scale = $mem$$scale;
  1704      int  disp = $mem$$disp;
  1706      if( index != 0 ) {
  1707         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1708         __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1709      } else {
  1710         __ lb(as_Register(dst), as_Register(base), disp);
  1712   %}
  1714   //Load byte unsigned
  1715   enc_class load_UB_enc (mRegI dst, umemory mem) %{
  1716      MacroAssembler _masm(&cbuf);
  1717      int  dst = $dst$$reg;
  1718      int  base = $mem$$base;
  1719      int  index = $mem$$index;
  1720      int  scale = $mem$$scale;
  1721      int  disp = $mem$$disp;
  1723      assert(index == 0, "no index");
  1724      __ lbu(as_Register(dst), as_Register(base), disp);
  1725   %}
  1727   enc_class store_B_reg_enc (memory mem, mRegI src) %{
  1728      MacroAssembler _masm(&cbuf);
  1729      int  src = $src$$reg;
  1730      int  base = $mem$$base;
  1731      int  index = $mem$$index;
  1732      int  scale = $mem$$scale;
  1733      int  disp = $mem$$disp;
  1735      if( index != 0 ) {
  1736         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1737         __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
  1738      } else {
  1739         __ sb(as_Register(src), as_Register(base), disp);
  1741   %}
  1743   enc_class store_B0_enc (memory mem) %{
  1744      MacroAssembler _masm(&cbuf);
  1745      int  base = $mem$$base;
  1746      int  index = $mem$$index;
  1747      int  scale = $mem$$scale;
  1748      int  disp = $mem$$disp;
  1750      if( index != 0 ) {
  1751         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1752         __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1753      } else {
  1754         __ sb(R0, as_Register(base), disp);
  1756   %}
  1758   enc_class store_B_reg_sync_enc (memory mem, mRegI src) %{
  1759      MacroAssembler _masm(&cbuf);
  1760      int  src = $src$$reg;
  1761      int  base = $mem$$base;
  1762      int  index = $mem$$index;
  1763      int  scale = $mem$$scale;
  1764      int  disp = $mem$$disp;
  1766      if( index != 0 ) {
  1767         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1768         __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
  1769      } else {
  1770         __ sb(as_Register(src), as_Register(base), disp);
  1772      __ sync();
  1773   %}
  1775   enc_class store_B0_sync_enc (memory mem) %{
  1776      MacroAssembler _masm(&cbuf);
  1777      int  base = $mem$$base;
  1778      int  index = $mem$$index;
  1779      int  scale = $mem$$scale;
  1780      int  disp = $mem$$disp;
  1782      if( index != 0 ) {
  1783         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1784         __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1785      } else {
  1786         __ sb(R0, as_Register(base), disp);
  1788      __ sync();
  1789   %}
  1791   // Load Short (16bit signed)
  1792   enc_class load_S_enc (mRegI dst, memory mem) %{
  1793      MacroAssembler _masm(&cbuf);
  1794      int  dst = $dst$$reg;
  1795      int  base = $mem$$base;
  1796      int  index = $mem$$index;
  1797      int  scale = $mem$$scale;
  1798      int  disp = $mem$$disp;
  1800      if( index != 0 ) {
  1801         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1802 	__ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1803      } else {
  1804         __ lh(as_Register(dst), as_Register(base), disp);
  1806   %}
  1808   // Load Char (16bit unsigned)
  1809   enc_class load_C_enc (mRegI dst, umemory mem) %{
  1810      MacroAssembler _masm(&cbuf);
  1811      int  dst = $dst$$reg;
  1812      int  base = $mem$$base;
  1813      int  index = $mem$$index;
  1814      int  scale = $mem$$scale;
  1815      int  disp = $mem$$disp;
  1817      assert(index == 0, "no index");
  1818      __ lhu(as_Register(dst), as_Register(base), disp);
  1819   %}
  1821   // Store Char (16bit unsigned)
  1822   enc_class store_C_reg_enc (memory mem, mRegI src) %{
  1823      MacroAssembler _masm(&cbuf);
  1824      int  src = $src$$reg;
  1825      int  base = $mem$$base;
  1826      int  index = $mem$$index;
  1827      int  scale = $mem$$scale;
  1828      int  disp = $mem$$disp;
  1830      if( index != 0 ) {
  1831         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1832         __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
  1833      } else {
  1834         __ sh(as_Register(src), as_Register(base), disp);
  1836   %}
  1838   enc_class store_C0_enc (memory mem) %{
  1839      MacroAssembler _masm(&cbuf);
  1840      int  base = $mem$$base;
  1841      int  index = $mem$$index;
  1842      int  scale = $mem$$scale;
  1843      int  disp = $mem$$disp;
  1845      if( index != 0 ) {
  1846         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1847         __ gsshx(R0, as_Register(base), as_Register(index), disp);
  1848      } else {
  1849         __ sh(R0, as_Register(base), disp);
  1851   %}
  1853   enc_class load_I_enc (mRegI dst, memory mem) %{
  1854      MacroAssembler _masm(&cbuf);
  1855      int  dst = $dst$$reg;
  1856      int  base = $mem$$base;
  1857      int  index = $mem$$index;
  1858      int  scale = $mem$$scale;
  1859      int  disp = $mem$$disp;
  1861      if( index != 0 ) {
  1862         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1863         __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1864      } else {
  1865         __ lw(as_Register(dst), as_Register(base), disp);
  1867   %}
  1869   enc_class store_I_reg_enc (memory mem, mRegI src) %{
  1870      MacroAssembler _masm(&cbuf);
  1871      int  src = $src$$reg;
  1872      int  base = $mem$$base;
  1873      int  index = $mem$$index;
  1874      int  scale = $mem$$scale;
  1875      int  disp = $mem$$disp;
  1877      if( index != 0 ) {
  1878         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1879         __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  1880      } else {
  1881         __ sw(as_Register(src), as_Register(base), disp);
  1883   %}
  1885   enc_class store_I_immI0_enc (memory mem) %{
  1886      MacroAssembler _masm(&cbuf);
  1887      int  base  = $mem$$base;
  1888      int  index = $mem$$index;
  1889      int  scale = $mem$$scale;
  1890      int  disp  = $mem$$disp;
  1892      if( index != 0 ) {
  1893         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1894         __ gsswx(R0, as_Register(base), as_Register(index), disp);
  1895      } else {
  1896         __ sw(R0, as_Register(base), disp);
  1898   %}
  1900   enc_class load_N_enc (mRegN dst, umemory mem) %{
  1901      MacroAssembler _masm(&cbuf);
  1902      int  dst = $dst$$reg;
  1903      int  base = $mem$$base;
  1904      int  index = $mem$$index;
  1905      int  scale = $mem$$scale;
  1906      int  disp = $mem$$disp;
  1908      relocInfo::relocType disp_reloc = $mem->disp_reloc();
  1909      assert(disp_reloc == relocInfo::none, "cannot have disp");
  1911      assert(index == 0, "no index");
  1912      __ lwu(as_Register(dst), as_Register(base), disp);
  1913   %}
  1916   enc_class load_P_enc (mRegP dst, memory mem) %{
  1917      MacroAssembler _masm(&cbuf);
  1918      int  dst = $dst$$reg;
  1919      int  base = $mem$$base;
  1920      int  index = $mem$$index;
  1921      int  scale = $mem$$scale;
  1922      int  disp = $mem$$disp;
  1924      relocInfo::relocType disp_reloc = $mem->disp_reloc();
  1925      assert(disp_reloc == relocInfo::none, "cannot have disp");
  1927      if( index != 0 ) {
  1928         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1929         __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1930      } else {
  1931         __ ld(as_Register(dst), as_Register(base), disp);
  1933   %}
  1935   enc_class store_P_reg_enc (memory mem, mRegP src) %{
  1936      MacroAssembler _masm(&cbuf);
  1937      int  src = $src$$reg;
  1938      int  base = $mem$$base;
  1939      int  index = $mem$$index;
  1940      int  scale = $mem$$scale;
  1941      int  disp = $mem$$disp;
  1943      if( index != 0 ) {
  1944         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1945         __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
  1946      } else {
  1947         __ sd(as_Register(src), as_Register(base), disp);
  1949   %}
  1951   enc_class store_N_reg_enc (memory mem, mRegN src) %{
  1952      MacroAssembler _masm(&cbuf);
  1953      int  src = $src$$reg;
  1954      int  base = $mem$$base;
  1955      int  index = $mem$$index;
  1956      int  scale = $mem$$scale;
  1957      int  disp = $mem$$disp;
  1959      if( index != 0 ) {
  1960         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1961         __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  1962      } else {
  1963 	__ sw(as_Register(src), as_Register(base), disp);
  1965   %}
  1967   enc_class store_P_immP0_enc (memory mem) %{
  1968      MacroAssembler _masm(&cbuf);
  1969      int  base = $mem$$base;
  1970      int  index = $mem$$index;
  1971      int  scale = $mem$$scale;
  1972      int  disp = $mem$$disp;
  1974      if( index != 0 ) {
  1975         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1976         __ gssdx(R0, as_Register(base), as_Register(index), disp);
  1977      } else {
  1978         __ sd(R0, as_Register(base), disp);
  1980   %}
  1983   enc_class storeImmN0_enc(memory mem) %{
  1984      MacroAssembler _masm(&cbuf);
  1985      int  base = $mem$$base;
  1986      int  index = $mem$$index;
  1987      int  scale = $mem$$scale;
  1988      int  disp = $mem$$disp;
  1990      if(index != 0){
  1991        assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  1992        __ gsswx(R0, as_Register(base), as_Register(index), disp);
  1993      } else {
  1994        __ sw(R0, as_Register(base), disp);
  1996   %} 
  1998   enc_class load_L_enc (mRegL dst, memory mem) %{
  1999      MacroAssembler _masm(&cbuf);
  2000      int  base = $mem$$base;
  2001      int  index = $mem$$index;
  2002      int  scale = $mem$$scale;
  2003      int  disp = $mem$$disp;
  2004      Register  dst_reg = as_Register($dst$$reg);
  2006      if( index != 0 ) {
  2007         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2008         __ gsldx(dst_reg, as_Register(base), as_Register(index), disp);
  2009      } else {
  2010         __ ld(dst_reg, as_Register(base), disp);
  2012   %}
  2014   enc_class store_L_reg_enc (memory mem, mRegL src) %{
  2015      MacroAssembler _masm(&cbuf);
  2016      int  base = $mem$$base;
  2017      int  index = $mem$$index;
  2018      int  scale = $mem$$scale;
  2019      int  disp = $mem$$disp;
  2020      Register  src_reg = as_Register($src$$reg);
  2022      if( index != 0 ) {
  2023         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2024         __ gssdx(src_reg, as_Register(base), as_Register(index), disp);
  2025      } else {
  2026         __ sd(src_reg, as_Register(base), disp);
  2028   %}
  2030   enc_class store_L_immL0_enc (memory mem) %{
  2031      MacroAssembler _masm(&cbuf);
  2032      int  base = $mem$$base;
  2033      int  index = $mem$$index;
  2034      int  scale = $mem$$scale;
  2035      int  disp = $mem$$disp;
  2037      if( index != 0 ) {
  2038         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2039         __ gssdx(R0, as_Register(base), as_Register(index), disp);
  2040      } else {
  2041         __ sd(R0, as_Register(base), disp);
  2043   %}
  2045   enc_class load_F_enc (regF dst, memory mem) %{
  2046      MacroAssembler _masm(&cbuf);
  2047      int  base = $mem$$base;
  2048      int  index = $mem$$index;
  2049      int  scale = $mem$$scale;
  2050      int  disp = $mem$$disp;
  2051      FloatRegister dst = $dst$$FloatRegister;
  2053      if( index != 0 ) {
  2054         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2055         __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
  2056      } else {
  2057         __ lwc1(dst, as_Register(base), disp);
  2059   %}
  2061   enc_class store_F_reg_enc (memory mem, regF src) %{
  2062      MacroAssembler _masm(&cbuf);
  2063      int  base = $mem$$base;
  2064      int  index = $mem$$index;
  2065      int  scale = $mem$$scale;
  2066      int  disp = $mem$$disp;
  2067      FloatRegister src = $src$$FloatRegister;
  2069      if( index != 0 ) {
  2070         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2071         __ gsswxc1(src, as_Register(base), as_Register(index), disp);
  2072      } else {
  2073         __ swc1(src, as_Register(base), disp);
  2075   %}
  2077   enc_class load_D_enc (regD dst, memory mem) %{
  2078      MacroAssembler _masm(&cbuf);
  2079      int  base = $mem$$base;
  2080      int  index = $mem$$index;
  2081      int  scale = $mem$$scale;
  2082      int  disp = $mem$$disp;
  2083      FloatRegister dst_reg = as_FloatRegister($dst$$reg);
  2085      if( index != 0 ) {
  2086         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2087         __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
  2088      } else {
  2089         __ ldc1(dst_reg, as_Register(base), disp);
  2091   %}
  2093   enc_class store_D_reg_enc (memory mem, regD src) %{
  2094      MacroAssembler _masm(&cbuf);
  2095      int  base  = $mem$$base;
  2096      int  index = $mem$$index;
  2097      int  scale = $mem$$scale;
  2098      int  disp  = $mem$$disp;
  2099      FloatRegister src_reg = as_FloatRegister($src$$reg);
  2101      if( index != 0 ) {
  2102         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
  2103         __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
  2104      } else {
  2105         __ sdc1(src_reg, as_Register(base), disp);
  2107   %}
  2109   enc_class Java_To_Runtime (method meth) %{    // CALL Java_To_Runtime, Java_To_Runtime_Leaf
  2110       MacroAssembler _masm(&cbuf);
  2111     // This is the instruction starting address for relocation info.
  2112     __ block_comment("Java_To_Runtime");
  2113     cbuf.set_insts_mark();
  2114     __ relocate(relocInfo::runtime_call_type);
  2116     __ patchable_call((address)$meth$$method);
  2117     %}
  2119   enc_class Java_Static_Call (method meth) %{    // JAVA STATIC CALL
  2120     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
  2121     // who we intended to call.
  2122     MacroAssembler _masm(&cbuf);
  2123     cbuf.set_insts_mark();
  2125     if ( !_method ) {
  2126       __ relocate(relocInfo::runtime_call_type);
  2127     } else if(_optimized_virtual) {
  2128       __ relocate(relocInfo::opt_virtual_call_type);
  2129     } else {
  2130       __ relocate(relocInfo::static_call_type);
  2133     __ patchable_call((address)($meth$$method));
  2134     if( _method ) {  // Emit stub for static call
  2135       emit_java_to_interp(cbuf);
  2137   %}
  2140 /*
  2141  * [Ref: LIR_Assembler::ic_call() ]
  2142  */
  2143 enc_class Java_Dynamic_Call (method meth) %{    // JAVA DYNAMIC CALL
  2144     MacroAssembler _masm(&cbuf);
  2145 	__ block_comment("Java_Dynamic_Call");
  2146 	__ ic_call((address)$meth$$method);
  2147   %}
  2150   enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
  2151     Register flags = $cr$$Register;
  2152     Label  L;
  2154     MacroAssembler _masm(&cbuf);
  2156     __ addu(flags, R0, R0);    
  2157     __ beq(AT, R0, L);
  2158     __ delayed()->nop();
  2159     __ move(flags, 0xFFFFFFFF);
  2160     __ bind(L);
  2161   %}
  2163   enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
  2164     Register result = $result$$Register;
  2165     Register sub    = $sub$$Register;
  2166     Register super  = $super$$Register;
  2167     Register length = $tmp$$Register;
  2168     Register tmp    = T9;
  2169     Label miss;
  2171     /* 2012/9/28 Jin: result may be the same as sub
  2172      *    47c   B40: #    B21 B41 <- B20  Freq: 0.155379
  2173      *    47c     partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
  2174      *    4bc     mov   S2, NULL #@loadConP
  2175      *    4c0     beq   S1, S2, B21 #@branchConP  P=0.999999 C=-1.000000
  2176     */
  2177     MacroAssembler _masm(&cbuf);
  2178     Label done;
  2179     __ check_klass_subtype_slow_path(sub, super, length, tmp,
  2180                                      NULL, &miss,
  2181                                      /*set_cond_codes:*/ true);
  2182     /* 2013/7/22 Jin: Refer to X86_64's RDI */
  2183     __ move(result, 0);
  2184     __ b(done);
  2185     __ nop();
  2187     __ bind(miss);
  2188     __ move(result, 1);
  2189     __ bind(done);
  2190   %}
  2192 %}
  2195 //---------MIPS FRAME--------------------------------------------------------------
  2196 // Definition of frame structure and management information.
  2197 //
  2198 //  S T A C K   L A Y O U T    Allocators stack-slot number
  2199 //                             |   (to get allocators register number
  2200 //  G  Owned by    |        |  v    add SharedInfo::stack0)
  2201 //  r   CALLER     |        |
  2202 //  o     |        +--------+      pad to even-align allocators stack-slot 
  2203 //  w     V        |  pad0  |        numbers; owned by CALLER
  2204 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
  2205 //  h     ^        |   in   |  5   
  2206 //        |        |  args  |  4   Holes in incoming args owned by SELF
  2207 //  |     |    old |        |  3
  2208 //  |     |     SP-+--------+----> Matcher::_old_SP, even aligned
  2209 //  v     |        |  ret   |  3   return address
  2210 //     Owned by    +--------+
  2211 //      Self       |  pad2  |  2   pad to align old SP
  2212 //        |        +--------+  1
  2213 //        |        | locks  |  0
  2214 //        |        +--------+----> SharedInfo::stack0, even aligned  
  2215 //        |        |  pad1  | 11   pad to align new SP
  2216 //        |        +--------+
  2217 //        |        |        | 10
  2218 //        |        | spills |  9   spills
  2219 //        V        |        |  8   (pad0 slot for callee)
  2220 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
  2221 //        ^        |  out   |  7   
  2222 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
  2223 //   Owned by  new |				|
  2224 //		Callee    SP-+--------+----> Matcher::_new_SP, even aligned
  2225 //           			 |        |
  2226 //
  2227 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is 
  2228 //         known from SELF's arguments and the Java calling convention.
  2229 //         Region 6-7 is determined per call site.
  2230 // Note 2: If the calling convention leaves holes in the incoming argument 
  2231 //         area, those holes are owned by SELF.  Holes in the outgoing area
  2232 //         are owned by the CALLEE.  Holes should not be nessecary in the
  2233 //         incoming area, as the Java calling convention is completely under
  2234 //         the control of the AD file.  Doubles can be sorted and packed to
  2235 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
  2236 //         varargs C calling conventions.
  2237 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is 
  2238 //         even aligned with pad0 as needed.
  2239 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
  2240 //         region 6-11 is even aligned; it may be padded out more so that
  2241 //         the region from SP to FP meets the minimum stack alignment.
  2242 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
  2243 //         alignment.  Region 11, pad1, may be dynamically extended so that
  2244 //         SP meets the minimum alignment.
  2247 frame %{
  2249   stack_direction(TOWARDS_LOW);
  2251   // These two registers define part of the calling convention 
  2252   // between compiled code and the interpreter.
  2253 	// SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention 
  2254 	// for more information. by yjl 3/16/2006
  2256   inline_cache_reg(T1);                // Inline Cache Register
  2257   interpreter_method_oop_reg(S3);      // Method Oop Register when calling interpreter
  2258  /*
  2259   inline_cache_reg(T1);          // Inline Cache Register or methodOop for I2C
  2260   interpreter_arg_ptr_reg(A0);         // Argument pointer for I2C adapters
  2261 */
  2263   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
  2264   cisc_spilling_operand_name(indOffset32);  
  2266   // Number of stack slots consumed by locking an object
  2267 	// generate Compile::sync_stack_slots
  2268 #ifdef _LP64
  2269   sync_stack_slots(2);
  2270 #else
  2271   sync_stack_slots(1);
  2272 #endif
  2274   frame_pointer(SP);
  2276   // Interpreter stores its frame pointer in a register which is 
  2277   // stored to the stack by I2CAdaptors.
  2278   // I2CAdaptors convert from interpreted java to compiled java.
  2280   interpreter_frame_pointer(FP);
  2282 	// generate Matcher::stack_alignment
  2283   stack_alignment(StackAlignmentInBytes);  //wordSize = sizeof(char*);            
  2285   // Number of stack slots between incoming argument block and the start of 
  2286   // a new frame.  The PROLOG must add this many slots to the stack.  The
  2287   // EPILOG must remove this many slots.  Intel needs one slot for
  2288   // return address.
  2289 	// generate Matcher::in_preserve_stack_slots
  2290   //in_preserve_stack_slots(VerifyStackAtCalls + 2);  //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
  2291   in_preserve_stack_slots(4);  //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
  2293   // Number of outgoing stack slots killed above the out_preserve_stack_slots
  2294   // for calls to C.  Supports the var-args backing area for register parms.
  2295   varargs_C_out_slots_killed(0);
  2297   // The after-PROLOG location of the return address.  Location of
  2298   // return address specifies a type (REG or STACK) and a number
  2299   // representing the register number (i.e. - use a register name) or
  2300   // stack slot.
  2301   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
  2302   // Otherwise, it is above the locks and verification slot and alignment word
  2303   //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
  2304   return_addr(REG RA);
  2306   // Body of function which returns an integer array locating
  2307   // arguments either in registers or in stack slots.  Passed an array
  2308   // of ideal registers called "sig" and a "length" count.  Stack-slot
  2309   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  2310   // arguments for a CALLEE.  Incoming stack arguments are
  2311   // automatically biased by the preserve_stack_slots field above.
  2314 	// will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
  2315 	// StartNode::calling_convention call this. by yjl 3/16/2006
  2316   calling_convention %{           
  2317     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
  2318   %}
  2323   // Body of function which returns an integer array locating
  2324   // arguments either in registers or in stack slots.  Passed an array
  2325   // of ideal registers called "sig" and a "length" count.  Stack-slot
  2326   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  2327   // arguments for a CALLEE.  Incoming stack arguments are
  2328   // automatically biased by the preserve_stack_slots field above.
  2331 	// SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
  2332   c_calling_convention %{          
  2333    (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
  2334   %}
  2337   // Location of C & interpreter return values
  2338 	// register(s) contain(s) return value for Op_StartI2C and Op_StartOSR. 
  2339 	// SEE Matcher::match. by yjl 3/16/2006
  2340   c_return_value %{
  2341     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  2342                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  2343     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,    V0_num };
  2344     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,  V0_H_num };
  2345     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  2346   %}
  2348   // Location of return values
  2349 	// register(s) contain(s) return value for Op_StartC2I and Op_Start. 
  2350 	// SEE Matcher::match. by yjl 3/16/2006
  2352   return_value %{
  2353     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  2354                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  2355     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,     V0_num };
  2356     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,   V0_H_num};
  2357     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  2358   %}
  2360 %}
  2362 //----------ATTRIBUTES---------------------------------------------------------
  2363 //----------Operand Attributes-------------------------------------------------
  2364 op_attrib op_cost(0);        // Required cost attribute
  2366 //----------Instruction Attributes---------------------------------------------
  2367 ins_attrib ins_cost(100);       // Required cost attribute
  2368 ins_attrib ins_size(32);         // Required size attribute (in bits)
  2369 ins_attrib ins_pc_relative(0);  // Required PC Relative flag
  2370 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
  2371                                 // non-matching short branch variant of some
  2372                                                             // long branch?
  2373 ins_attrib ins_alignment(4);    // Required alignment attribute (must be a power of 2)
  2374                                 // specifies the alignment that some part of the instruction (not
  2375                                 // necessarily the start) requires.  If > 1, a compute_padding()
  2376                                 // function must be provided for the instruction
  2378 //----------OPERANDS-----------------------------------------------------------
  2379 // Operand definitions must precede instruction definitions for correct parsing
  2380 // in the ADLC because operands constitute user defined types which are used in
  2381 // instruction definitions.
  2383 // Vectors
  2384 operand vecD() %{
  2385   constraint(ALLOC_IN_RC(dbl_reg));
  2386   match(VecD);
  2388   format %{ %}
  2389   interface(REG_INTER);
  2390 %}
  2392 // Flags register, used as output of compare instructions
  2393 operand FlagsReg() %{
  2394   constraint(ALLOC_IN_RC(mips_flags));
  2395   match(RegFlags);
  2397   format %{ "EFLAGS" %}
  2398   interface(REG_INTER);
  2399 %}
  2401 //----------Simple Operands----------------------------------------------------
  2402 //TODO: Should we need to define some more special immediate number ?
  2403 // Immediate Operands
  2404 // Integer Immediate
  2405 operand immI() %{
  2406   match(ConI);
  2407   //TODO: should not match immI8 here LEE
  2408   match(immI8);
  2410   op_cost(20);
  2411   format %{ %}
  2412   interface(CONST_INTER);
  2413 %}
  2415 // Long Immediate 8-bit
  2416 operand immL8()
  2417 %{
  2418   predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
  2419   match(ConL);
  2421   op_cost(5);
  2422   format %{ %}
  2423   interface(CONST_INTER);
  2424 %}
  2426 // Constant for test vs zero
  2427 operand immI0() %{
  2428   predicate(n->get_int() == 0);
  2429   match(ConI);
  2431   op_cost(0);
  2432   format %{ %}
  2433   interface(CONST_INTER);
  2434 %}
  2436 // Constant for increment
  2437 operand immI1() %{
  2438   predicate(n->get_int() == 1);
  2439   match(ConI);
  2441   op_cost(0);
  2442   format %{ %}
  2443   interface(CONST_INTER);
  2444 %}
  2446 // Constant for decrement
  2447 operand immI_M1() %{
  2448   predicate(n->get_int() == -1);
  2449   match(ConI);
  2451   op_cost(0);
  2452   format %{ %}
  2453   interface(CONST_INTER);
  2454 %}
  2456 operand immI_MaxI() %{
  2457   predicate(n->get_int() == 2147483647);
  2458   match(ConI);
  2460   op_cost(0);
  2461   format %{ %}
  2462   interface(CONST_INTER);
  2463 %}
  2465 // Valid scale values for addressing modes
  2466 operand immI2() %{
  2467   predicate(0 <= n->get_int() && (n->get_int() <= 3));
  2468   match(ConI);
  2470   format %{ %}
  2471   interface(CONST_INTER);
  2472 %}
  2474 operand immI8() %{
  2475   predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
  2476   match(ConI);
  2478   op_cost(5);
  2479   format %{ %}
  2480   interface(CONST_INTER);
  2481 %}
  2483 operand immI16() %{
  2484   predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
  2485   match(ConI);
  2487   op_cost(10);
  2488   format %{ %}
  2489   interface(CONST_INTER);
  2490 %}
  2492 // Constant for long shifts
  2493 operand immI_32() %{
  2494   predicate( n->get_int() == 32 );
  2495   match(ConI);
  2497   op_cost(0);
  2498   format %{ %}
  2499   interface(CONST_INTER);
  2500 %}
  2502 operand immI_63() %{
  2503   predicate( n->get_int() == 63 );
  2504   match(ConI);
  2506   op_cost(0);
  2507   format %{ %}
  2508   interface(CONST_INTER);
  2509 %}
  2511 operand immI_0_31() %{
  2512   predicate( n->get_int() >= 0 && n->get_int() <= 31 );
  2513   match(ConI);
  2515   op_cost(0);
  2516   format %{ %}
  2517   interface(CONST_INTER);
  2518 %}
  2520 // Operand for non-negtive integer mask
  2521 operand immI_nonneg_mask() %{
  2522   predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
  2523   match(ConI);
  2525   op_cost(0);
  2526   format %{ %}
  2527   interface(CONST_INTER);
  2528 %}
  2530 operand immI_32_63() %{
  2531   predicate( n->get_int() >= 32 && n->get_int() <= 63 );
  2532   match(ConI);
  2533   op_cost(0);
  2535   format %{ %}
  2536   interface(CONST_INTER);
  2537 %}
  2539 operand immI16_sub() %{
  2540   predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
  2541   match(ConI);
  2543   op_cost(10);
  2544   format %{ %}
  2545   interface(CONST_INTER);
  2546 %}
  2548 operand immI_0_32767() %{
  2549   predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
  2550   match(ConI);
  2551   op_cost(0);
  2553   format %{ %}
  2554   interface(CONST_INTER);
  2555 %}
  2557 operand immI_0_65535() %{
  2558   predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
  2559   match(ConI);
  2560   op_cost(0);
  2562   format %{ %}
  2563   interface(CONST_INTER);
  2564 %}
  2566 operand immI_1() %{
  2567   predicate( n->get_int() == 1 );
  2568   match(ConI);
  2570   op_cost(0);
  2571   format %{ %}
  2572   interface(CONST_INTER);
  2573 %}
  2575 operand immI_2() %{
  2576   predicate( n->get_int() == 2 );
  2577   match(ConI);
  2579   op_cost(0);
  2580   format %{ %}
  2581   interface(CONST_INTER);
  2582 %}
  2584 operand immI_3() %{
  2585   predicate( n->get_int() == 3 );
  2586   match(ConI);
  2588   op_cost(0);
  2589   format %{ %}
  2590   interface(CONST_INTER);
  2591 %}
  2593 operand immI_7() %{
  2594   predicate( n->get_int() == 7 );
  2595   match(ConI);
  2597   format %{ %}
  2598   interface(CONST_INTER);
  2599 %}
  2601 // Immediates for special shifts (sign extend)
  2603 // Constants for increment
  2604 operand immI_16() %{
  2605   predicate( n->get_int() == 16 );
  2606   match(ConI);
  2608   format %{ %}
  2609   interface(CONST_INTER);
  2610 %}
  2612 operand immI_24() %{
  2613   predicate( n->get_int() == 24 );
  2614   match(ConI);
  2616   format %{ %}
  2617   interface(CONST_INTER);
  2618 %}
  2620 // Constant for byte-wide masking
  2621 operand immI_255() %{
  2622   predicate( n->get_int() == 255 );
  2623   match(ConI);
  2625   op_cost(0);
  2626   format %{ %}
  2627   interface(CONST_INTER);
  2628 %}
  2630 operand immI_65535() %{
  2631   predicate( n->get_int() == 65535 );
  2632   match(ConI);
  2634   op_cost(5);
  2635   format %{ %}
  2636   interface(CONST_INTER);
  2637 %}
  2639 operand immI_65536() %{
  2640   predicate( n->get_int() == 65536 );
  2641   match(ConI);
  2643   op_cost(5);
  2644   format %{ %}
  2645   interface(CONST_INTER);
  2646 %}
  2648 operand immI_M65536() %{
  2649   predicate( n->get_int() == -65536 );
  2650   match(ConI);
  2652   op_cost(5);
  2653   format %{ %}
  2654   interface(CONST_INTER);
  2655 %}
  2657 // Pointer Immediate
  2658 operand immP() %{
  2659   match(ConP);
  2661   op_cost(10);
  2662   format %{ %}
  2663   interface(CONST_INTER);
  2664 %}
  2666 // NULL Pointer Immediate
  2667 operand immP0() %{
  2668   predicate( n->get_ptr() == 0 );
  2669   match(ConP);
  2670   op_cost(0);
  2672   format %{ %}
  2673   interface(CONST_INTER);
  2674 %}
  2676 // Pointer Immediate: 64-bit
  2677 operand immP_set() %{
  2678   match(ConP);
  2680   op_cost(5);
  2681   // formats are generated automatically for constants and base registers
  2682   format %{ %}
  2683   interface(CONST_INTER);
  2684 %}
  2686 // Pointer Immediate: 64-bit
  2687 operand immP_load() %{
  2688   predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
  2689   match(ConP);
  2691   op_cost(5);
  2692   // formats are generated automatically for constants and base registers
  2693   format %{ %}
  2694   interface(CONST_INTER);
  2695 %}
  2697 // Pointer Immediate: 64-bit
  2698 operand immP_no_oop_cheap() %{
  2699   predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
  2700   match(ConP);
  2702   op_cost(5);
  2703   // formats are generated automatically for constants and base registers
  2704   format %{ %}
  2705   interface(CONST_INTER);
  2706 %}
  2708 // Pointer for polling page 
  2709 operand immP_poll() %{
  2710   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
  2711   match(ConP);
  2712   op_cost(5);
  2714   format %{ %}
  2715   interface(CONST_INTER);
  2716 %}
  2718 // Pointer Immediate
  2719 operand immN() %{
  2720   match(ConN);
  2722   op_cost(10);
  2723   format %{ %}
  2724   interface(CONST_INTER);
  2725 %}
  2727 operand immNKlass() %{
  2728   match(ConNKlass);
  2730   op_cost(10);
  2731   format %{ %}
  2732   interface(CONST_INTER);
  2733 %}
  2735 // NULL Pointer Immediate
  2736 operand immN0() %{
  2737   predicate(n->get_narrowcon() == 0);
  2738   match(ConN);
  2740   op_cost(5);
  2741   format %{ %}
  2742   interface(CONST_INTER);
  2743 %}
  2745 // Long Immediate
  2746 operand immL() %{
  2747   match(ConL);
  2749   op_cost(20);
  2750   format %{ %}
  2751   interface(CONST_INTER);
  2752 %}
  2754 // Long Immediate zero
  2755 operand immL0() %{
  2756   predicate( n->get_long() == 0L );
  2757   match(ConL);
  2758   op_cost(0);
  2760   format %{ %}
  2761   interface(CONST_INTER);
  2762 %}
  2764 operand immL7() %{
  2765   predicate( n->get_long() == 7L );
  2766   match(ConL);
  2767   op_cost(0);
  2769   format %{ %}
  2770   interface(CONST_INTER);
  2771 %}
  2773 operand immL_M1() %{
  2774   predicate( n->get_long() == -1L );
  2775   match(ConL);
  2776   op_cost(0);
  2778   format %{ %}
  2779   interface(CONST_INTER);
  2780 %}
  2782 // bit 0..2 zero
  2783 operand immL_M8() %{
  2784   predicate( n->get_long() == -8L );
  2785   match(ConL);
  2786   op_cost(0);
  2788   format %{ %}
  2789   interface(CONST_INTER);
  2790 %}
  2792 // bit 2 zero
  2793 operand immL_M5() %{
  2794   predicate( n->get_long() == -5L );
  2795   match(ConL);
  2796   op_cost(0);
  2798   format %{ %}
  2799   interface(CONST_INTER);
  2800 %}
  2802 // bit 1..2 zero
  2803 operand immL_M7() %{
  2804   predicate( n->get_long() == -7L );
  2805   match(ConL);
  2806   op_cost(0);
  2808   format %{ %}
  2809   interface(CONST_INTER);
  2810 %}
  2812 // bit 0..1 zero
  2813 operand immL_M4() %{
  2814   predicate( n->get_long() == -4L );
  2815   match(ConL);
  2816   op_cost(0);
  2818   format %{ %}
  2819   interface(CONST_INTER);
  2820 %}
  2822 // bit 3..6 zero
  2823 operand immL_M121() %{
  2824   predicate( n->get_long() == -121L );
  2825   match(ConL);
  2826   op_cost(0);
  2828   format %{ %}
  2829   interface(CONST_INTER);
  2830 %}
  2832 // Long immediate from 0 to 127.
  2833 // Used for a shorter form of long mul by 10.
  2834 operand immL_127() %{
  2835   predicate((0 <= n->get_long()) && (n->get_long() <= 127));
  2836   match(ConL);
  2837   op_cost(0);
  2839   format %{ %}
  2840   interface(CONST_INTER);
  2841 %}
  2843 // Operand for non-negtive long mask
  2844 operand immL_nonneg_mask() %{
  2845   predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
  2846   match(ConL);
  2848   op_cost(0);
  2849   format %{ %}
  2850   interface(CONST_INTER);
  2851 %}
  2853 operand immL_0_65535() %{
  2854   predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
  2855   match(ConL);
  2856   op_cost(0);
  2858   format %{ %}
  2859   interface(CONST_INTER);
  2860 %}
  2862 // Long Immediate: cheap (materialize in <= 3 instructions)
  2863 operand immL_cheap() %{
  2864   predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
  2865   match(ConL);
  2866   op_cost(0);
  2868   format %{ %}
  2869   interface(CONST_INTER);
  2870 %}
  2872 // Long Immediate: expensive (materialize in > 3 instructions)
  2873 operand immL_expensive() %{
  2874   predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
  2875   match(ConL);
  2876   op_cost(0);
  2878   format %{ %}
  2879   interface(CONST_INTER);
  2880 %}
  2882 operand immL16() %{
  2883   predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
  2884   match(ConL);
  2886   op_cost(10);
  2887   format %{ %}
  2888   interface(CONST_INTER);
  2889 %}
  2891 operand immL16_sub() %{
  2892   predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
  2893   match(ConL);
  2895   op_cost(10);
  2896   format %{ %}
  2897   interface(CONST_INTER);
  2898 %}
  2900 // Long Immediate: low 32-bit mask
  2901 operand immL_32bits() %{
  2902   predicate(n->get_long() == 0xFFFFFFFFL);
  2903   match(ConL);
  2904   op_cost(20);
  2906   format %{ %}
  2907   interface(CONST_INTER);
  2908 %}
  2910 // Long Immediate 32-bit signed
  2911 operand immL32()
  2912 %{
  2913   predicate(n->get_long() == (int) (n->get_long()));
  2914   match(ConL);
  2916   op_cost(15);
  2917   format %{ %}
  2918   interface(CONST_INTER);
  2919 %}
  2922 //single-precision floating-point zero
  2923 operand immF0() %{
  2924   predicate(jint_cast(n->getf()) == 0);
  2925   match(ConF);
  2927   op_cost(5);
  2928   format %{ %}
  2929   interface(CONST_INTER);
  2930 %}
  2932 //single-precision floating-point immediate
  2933 operand immF() %{
  2934   match(ConF);
  2936   op_cost(20);
  2937   format %{ %}
  2938   interface(CONST_INTER);
  2939 %}
  2941 //double-precision floating-point zero 
  2942 operand immD0() %{
  2943   predicate(jlong_cast(n->getd()) == 0);
  2944   match(ConD);
  2946   op_cost(5);
  2947   format %{ %}
  2948   interface(CONST_INTER);
  2949 %}
  2951 //double-precision floating-point immediate
  2952 operand immD() %{
  2953   match(ConD);
  2955   op_cost(20);
  2956   format %{ %}
  2957   interface(CONST_INTER);
  2958 %}
  2960 // Register Operands
  2961 // Integer Register
  2962 operand mRegI() %{
  2963   constraint(ALLOC_IN_RC(int_reg));
  2964   match(RegI);
  2966   format %{ %}
  2967   interface(REG_INTER);
  2968 %}
  2970 operand no_Ax_mRegI() %{
  2971   constraint(ALLOC_IN_RC(no_Ax_int_reg));
  2972   match(RegI);
  2973   match(mRegI);
  2975   format %{  %}
  2976   interface(REG_INTER);
  2977 %} 
  2979 operand mS0RegI() %{
  2980   constraint(ALLOC_IN_RC(s0_reg));
  2981   match(RegI);
  2982   match(mRegI);
  2984   format %{ "S0" %}
  2985   interface(REG_INTER);
  2986 %}
  2988 operand mS1RegI() %{
  2989   constraint(ALLOC_IN_RC(s1_reg));
  2990   match(RegI);
  2991   match(mRegI);
  2993   format %{ "S1" %}
  2994   interface(REG_INTER);
  2995 %}
  2997 operand mS2RegI() %{
  2998   constraint(ALLOC_IN_RC(s2_reg));
  2999   match(RegI);
  3000   match(mRegI);
  3002   format %{ "S2" %}
  3003   interface(REG_INTER);
  3004 %}
  3006 operand mS3RegI() %{
  3007   constraint(ALLOC_IN_RC(s3_reg));
  3008   match(RegI);
  3009   match(mRegI);
  3011   format %{ "S3" %}
  3012   interface(REG_INTER);
  3013 %}
  3015 operand mS4RegI() %{
  3016   constraint(ALLOC_IN_RC(s4_reg));
  3017   match(RegI);
  3018   match(mRegI);
  3020   format %{ "S4" %}
  3021   interface(REG_INTER);
  3022 %}
  3024 operand mS5RegI() %{
  3025   constraint(ALLOC_IN_RC(s5_reg));
  3026   match(RegI);
  3027   match(mRegI);
  3029   format %{ "S5" %}
  3030   interface(REG_INTER);
  3031 %}
  3033 operand mS6RegI() %{
  3034   constraint(ALLOC_IN_RC(s6_reg));
  3035   match(RegI);
  3036   match(mRegI);
  3038   format %{ "S6" %}
  3039   interface(REG_INTER);
  3040 %}
  3042 operand mS7RegI() %{
  3043   constraint(ALLOC_IN_RC(s7_reg));
  3044   match(RegI);
  3045   match(mRegI);
  3047   format %{ "S7" %}
  3048   interface(REG_INTER);
  3049 %}
  3052 operand mT0RegI() %{
  3053   constraint(ALLOC_IN_RC(t0_reg));
  3054   match(RegI);
  3055   match(mRegI);
  3057   format %{ "T0" %}
  3058   interface(REG_INTER);
  3059 %}
  3061 operand mT1RegI() %{
  3062   constraint(ALLOC_IN_RC(t1_reg));
  3063   match(RegI);
  3064   match(mRegI);
  3066   format %{ "T1" %}
  3067   interface(REG_INTER);
  3068 %}
  3070 operand mT2RegI() %{
  3071   constraint(ALLOC_IN_RC(t2_reg));
  3072   match(RegI);
  3073   match(mRegI);
  3075   format %{ "T2" %}
  3076   interface(REG_INTER);
  3077 %}
  3079 operand mT3RegI() %{
  3080   constraint(ALLOC_IN_RC(t3_reg));
  3081   match(RegI);
  3082   match(mRegI);
  3084   format %{ "T3" %}
  3085   interface(REG_INTER);
  3086 %}
  3088 operand mT8RegI() %{
  3089   constraint(ALLOC_IN_RC(t8_reg));
  3090   match(RegI);
  3091   match(mRegI);
  3093   format %{ "T8" %}
  3094   interface(REG_INTER);
  3095 %}
  3097 operand mT9RegI() %{
  3098   constraint(ALLOC_IN_RC(t9_reg));
  3099   match(RegI);
  3100   match(mRegI);
  3102   format %{ "T9" %}
  3103   interface(REG_INTER);
  3104 %}
  3106 operand mA0RegI() %{
  3107   constraint(ALLOC_IN_RC(a0_reg));
  3108   match(RegI);
  3109   match(mRegI);
  3111   format %{ "A0" %}
  3112   interface(REG_INTER);
  3113 %}
  3115 operand mA1RegI() %{
  3116   constraint(ALLOC_IN_RC(a1_reg));
  3117   match(RegI);
  3118   match(mRegI);
  3120   format %{ "A1" %}
  3121   interface(REG_INTER);
  3122 %}
  3124 operand mA2RegI() %{
  3125   constraint(ALLOC_IN_RC(a2_reg));
  3126   match(RegI);
  3127   match(mRegI);
  3129   format %{ "A2" %}
  3130   interface(REG_INTER);
  3131 %}
  3133 operand mA3RegI() %{
  3134   constraint(ALLOC_IN_RC(a3_reg));
  3135   match(RegI);
  3136   match(mRegI);
  3138   format %{ "A3" %}
  3139   interface(REG_INTER);
  3140 %}
  3142 operand mA4RegI() %{
  3143   constraint(ALLOC_IN_RC(a4_reg));
  3144   match(RegI);
  3145   match(mRegI);
  3147   format %{ "A4" %}
  3148   interface(REG_INTER);
  3149 %}
  3151 operand mA5RegI() %{
  3152   constraint(ALLOC_IN_RC(a5_reg));
  3153   match(RegI);
  3154   match(mRegI);
  3156   format %{ "A5" %}
  3157   interface(REG_INTER);
  3158 %}
  3160 operand mA6RegI() %{
  3161   constraint(ALLOC_IN_RC(a6_reg));
  3162   match(RegI);
  3163   match(mRegI);
  3165   format %{ "A6" %}
  3166   interface(REG_INTER);
  3167 %}
  3169 operand mA7RegI() %{
  3170   constraint(ALLOC_IN_RC(a7_reg));
  3171   match(RegI);
  3172   match(mRegI);
  3174   format %{ "A7" %}
  3175   interface(REG_INTER);
  3176 %}
  3178 operand mV0RegI() %{
  3179   constraint(ALLOC_IN_RC(v0_reg));
  3180   match(RegI);
  3181   match(mRegI);
  3183   format %{ "V0" %}
  3184   interface(REG_INTER);
  3185 %}
  3187 operand mV1RegI() %{
  3188   constraint(ALLOC_IN_RC(v1_reg));
  3189   match(RegI);
  3190   match(mRegI);
  3192   format %{ "V1" %}
  3193   interface(REG_INTER);
  3194 %}
  3196 operand mRegN() %{
  3197   constraint(ALLOC_IN_RC(int_reg));
  3198   match(RegN);
  3200   format %{ %}
  3201   interface(REG_INTER);
  3202 %}
  3204 operand t0_RegN() %{
  3205   constraint(ALLOC_IN_RC(t0_reg));
  3206   match(RegN);
  3207   match(mRegN);
  3209   format %{ %}
  3210   interface(REG_INTER);
  3211 %}
  3213 operand t1_RegN() %{
  3214   constraint(ALLOC_IN_RC(t1_reg));
  3215   match(RegN);
  3216   match(mRegN);
  3218   format %{ %}
  3219   interface(REG_INTER);
  3220 %}
  3222 operand t2_RegN() %{
  3223   constraint(ALLOC_IN_RC(t2_reg));
  3224   match(RegN);
  3225   match(mRegN);
  3227   format %{ %}
  3228   interface(REG_INTER);
  3229 %}
  3231 operand t3_RegN() %{
  3232   constraint(ALLOC_IN_RC(t3_reg));
  3233   match(RegN);
  3234   match(mRegN);
  3236   format %{ %}
  3237   interface(REG_INTER);
  3238 %}
  3240 operand t8_RegN() %{
  3241   constraint(ALLOC_IN_RC(t8_reg));
  3242   match(RegN);
  3243   match(mRegN);
  3245   format %{ %}
  3246   interface(REG_INTER);
  3247 %}
  3249 operand t9_RegN() %{
  3250   constraint(ALLOC_IN_RC(t9_reg));
  3251   match(RegN);
  3252   match(mRegN);
  3254   format %{ %}
  3255   interface(REG_INTER);
  3256 %}
  3258 operand a0_RegN() %{
  3259   constraint(ALLOC_IN_RC(a0_reg));
  3260   match(RegN);
  3261   match(mRegN);
  3263   format %{ %}
  3264   interface(REG_INTER);
  3265 %}
  3267 operand a1_RegN() %{
  3268   constraint(ALLOC_IN_RC(a1_reg));
  3269   match(RegN);
  3270   match(mRegN);
  3272   format %{ %}
  3273   interface(REG_INTER);
  3274 %}
  3276 operand a2_RegN() %{
  3277   constraint(ALLOC_IN_RC(a2_reg));
  3278   match(RegN);
  3279   match(mRegN);
  3281   format %{ %}
  3282   interface(REG_INTER);
  3283 %}
  3285 operand a3_RegN() %{
  3286   constraint(ALLOC_IN_RC(a3_reg));
  3287   match(RegN);
  3288   match(mRegN);
  3290   format %{ %}
  3291   interface(REG_INTER);
  3292 %}
  3294 operand a4_RegN() %{
  3295   constraint(ALLOC_IN_RC(a4_reg));
  3296   match(RegN);
  3297   match(mRegN);
  3299   format %{ %}
  3300   interface(REG_INTER);
  3301 %}
  3303 operand a5_RegN() %{
  3304   constraint(ALLOC_IN_RC(a5_reg));
  3305   match(RegN);
  3306   match(mRegN);
  3308   format %{ %}
  3309   interface(REG_INTER);
  3310 %}
  3312 operand a6_RegN() %{
  3313   constraint(ALLOC_IN_RC(a6_reg));
  3314   match(RegN);
  3315   match(mRegN);
  3317   format %{ %}
  3318   interface(REG_INTER);
  3319 %}
  3321 operand a7_RegN() %{
  3322   constraint(ALLOC_IN_RC(a7_reg));
  3323   match(RegN);
  3324   match(mRegN);
  3326   format %{ %}
  3327   interface(REG_INTER);
  3328 %}
  3330 operand s0_RegN() %{
  3331   constraint(ALLOC_IN_RC(s0_reg));
  3332   match(RegN);
  3333   match(mRegN);
  3335   format %{ %}
  3336   interface(REG_INTER);
  3337 %}
  3339 operand s1_RegN() %{
  3340   constraint(ALLOC_IN_RC(s1_reg));
  3341   match(RegN);
  3342   match(mRegN);
  3344   format %{ %}
  3345   interface(REG_INTER);
  3346 %}
  3348 operand s2_RegN() %{
  3349   constraint(ALLOC_IN_RC(s2_reg));
  3350   match(RegN);
  3351   match(mRegN);
  3353   format %{ %}
  3354   interface(REG_INTER);
  3355 %}
  3357 operand s3_RegN() %{
  3358   constraint(ALLOC_IN_RC(s3_reg));
  3359   match(RegN);
  3360   match(mRegN);
  3362   format %{ %}
  3363   interface(REG_INTER);
  3364 %}
  3366 operand s4_RegN() %{
  3367   constraint(ALLOC_IN_RC(s4_reg));
  3368   match(RegN);
  3369   match(mRegN);
  3371   format %{ %}
  3372   interface(REG_INTER);
  3373 %}
  3375 operand s5_RegN() %{
  3376   constraint(ALLOC_IN_RC(s5_reg));
  3377   match(RegN);
  3378   match(mRegN);
  3380   format %{ %}
  3381   interface(REG_INTER);
  3382 %}
  3384 operand s6_RegN() %{
  3385   constraint(ALLOC_IN_RC(s6_reg));
  3386   match(RegN);
  3387   match(mRegN);
  3389   format %{ %}
  3390   interface(REG_INTER);
  3391 %}
  3393 operand s7_RegN() %{
  3394   constraint(ALLOC_IN_RC(s7_reg));
  3395   match(RegN);
  3396   match(mRegN);
  3398   format %{ %}
  3399   interface(REG_INTER);
  3400 %}
  3402 operand v0_RegN() %{
  3403   constraint(ALLOC_IN_RC(v0_reg));
  3404   match(RegN);
  3405   match(mRegN);
  3407   format %{ %}
  3408   interface(REG_INTER);
  3409 %}
  3411 operand v1_RegN() %{
  3412   constraint(ALLOC_IN_RC(v1_reg));
  3413   match(RegN);
  3414   match(mRegN);
  3416   format %{ %}
  3417   interface(REG_INTER);
  3418 %}
  3420 // Pointer Register
  3421 operand mRegP() %{
  3422   constraint(ALLOC_IN_RC(p_reg));
  3423   match(RegP);
  3425   format %{  %}
  3426   interface(REG_INTER);
  3427 %} 
  3429 operand no_T8_mRegP() %{
  3430   constraint(ALLOC_IN_RC(no_T8_p_reg));
  3431   match(RegP);
  3432   match(mRegP);
  3434   format %{  %}
  3435   interface(REG_INTER);
  3436 %} 
  3438 operand s0_RegP()
  3439 %{
  3440   constraint(ALLOC_IN_RC(s0_long_reg));
  3441   match(RegP);
  3442   match(mRegP);
  3443   match(no_T8_mRegP);
  3445   format %{ %}
  3446   interface(REG_INTER);
  3447 %}
  3449 operand s1_RegP()
  3450 %{
  3451   constraint(ALLOC_IN_RC(s1_long_reg));
  3452   match(RegP);
  3453   match(mRegP);
  3454   match(no_T8_mRegP);
  3456   format %{ %}
  3457   interface(REG_INTER);
  3458 %}
  3460 operand s2_RegP()
  3461 %{
  3462   constraint(ALLOC_IN_RC(s2_long_reg));
  3463   match(RegP);
  3464   match(mRegP);
  3465   match(no_T8_mRegP);
  3467   format %{ %}
  3468   interface(REG_INTER);
  3469 %}
  3471 operand s3_RegP()
  3472 %{
  3473   constraint(ALLOC_IN_RC(s3_long_reg));
  3474   match(RegP);
  3475   match(mRegP);
  3476   match(no_T8_mRegP);
  3478   format %{ %}
  3479   interface(REG_INTER);
  3480 %}
  3482 operand s4_RegP()
  3483 %{
  3484   constraint(ALLOC_IN_RC(s4_long_reg));
  3485   match(RegP);
  3486   match(mRegP);
  3487   match(no_T8_mRegP);
  3489   format %{ %}
  3490   interface(REG_INTER);
  3491 %}
  3493 operand s5_RegP()
  3494 %{
  3495   constraint(ALLOC_IN_RC(s5_long_reg));
  3496   match(RegP);
  3497   match(mRegP);
  3498   match(no_T8_mRegP);
  3500   format %{ %}
  3501   interface(REG_INTER);
  3502 %}
  3504 operand s6_RegP()
  3505 %{
  3506   constraint(ALLOC_IN_RC(s6_long_reg));
  3507   match(RegP);
  3508   match(mRegP);
  3509   match(no_T8_mRegP);
  3511   format %{ %}
  3512   interface(REG_INTER);
  3513 %}
  3515 operand s7_RegP()
  3516 %{
  3517   constraint(ALLOC_IN_RC(s7_long_reg));
  3518   match(RegP);
  3519   match(mRegP);
  3520   match(no_T8_mRegP);
  3522   format %{ %}
  3523   interface(REG_INTER);
  3524 %}
  3526 operand t0_RegP()
  3527 %{
  3528   constraint(ALLOC_IN_RC(t0_long_reg));
  3529   match(RegP);
  3530   match(mRegP);
  3531   match(no_T8_mRegP);
  3533   format %{ %}
  3534   interface(REG_INTER);
  3535 %}
  3537 operand t1_RegP()
  3538 %{
  3539   constraint(ALLOC_IN_RC(t1_long_reg));
  3540   match(RegP);
  3541   match(mRegP);
  3542   match(no_T8_mRegP);
  3544   format %{ %}
  3545   interface(REG_INTER);
  3546 %}
  3548 operand t2_RegP()
  3549 %{
  3550   constraint(ALLOC_IN_RC(t2_long_reg));
  3551   match(RegP);
  3552   match(mRegP);
  3553   match(no_T8_mRegP);
  3555   format %{ %}
  3556   interface(REG_INTER);
  3557 %}
  3559 operand t3_RegP()
  3560 %{
  3561   constraint(ALLOC_IN_RC(t3_long_reg));
  3562   match(RegP);
  3563   match(mRegP);
  3564   match(no_T8_mRegP);
  3566   format %{ %}
  3567   interface(REG_INTER);
  3568 %}
  3570 operand t8_RegP()
  3571 %{
  3572   constraint(ALLOC_IN_RC(t8_long_reg));
  3573   match(RegP);
  3574   match(mRegP);
  3576   format %{ %}
  3577   interface(REG_INTER);
  3578 %}
  3580 operand t9_RegP()
  3581 %{
  3582   constraint(ALLOC_IN_RC(t9_long_reg));
  3583   match(RegP);
  3584   match(mRegP);
  3585   match(no_T8_mRegP);
  3587   format %{ %}
  3588   interface(REG_INTER);
  3589 %}
  3591 operand a0_RegP()
  3592 %{
  3593   constraint(ALLOC_IN_RC(a0_long_reg));
  3594   match(RegP);
  3595   match(mRegP);
  3596   match(no_T8_mRegP);
  3598   format %{ %}
  3599   interface(REG_INTER);
  3600 %}
  3602 operand a1_RegP()
  3603 %{
  3604   constraint(ALLOC_IN_RC(a1_long_reg));
  3605   match(RegP);
  3606   match(mRegP);
  3607   match(no_T8_mRegP);
  3609   format %{ %}
  3610   interface(REG_INTER);
  3611 %}
  3613 operand a2_RegP()
  3614 %{
  3615   constraint(ALLOC_IN_RC(a2_long_reg));
  3616   match(RegP);
  3617   match(mRegP);
  3618   match(no_T8_mRegP);
  3620   format %{ %}
  3621   interface(REG_INTER);
  3622 %}
  3624 operand a3_RegP()
  3625 %{
  3626   constraint(ALLOC_IN_RC(a3_long_reg));
  3627   match(RegP);
  3628   match(mRegP);
  3629   match(no_T8_mRegP);
  3631   format %{ %}
  3632   interface(REG_INTER);
  3633 %}
  3635 operand a4_RegP()
  3636 %{
  3637   constraint(ALLOC_IN_RC(a4_long_reg));
  3638   match(RegP);
  3639   match(mRegP);
  3640   match(no_T8_mRegP);
  3642   format %{ %}
  3643   interface(REG_INTER);
  3644 %}
  3647 operand a5_RegP()
  3648 %{
  3649   constraint(ALLOC_IN_RC(a5_long_reg));
  3650   match(RegP);
  3651   match(mRegP);
  3652   match(no_T8_mRegP);
  3654   format %{ %}
  3655   interface(REG_INTER);
  3656 %}
  3658 operand a6_RegP()
  3659 %{
  3660   constraint(ALLOC_IN_RC(a6_long_reg));
  3661   match(RegP);
  3662   match(mRegP);
  3663   match(no_T8_mRegP);
  3665   format %{ %}
  3666   interface(REG_INTER);
  3667 %}
  3669 operand a7_RegP()
  3670 %{
  3671   constraint(ALLOC_IN_RC(a7_long_reg));
  3672   match(RegP);
  3673   match(mRegP);
  3674   match(no_T8_mRegP);
  3676   format %{ %}
  3677   interface(REG_INTER);
  3678 %}
  3680 operand v0_RegP()
  3681 %{
  3682   constraint(ALLOC_IN_RC(v0_long_reg));
  3683   match(RegP);
  3684   match(mRegP);
  3685   match(no_T8_mRegP);
  3687   format %{ %}
  3688   interface(REG_INTER);
  3689 %}
  3691 operand v1_RegP()
  3692 %{
  3693   constraint(ALLOC_IN_RC(v1_long_reg));
  3694   match(RegP);
  3695   match(mRegP);
  3696   match(no_T8_mRegP);
  3698   format %{ %}
  3699   interface(REG_INTER);
  3700 %}
  3702 /*
  3703 operand mSPRegP(mRegP reg) %{
  3704   constraint(ALLOC_IN_RC(sp_reg));
  3705   match(reg);
  3707   format %{ "SP"  %}
  3708   interface(REG_INTER);
  3709 %}
  3711 operand mFPRegP(mRegP reg) %{
  3712   constraint(ALLOC_IN_RC(fp_reg));
  3713   match(reg);
  3715   format %{ "FP"  %}
  3716   interface(REG_INTER);
  3717 %}
  3718 */
  3720 operand mRegL() %{
  3721   constraint(ALLOC_IN_RC(long_reg));
  3722   match(RegL);
  3724   format %{ %}
  3725   interface(REG_INTER);
  3726 %}
  3728 operand v0RegL() %{
  3729   constraint(ALLOC_IN_RC(v0_long_reg));
  3730   match(RegL);
  3731   match(mRegL);
  3733   format %{ %}
  3734   interface(REG_INTER);
  3735 %}
  3737 operand v1RegL() %{
  3738   constraint(ALLOC_IN_RC(v1_long_reg));
  3739   match(RegL);
  3740   match(mRegL);
  3742   format %{ %}
  3743   interface(REG_INTER);
  3744 %}
  3746 operand a0RegL() %{
  3747   constraint(ALLOC_IN_RC(a0_long_reg));
  3748   match(RegL);
  3749   match(mRegL);
  3751   format %{ "A0" %}
  3752   interface(REG_INTER);
  3753 %}
  3755 operand a1RegL() %{
  3756   constraint(ALLOC_IN_RC(a1_long_reg));
  3757   match(RegL);
  3758   match(mRegL);
  3760   format %{ %}
  3761   interface(REG_INTER);
  3762 %}
  3764 operand a2RegL() %{
  3765   constraint(ALLOC_IN_RC(a2_long_reg));
  3766   match(RegL);
  3767   match(mRegL);
  3769   format %{ %}
  3770   interface(REG_INTER);
  3771 %}
  3773 operand a3RegL() %{
  3774   constraint(ALLOC_IN_RC(a3_long_reg));
  3775   match(RegL);
  3776   match(mRegL);
  3778   format %{ %}
  3779   interface(REG_INTER);
  3780 %}
  3782 operand t0RegL() %{
  3783   constraint(ALLOC_IN_RC(t0_long_reg));
  3784   match(RegL);
  3785   match(mRegL);
  3787   format %{ %}
  3788   interface(REG_INTER);
  3789 %}
  3791 operand t1RegL() %{
  3792   constraint(ALLOC_IN_RC(t1_long_reg));
  3793   match(RegL);
  3794   match(mRegL);
  3796   format %{ %}
  3797   interface(REG_INTER);
  3798 %}
  3800 operand t2RegL() %{
  3801   constraint(ALLOC_IN_RC(t2_long_reg));
  3802   match(RegL);
  3803   match(mRegL);
  3805   format %{ %}
  3806   interface(REG_INTER);
  3807 %}
  3809 operand t3RegL() %{
  3810   constraint(ALLOC_IN_RC(t3_long_reg));
  3811   match(RegL);
  3812   match(mRegL);
  3814   format %{ %}
  3815   interface(REG_INTER);
  3816 %}
  3818 operand t8RegL() %{
  3819   constraint(ALLOC_IN_RC(t8_long_reg));
  3820   match(RegL);
  3821   match(mRegL);
  3823   format %{ %}
  3824   interface(REG_INTER);
  3825 %}
  3827 operand a4RegL() %{
  3828   constraint(ALLOC_IN_RC(a4_long_reg));
  3829   match(RegL);
  3830   match(mRegL);
  3832   format %{ %}
  3833   interface(REG_INTER);
  3834 %}
  3836 operand a5RegL() %{
  3837   constraint(ALLOC_IN_RC(a5_long_reg));
  3838   match(RegL);
  3839   match(mRegL);
  3841   format %{ %}
  3842   interface(REG_INTER);
  3843 %}
  3845 operand a6RegL() %{
  3846   constraint(ALLOC_IN_RC(a6_long_reg));
  3847   match(RegL);
  3848   match(mRegL);
  3850   format %{ %}
  3851   interface(REG_INTER);
  3852 %}
  3854 operand a7RegL() %{
  3855   constraint(ALLOC_IN_RC(a7_long_reg));
  3856   match(RegL);
  3857   match(mRegL);
  3859   format %{ %}
  3860   interface(REG_INTER);
  3861 %}
  3863 operand s0RegL() %{
  3864   constraint(ALLOC_IN_RC(s0_long_reg));
  3865   match(RegL);
  3866   match(mRegL);
  3868   format %{ %}
  3869   interface(REG_INTER);
  3870 %}
  3872 operand s1RegL() %{
  3873   constraint(ALLOC_IN_RC(s1_long_reg));
  3874   match(RegL);
  3875   match(mRegL);
  3877   format %{ %}
  3878   interface(REG_INTER);
  3879 %}
  3881 operand s2RegL() %{
  3882   constraint(ALLOC_IN_RC(s2_long_reg));
  3883   match(RegL);
  3884   match(mRegL);
  3886   format %{ %}
  3887   interface(REG_INTER);
  3888 %}
  3890 operand s3RegL() %{
  3891   constraint(ALLOC_IN_RC(s3_long_reg));
  3892   match(RegL);
  3893   match(mRegL);
  3895   format %{ %}
  3896   interface(REG_INTER);
  3897 %}
  3899 operand s4RegL() %{
  3900   constraint(ALLOC_IN_RC(s4_long_reg));
  3901   match(RegL);
  3902   match(mRegL);
  3904   format %{ %}
  3905   interface(REG_INTER);
  3906 %}
  3908 operand s7RegL() %{
  3909   constraint(ALLOC_IN_RC(s7_long_reg));
  3910   match(RegL);
  3911   match(mRegL);
  3913   format %{ %}
  3914   interface(REG_INTER);
  3915 %}
  3917 // Floating register operands
  3918 operand regF() %{
  3919   constraint(ALLOC_IN_RC(flt_reg));
  3920   match(RegF);
  3922   format %{ %}
  3923   interface(REG_INTER);
  3924 %}
  3926 //Double Precision Floating register operands
  3927 operand regD() %{
  3928   constraint(ALLOC_IN_RC(dbl_reg));
  3929   match(RegD);
  3931   format %{ %}
  3932   interface(REG_INTER);
  3933 %}
  3935 //----------Memory Operands----------------------------------------------------
  3936 operand baseOffset16(mRegP reg, immL16 off)
  3937 %{
  3938   constraint(ALLOC_IN_RC(p_reg));
  3939   match(AddP reg off);
  3941   op_cost(5);
  3942   format %{ "[$reg + $off (16-bit)] @ baseOffset16" %}
  3943   interface(MEMORY_INTER) %{
  3944     base($reg);
  3945     index(0x0);
  3946     scale(0x0);
  3947     disp($off);
  3948   %}
  3949 %}
  3951 operand gsBaseIndexOffset8(mRegP base, mRegL index, immL8 off)
  3952 %{
  3953   predicate(UseLoongsonISA);
  3954   constraint(ALLOC_IN_RC(p_reg));
  3955   match(AddP (AddP base index) off);
  3957   op_cost(5);
  3958   format %{ "[$base + $index + $off (8-bit)] @ gsBaseIndexOffset8" %}
  3959   interface(MEMORY_INTER) %{
  3960     base($base);
  3961     index($index);
  3962     scale(0x0);
  3963     disp($off);
  3964   %}
  3965 %}
  3967 operand gsBaseIndexI2LOffset8(mRegP base, mRegI index, immL8 off)
  3968 %{
  3969   predicate(UseLoongsonISA);
  3970   constraint(ALLOC_IN_RC(p_reg));
  3971   match(AddP (AddP base (ConvI2L index)) off);
  3973   op_cost(5);
  3974   format %{ "[$base + $index + $off (8-bit)] @ gsBaseIndexI2LOffset8" %}
  3975   interface(MEMORY_INTER) %{
  3976     base($base);
  3977     index($index);
  3978     scale(0x0);
  3979     disp($off);
  3980   %}
  3981 %}
  3983 operand gsBaseIndexOffset0(mRegP addr, mRegL index) %{
  3984   predicate(UseLoongsonISA);
  3985   constraint(ALLOC_IN_RC(p_reg));
  3986   match(AddP addr index);
  3988   op_cost(10);
  3989   format %{"[$addr + $index] @ gsBaseIndexOffset0" %}
  3990   interface(MEMORY_INTER) %{
  3991     base($addr);
  3992     index($index);
  3993     scale(0x0);
  3994     disp(0x0);
  3995   %}
  3996 %}
  3998 operand baseOffset0(mRegP reg) %{
  3999   constraint(ALLOC_IN_RC(p_reg));
  4000   op_cost(10);
  4001   match(reg);
  4003   format %{ "[$reg] @ baseOffset0" %}
  4004   interface(MEMORY_INTER) %{
  4005     base($reg);
  4006     index(0x0);
  4007     scale(0x0);
  4008     disp(0x0);
  4009   %}
  4010 %}
  4012 operand baseOffset16Narrow(mRegN reg, immL16 off)
  4013 %{
  4014   predicate(Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
  4015   constraint(ALLOC_IN_RC(p_reg));
  4016   match(AddP (DecodeN reg) off);
  4018   op_cost(5);
  4019   format %{ "[$reg + $off (16-bit)] @ baseOffset16Narrow" %}
  4020   interface(MEMORY_INTER) %{
  4021     base($reg);
  4022     index(0x0);
  4023     scale(0x0);
  4024     disp($off);
  4025   %}
  4026 %}
  4028 operand gsBaseIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
  4029 %{
  4030   predicate(UseLoongsonISA && Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
  4031   constraint(ALLOC_IN_RC(p_reg));
  4032   match(AddP (AddP (DecodeN reg) lreg) off);
  4034   op_cost(5);
  4035   format %{"[$reg + $off + $lreg] @ gsBaseIndexOffset8Narrow" %}
  4036   interface(MEMORY_INTER) %{
  4037     base($reg);
  4038     index($lreg);
  4039     scale(0x0);
  4040     disp($off);
  4041   %}
  4042 %}
  4044 operand baseOffset0Narrow(mRegN reg)
  4045 %{
  4046   predicate(Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
  4047   constraint(ALLOC_IN_RC(p_reg));
  4048   match(DecodeN reg);
  4050   op_cost(10);
  4051   format %{ "[$reg] @ baseOffset0Narrow" %}
  4052   interface(MEMORY_INTER) %{
  4053     base($reg);
  4054     index(0x0);
  4055     scale(0x0);
  4056     disp(0x0);
  4057   %}
  4058 %}
  4060 operand baseOffset16NarrowKlass(mRegN reg, immL16 off)
  4061 %{
  4062   predicate(Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
  4063   constraint(ALLOC_IN_RC(p_reg));
  4064   match(AddP (DecodeNKlass reg) off);
  4066   op_cost(5);
  4067   format %{ "[$reg + $off (16-bit)] @ baseOffset16NarrowKlass" %}
  4068   interface(MEMORY_INTER) %{
  4069     base($reg);
  4070     index(0x0);
  4071     scale(0x0);
  4072     disp($off);
  4073   %}
  4074 %}
  4076 operand baseOffset0NarrowKlass(mRegN reg)
  4077 %{
  4078   predicate(Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
  4079   constraint(ALLOC_IN_RC(p_reg));
  4080   match(DecodeNKlass reg);
  4082   op_cost(10);
  4083   format %{ "[$reg] @ baseOffset0NarrowKlass" %}
  4084   interface(MEMORY_INTER) %{
  4085     base($reg);
  4086     index(0x0);
  4087     scale(0x0);
  4088     disp(0x0);
  4089   %}
  4090 %}
  4092 operand gsBaseIndexOffset8NarrowKlass(mRegN reg, mRegL lreg, immL8 off)
  4093 %{
  4094   predicate(UseLoongsonISA && Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
  4095   constraint(ALLOC_IN_RC(p_reg));
  4096   match(AddP (AddP (DecodeNKlass reg) lreg) off);
  4098   op_cost(5);
  4099   format %{"[$reg + $off + $lreg] @ gsBaseIndexOffset8NarrowKlass" %}
  4100   interface(MEMORY_INTER) %{
  4101     base($reg);
  4102     index($lreg);
  4103     scale(0x0);
  4104     disp($off);
  4105   %}
  4106 %}
  4108 operand gsBaseIndexOffset0NarrowKlass(mRegN reg, mRegL lreg)
  4109 %{
  4110   predicate(UseLoongsonISA && Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
  4111   constraint(ALLOC_IN_RC(p_reg));
  4112   match(AddP (DecodeNKlass reg) lreg);
  4114   op_cost(10);
  4115   format %{"[$reg + $lreg] @ gsBaseIndexOffset0NarrowKlass" %}
  4116   interface(MEMORY_INTER) %{
  4117     base($reg);
  4118     index($lreg);
  4119     scale(0x0);
  4120     disp(0x0);
  4121   %}
  4122 %}
  4125 //------------------------OPERAND CLASSES--------------------------------------
  4126 opclass memory(
  4127   baseOffset16,
  4128   gsBaseIndexOffset8,
  4129   gsBaseIndexI2LOffset8,
  4130   gsBaseIndexOffset0,
  4131   baseOffset0,
  4133   baseOffset16Narrow,
  4134   gsBaseIndexOffset8Narrow,
  4135   baseOffset0Narrow,
  4137   baseOffset16NarrowKlass,
  4138   baseOffset0NarrowKlass,
  4139   gsBaseIndexOffset8NarrowKlass,
  4140   gsBaseIndexOffset0NarrowKlass
  4141 );
  4143 // For loading unsigned values
  4144 // umemory --> unsigned memory
  4145 opclass umemory(
  4146   baseOffset16,
  4147   baseOffset0,
  4149   baseOffset16Narrow,
  4150   baseOffset0Narrow,
  4152   baseOffset16NarrowKlass,
  4153   baseOffset0NarrowKlass
  4154 );
  4157 //----------Conditional Branch Operands----------------------------------------
  4158 // Comparison Op  - This is the operation of the comparison, and is limited to
  4159 //                  the following set of codes:
  4160 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
  4161 //
  4162 // Other attributes of the comparison, such as unsignedness, are specified
  4163 // by the comparison instruction that sets a condition code flags register.
  4164 // That result is represented by a flags operand whose subtype is appropriate
  4165 // to the unsignedness (etc.) of the comparison.
  4166 //
  4167 // Later, the instruction which matches both the Comparison Op (a Bool) and
  4168 // the flags (produced by the Cmp) specifies the coding of the comparison op
  4169 // by matching a specific subtype of Bool operand below, such as cmpOpU.
  4171 // Comparision Code
  4172 operand cmpOp() %{
  4173   match(Bool);
  4175   format %{ "" %}
  4176   interface(COND_INTER) %{
  4177     equal(0x01);
  4178     not_equal(0x02);
  4179     greater(0x03);
  4180     greater_equal(0x04);
  4181     less(0x05);
  4182     less_equal(0x06);
  4183     overflow(0x7);
  4184     no_overflow(0x8);
  4185   %}
  4186 %}
  4189 // Comparision Code
  4190 // Comparison Code, unsigned compare.  Used by FP also, with
  4191 // C2 (unordered) turned into GT or LT already.  The other bits
  4192 // C0 and C3 are turned into Carry & Zero flags.
  4193 operand cmpOpU() %{
  4194   match(Bool);
  4196   format %{ "" %}
  4197   interface(COND_INTER) %{
  4198     equal(0x01);
  4199     not_equal(0x02);
  4200     greater(0x03);
  4201     greater_equal(0x04);
  4202     less(0x05);
  4203     less_equal(0x06);
  4204     overflow(0x7);
  4205     no_overflow(0x8);
  4206   %}
  4207 %}
  4210 //----------Special Memory Operands--------------------------------------------
  4211 // Stack Slot Operand - This operand is used for loading and storing temporary
  4212 //                      values on the stack where a match requires a value to
  4213 //                      flow through memory.
  4214 operand stackSlotP(sRegP reg) %{
  4215   constraint(ALLOC_IN_RC(stack_slots));
  4216   // No match rule because this operand is only generated in matching
  4217   op_cost(50);
  4218   format %{ "[$reg]" %}
  4219   interface(MEMORY_INTER) %{
  4220     base(0x1d);  // SP
  4221     index(0x0);  // No Index
  4222     scale(0x0);  // No Scale
  4223     disp($reg);  // Stack Offset
  4224   %}
  4225 %}
  4227 operand stackSlotI(sRegI reg) %{
  4228   constraint(ALLOC_IN_RC(stack_slots));
  4229   // No match rule because this operand is only generated in matching
  4230   op_cost(50);
  4231   format %{ "[$reg]" %}
  4232   interface(MEMORY_INTER) %{
  4233     base(0x1d);  // SP
  4234     index(0x0);  // No Index
  4235     scale(0x0);  // No Scale
  4236     disp($reg);  // Stack Offset
  4237   %}
  4238 %}
  4240 operand stackSlotF(sRegF reg) %{
  4241   constraint(ALLOC_IN_RC(stack_slots));
  4242   // No match rule because this operand is only generated in matching
  4243   op_cost(50);
  4244   format %{ "[$reg]" %}
  4245   interface(MEMORY_INTER) %{
  4246     base(0x1d);  // SP
  4247     index(0x0);  // No Index
  4248     scale(0x0);  // No Scale
  4249     disp($reg);  // Stack Offset
  4250   %}
  4251 %}
  4253 operand stackSlotD(sRegD reg) %{
  4254   constraint(ALLOC_IN_RC(stack_slots));
  4255   // No match rule because this operand is only generated in matching
  4256   op_cost(50);
  4257   format %{ "[$reg]" %}
  4258   interface(MEMORY_INTER) %{
  4259     base(0x1d);  // SP
  4260     index(0x0);  // No Index
  4261     scale(0x0);  // No Scale
  4262     disp($reg);  // Stack Offset
  4263   %}
  4264 %}
  4266 operand stackSlotL(sRegL reg) %{
  4267   constraint(ALLOC_IN_RC(stack_slots));
  4268   // No match rule because this operand is only generated in matching
  4269   op_cost(50);
  4270   format %{ "[$reg]" %}
  4271   interface(MEMORY_INTER) %{
  4272     base(0x1d);  // SP
  4273     index(0x0);  // No Index
  4274     scale(0x0);  // No Scale
  4275     disp($reg);  // Stack Offset
  4276   %}
  4277 %}
  4279 //----------PIPELINE-----------------------------------------------------------
  4280 // Rules which define the behavior of the target architectures pipeline.
  4282 pipeline %{
  4284 //----------ATTRIBUTES---------------------------------------------------------
  4285 attributes %{
  4286  	fixed_size_instructions;        	// Fixed size instructions
  4287  	branch_has_delay_slot;			// branch have delay slot in gs2
  4288  	max_instructions_per_bundle = 1;   	// 1 instruction per bundle
  4289  	max_bundles_per_cycle = 4;       	// Up to 4 bundles per cycle
  4290         bundle_unit_size=4;
  4291  	instruction_unit_size = 4;         	// An instruction is 4 bytes long
  4292  	instruction_fetch_unit_size = 16;  	// The processor fetches one line
  4293  	instruction_fetch_units = 1;       	// of 16 bytes
  4295  	// List of nop instructions
  4296  	nops( MachNop );
  4297  %}
  4299  //----------RESOURCES----------------------------------------------------------
  4300  // Resources are the functional units available to the machine
  4302  resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4,  ALU1, ALU2,  ALU = ALU1 | ALU2,  FPU1, FPU2, FPU = FPU1 | FPU2,  MEM,  BR); 
  4304  //----------PIPELINE DESCRIPTION-----------------------------------------------
  4305  // Pipeline Description specifies the stages in the machine's pipeline
  4307  // IF: fetch
  4308  // ID: decode
  4309  // RD: read 
  4310  // CA: caculate 
  4311  // WB: write back 
  4312  // CM: commit 
  4314  pipe_desc(IF, ID, RD, CA, WB, CM);
  4317  //----------PIPELINE CLASSES---------------------------------------------------
  4318  // Pipeline Classes describe the stages in which input and output are
  4319  // referenced by the hardware pipeline.
  4321  //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2  
  4322  pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
  4323         single_instruction;
  4324  	src1   : RD(read);
  4325  	src2   : RD(read);
  4326         dst    : WB(write)+1;
  4327         DECODE : ID;
  4328  	ALU    : CA;
  4329  %}
  4331  //No.19 Integer mult operation : dst <-- reg1 mult reg2  
  4332  pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
  4333  	src1   : RD(read);
  4334  	src2   : RD(read);
  4335         dst    : WB(write)+5;
  4336         DECODE : ID;
  4337  	ALU2   : CA;
  4338  %}
  4340  pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  4341  	src1   : RD(read);
  4342  	src2   : RD(read);
  4343         dst    : WB(write)+10;
  4344         DECODE : ID;
  4345  	ALU2   : CA;
  4346  %}
  4348  //No.19 Integer div operation : dst <-- reg1 div reg2  
  4349  pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
  4350  	src1   : RD(read);
  4351  	src2   : RD(read);
  4352         dst    : WB(write)+10;
  4353         DECODE : ID;
  4354  	ALU2   : CA;
  4355  %}
  4357  //No.19 Integer mod operation : dst <-- reg1 mod reg2  
  4358  pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
  4359         instruction_count(2);
  4360  	src1   : RD(read);
  4361  	src2   : RD(read);
  4362         dst    : WB(write)+10;
  4363         DECODE : ID;
  4364  	ALU2   : CA;
  4365  %}
  4367  //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2  
  4368  pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
  4369         instruction_count(2);
  4370  	src1   : RD(read);
  4371  	src2   : RD(read);
  4372         dst    : WB(write);
  4373         DECODE : ID;
  4374  	ALU    : CA;
  4375  %}
  4377  //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16 
  4378  pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
  4379         instruction_count(2);
  4380  	src    : RD(read);
  4381         dst    : WB(write);
  4382         DECODE : ID;
  4383  	ALU    : CA;
  4384  %}
  4386  //no.16 load Long from memory :                     
  4387  pipe_class ialu_loadL(mRegL dst, memory mem) %{
  4388  	instruction_count(2);
  4389  	mem    : RD(read);
  4390  	dst    : WB(write)+5;
  4391         DECODE : ID;
  4392  	MEM    : RD;
  4393  %}
  4395  //No.17 Store Long to Memory :                     
  4396  pipe_class ialu_storeL(mRegL src, memory mem) %{
  4397  	instruction_count(2);
  4398  	mem    : RD(read);
  4399  	src    : RD(read);
  4400         DECODE : ID;
  4401  	MEM    : RD;
  4402  %}
  4404  //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16  
  4405  pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
  4406         single_instruction;
  4407  	src    : RD(read);
  4408         dst    : WB(write);
  4409         DECODE : ID;
  4410  	ALU    : CA;
  4411  %}
  4413  //No.3 Integer move operation : dst <-- reg  
  4414  pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
  4415  	src    : RD(read);
  4416         dst    : WB(write);
  4417         DECODE : ID;
  4418  	ALU    : CA;
  4419  %}
  4421  //No.4 No instructions : do nothing 
  4422  pipe_class empty( ) %{
  4423         instruction_count(0);
  4424  %}
  4426  //No.5 UnConditional branch :
  4427  pipe_class pipe_jump( label labl ) %{
  4428         multiple_bundles;
  4429         DECODE : ID;
  4430 	BR     : RD;
  4431  %}
  4433  //No.6 ALU Conditional branch :
  4434  pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
  4435         multiple_bundles;
  4436         src1   : RD(read);
  4437         src2   : RD(read);
  4438         DECODE : ID;
  4439 	BR     : RD;
  4440  %}
  4442  //no.7 load integer from memory :                     
  4443  pipe_class ialu_loadI(mRegI dst, memory mem) %{
  4444  	mem    : RD(read);
  4445  	dst    : WB(write)+3;
  4446         DECODE : ID;
  4447  	MEM    : RD;
  4448  %}
  4450  //No.8 Store Integer to Memory :                     
  4451  pipe_class ialu_storeI(mRegI src, memory mem) %{
  4452  	mem    : RD(read);
  4453  	src    : RD(read);
  4454         DECODE : ID;
  4455  	MEM    : RD;
  4456  %}
  4459  //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2  
  4460  pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
  4461  	src1   : RD(read);
  4462  	src2   : RD(read);
  4463         dst    : WB(write);
  4464         DECODE : ID;
  4465  	FPU    : CA;
  4466  %}
  4468  //No.22 Floating div operation : dst <-- reg1 div reg2  
  4469  pipe_class fpu_div(regF dst, regF src1, regF src2) %{
  4470  	src1   : RD(read);
  4471  	src2   : RD(read);
  4472         dst    : WB(write);
  4473         DECODE : ID;
  4474  	FPU2   : CA;
  4475  %}
  4477  pipe_class fcvt_I2D(regD dst, mRegI src) %{
  4478  	src    : RD(read);
  4479         dst    : WB(write);
  4480         DECODE : ID;
  4481  	FPU1   : CA;
  4482  %}
  4484  pipe_class fcvt_D2I(mRegI dst, regD src) %{
  4485  	src    : RD(read);
  4486         dst    : WB(write);
  4487         DECODE : ID;
  4488  	FPU1   : CA;
  4489  %}
  4491  pipe_class pipe_mfc1(mRegI dst, regD src) %{
  4492  	src    : RD(read);
  4493         dst    : WB(write);
  4494         DECODE : ID;
  4495  	MEM    : RD;
  4496  %}
  4498  pipe_class pipe_mtc1(regD dst, mRegI src) %{
  4499  	src    : RD(read);
  4500         dst    : WB(write);
  4501         DECODE : ID;
  4502  	MEM    : RD(5);
  4503  %}
  4505  //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2  
  4506  pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
  4507         multiple_bundles;
  4508  	src1   : RD(read);
  4509  	src2   : RD(read);
  4510         dst    : WB(write);
  4511         DECODE : ID;
  4512  	FPU2   : CA;
  4513  %}
  4515  //No.11 Load Floating from Memory :                     
  4516  pipe_class fpu_loadF(regF dst, memory mem) %{
  4517         instruction_count(1);
  4518  	mem    : RD(read);
  4519  	dst    : WB(write)+3;
  4520         DECODE : ID;
  4521  	MEM    : RD;
  4522  %}
  4524  //No.12 Store Floating to Memory :                     
  4525  pipe_class fpu_storeF(regF src, memory mem) %{
  4526         instruction_count(1);
  4527  	mem    : RD(read);
  4528  	src    : RD(read);
  4529         DECODE : ID;
  4530  	MEM    : RD;
  4531  %}
  4533  //No.13 FPU Conditional branch :
  4534  pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
  4535         multiple_bundles;
  4536         src1   : RD(read);
  4537         src2   : RD(read);
  4538         DECODE : ID;
  4539 	BR     : RD;
  4540  %}
  4542 //No.14 Floating FPU reg operation : dst <-- op reg  
  4543  pipe_class fpu1_regF(regF dst, regF src) %{
  4544  	src    : RD(read);
  4545         dst    : WB(write);
  4546         DECODE : ID;
  4547  	FPU    : CA;
  4548  %}
  4550  pipe_class long_memory_op() %{
  4551 	instruction_count(10); multiple_bundles; force_serialization;
  4552 	fixed_latency(30);
  4553  %}
  4555  pipe_class simple_call() %{
  4556 	instruction_count(10); multiple_bundles; force_serialization;
  4557 	fixed_latency(200);
  4558 	BR     : RD;
  4559  %}
  4561  pipe_class call() %{
  4562 	instruction_count(10); multiple_bundles; force_serialization;
  4563 	fixed_latency(200);
  4564  %}
  4566  //FIXME:
  4567  //No.9 Piple slow : for multi-instructions 
  4568  pipe_class pipe_slow(  ) %{
  4569 	instruction_count(20);
  4570         force_serialization;
  4571         multiple_bundles;
  4572 	fixed_latency(50);
  4573  %}
  4575 %}
  4579 //----------INSTRUCTIONS-------------------------------------------------------
  4580 // 
  4581 // match      -- States which machine-independent subtree may be replaced 
  4582 //               by this instruction.
  4583 // ins_cost   -- The estimated cost of this instruction is used by instruction
  4584 //               selection to identify a minimum cost tree of machine 
  4585 //               instructions that matches a tree of machine-independent 
  4586 //               instructions.
  4587 // format     -- A string providing the disassembly for this instruction.
  4588 //               The value of an instruction's operand may be inserted 
  4589 //               by referring to it with a '$' prefix.
  4590 // opcode     -- Three instruction opcodes may be provided.  These are referred 
  4591 //               to within an encode class as $primary, $secondary, and $tertiary
  4592 //               respectively.  The primary opcode is commonly used to 
  4593 //               indicate the type of machine instruction, while secondary 
  4594 //               and tertiary are often used for prefix options or addressing 
  4595 //               modes.
  4596 // ins_encode -- A list of encode classes with parameters. The encode class
  4597 //               name must have been defined in an 'enc_class' specification
  4598 //               in the encode section of the architecture description.
  4601 // Load Integer
  4602 instruct loadI(mRegI dst, memory mem) %{
  4603   match(Set dst (LoadI mem));
  4605   ins_cost(125);
  4606   format %{ "lw    $dst, $mem 	#@loadI" %}
  4607   ins_encode (load_I_enc(dst, mem));
  4608   ins_pipe( ialu_loadI );
  4609 %}
  4611 instruct loadI_convI2L(mRegL dst, memory mem) %{
  4612   match(Set dst (ConvI2L (LoadI mem)));
  4614   ins_cost(125);
  4615   format %{ "lw    $dst, $mem 	#@loadI_convI2L" %}
  4616   ins_encode (load_I_enc(dst, mem));
  4617   ins_pipe( ialu_loadI );
  4618 %}
  4620 // Load Integer (32 bit signed) to Byte (8 bit signed)
  4621 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  4622   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
  4624   ins_cost(125);
  4625   format %{ "lb  $dst, $mem\t# int -> byte #@loadI2B" %}
  4626   ins_encode(load_B_enc(dst, mem));
  4627   ins_pipe(ialu_loadI);
  4628 %}
  4630 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
  4631 instruct loadI2UB(mRegI dst, umemory mem, immI_255 mask) %{
  4632   match(Set dst (AndI (LoadI mem) mask));
  4634   ins_cost(125);
  4635   format %{ "lbu  $dst, $mem\t# int -> ubyte #@loadI2UB" %}
  4636   ins_encode(load_UB_enc(dst, mem));
  4637   ins_pipe(ialu_loadI);
  4638 %}
  4640 // Load Integer (32 bit signed) to Short (16 bit signed)
  4641 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
  4642   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
  4644   ins_cost(125);
  4645   format %{ "lh  $dst, $mem\t# int -> short #@loadI2S" %}
  4646   ins_encode(load_S_enc(dst, mem));
  4647   ins_pipe(ialu_loadI);
  4648 %}
  4650 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
  4651 instruct loadI2US(mRegI dst, umemory mem, immI_65535 mask) %{
  4652   match(Set dst (AndI (LoadI mem) mask));
  4654   ins_cost(125);
  4655   format %{ "lhu  $dst, $mem\t# int -> ushort/char #@loadI2US" %}
  4656   ins_encode(load_C_enc(dst, mem));
  4657   ins_pipe(ialu_loadI);
  4658 %}
  4660 // Load Long.
  4661 instruct loadL(mRegL dst, memory mem) %{
  4662 //  predicate(!((LoadLNode*)n)->require_atomic_access());
  4663   match(Set dst (LoadL mem));
  4665   ins_cost(250);
  4666   format %{ "ld    $dst, $mem   #@loadL" %}
  4667   ins_encode(load_L_enc(dst, mem));
  4668   ins_pipe( ialu_loadL );
  4669 %}
  4671 // Load Long - UNaligned
  4672 instruct loadL_unaligned(mRegL dst, memory mem) %{
  4673   match(Set dst (LoadL_unaligned mem));
  4675   // FIXME: Jin: Need more effective ldl/ldr
  4676   ins_cost(450);
  4677   format %{ "ld    $dst, $mem   #@loadL_unaligned\n\t" %}
  4678   ins_encode(load_L_enc(dst, mem));
  4679   ins_pipe( ialu_loadL );
  4680 %}
  4682 // Store Long
  4683 instruct storeL_reg(memory mem, mRegL src) %{
  4684   match(Set mem (StoreL mem src));
  4686   ins_cost(200);
  4687   format %{ "sd    $mem,   $src #@storeL_reg\n" %}
  4688   ins_encode(store_L_reg_enc(mem, src));
  4689   ins_pipe( ialu_storeL );
  4690 %}
  4693 instruct storeL_immL0(memory mem, immL0 zero) %{
  4694   match(Set mem (StoreL mem zero));
  4696   ins_cost(180);
  4697   format %{ "sd    $mem,   zero #@storeL_immL0" %}
  4698   ins_encode(store_L_immL0_enc(mem));
  4699   ins_pipe( ialu_storeL );
  4700 %}
  4702 // Load Compressed Pointer
  4703 instruct loadN(mRegN dst, umemory mem)
  4704 %{
  4705    match(Set dst (LoadN mem));
  4707    ins_cost(125); // XXX
  4708    format %{ "lwu    $dst, $mem\t# compressed ptr @ loadN" %}
  4709    ins_encode (load_N_enc(dst, mem));
  4710    ins_pipe( ialu_loadI ); // XXX
  4711 %}
  4713 instruct loadN2P(mRegP dst, umemory mem)
  4714 %{
  4715    match(Set dst (DecodeN (LoadN mem)));
  4716    predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  4718    ins_cost(125); // XXX
  4719    format %{ "lwu    $dst, $mem\t# @ loadN2P" %}
  4720    ins_encode (load_N_enc(dst, mem));
  4721    ins_pipe( ialu_loadI ); // XXX
  4722 %}
  4724 // Load Pointer
  4725 instruct loadP(mRegP dst, memory mem) %{
  4726   match(Set dst (LoadP mem));
  4728   ins_cost(125);
  4729   format %{ "ld    $dst, $mem #@loadP" %}
  4730   ins_encode (load_P_enc(dst, mem));
  4731   ins_pipe( ialu_loadI );
  4732 %}
  4734 // Load Klass Pointer
  4735 instruct loadKlass(mRegP dst, memory mem) %{
  4736   match(Set dst (LoadKlass mem));
  4738   ins_cost(125);
  4739   format %{ "MOV    $dst,$mem @ loadKlass" %}
  4740   ins_encode (load_P_enc(dst, mem));
  4741   ins_pipe( ialu_loadI );
  4742 %}
  4744 // Load narrow Klass Pointer
  4745 instruct loadNKlass(mRegN dst, umemory mem)
  4746 %{
  4747   match(Set dst (LoadNKlass mem));
  4749   ins_cost(125); // XXX
  4750   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
  4751   ins_encode (load_N_enc(dst, mem));
  4752   ins_pipe( ialu_loadI ); // XXX
  4753 %}
  4755 instruct loadN2PKlass(mRegP dst, umemory mem)
  4756 %{
  4757   match(Set dst (DecodeNKlass (LoadNKlass mem)));
  4758   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  4760   ins_cost(125); // XXX
  4761   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
  4762   ins_encode (load_N_enc(dst, mem));
  4763   ins_pipe( ialu_loadI ); // XXX
  4764 %}
  4766 // Load Constant
  4767 instruct loadConI(mRegI dst, immI src) %{
  4768   match(Set dst src);
  4770   ins_cost(150);
  4771   format %{ "mov    $dst, $src #@loadConI" %}
  4772   ins_encode %{
  4773     Register dst = $dst$$Register;
  4774     int    value = $src$$constant;
  4775     __ move(dst, value);
  4776   %}
  4777   ins_pipe( ialu_regI_regI );
  4778 %}
  4781 instruct loadConL_set64(mRegL dst, immL src) %{
  4782   match(Set dst src);
  4783   ins_cost(120);
  4784   format %{ "li   $dst, $src @ loadConL_set64" %}
  4785   ins_encode %{
  4786     __ set64($dst$$Register, $src$$constant);
  4787   %}
  4788   ins_pipe(ialu_regL_regL);
  4789 %}
  4791 /*
  4792 // Load long value from constant table (predicated by immL_expensive).
  4793 instruct loadConL_load(mRegL dst, immL_expensive src) %{
  4794   match(Set dst src);
  4795   ins_cost(150);
  4796   format %{ "ld  $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
  4797   ins_encode %{
  4798     int con_offset = $constantoffset($src);
  4800     if (Assembler::is_simm16(con_offset)) {
  4801        __ ld($dst$$Register, $constanttablebase, con_offset);
  4802     } else {
  4803        __ set64(AT, con_offset);
  4804        if (UseLoongsonISA) {
  4805           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  4806        } else {
  4807           __ daddu(AT, $constanttablebase, AT);
  4808           __ ld($dst$$Register, AT, 0);
  4811   %}
  4812   ins_pipe(ialu_loadI);
  4813 %}
  4814 */
  4816 instruct loadConL16(mRegL dst, immL16 src) %{
  4817   match(Set dst src);
  4818   ins_cost(105);
  4819   format %{ "mov    $dst, $src #@loadConL16" %}
  4820   ins_encode %{
  4821     Register dst_reg = as_Register($dst$$reg);
  4822     int      value   = $src$$constant;
  4823     __ daddiu(dst_reg, R0, value);
  4824   %}
  4825   ins_pipe( ialu_regL_regL );
  4826 %}
  4829 instruct loadConL0(mRegL dst, immL0 src) %{
  4830   match(Set dst src);
  4831   ins_cost(100);
  4832   format %{ "mov    $dst, zero #@loadConL0" %}
  4833   ins_encode %{
  4834     Register dst_reg = as_Register($dst$$reg);
  4835     __ daddu(dst_reg, R0, R0);
  4836   %}
  4837   ins_pipe( ialu_regL_regL );
  4838 %}
  4840 // Load Range
  4841 instruct loadRange(mRegI dst, memory mem) %{
  4842   match(Set dst (LoadRange mem));
  4844   ins_cost(125);
  4845   format %{ "MOV    $dst,$mem @ loadRange" %}
  4846   ins_encode(load_I_enc(dst, mem));
  4847   ins_pipe( ialu_loadI );
  4848 %}
  4851 instruct storeP(memory mem, mRegP src ) %{
  4852   match(Set mem (StoreP mem src));
  4854   ins_cost(125);
  4855   format %{ "sd    $src, $mem #@storeP" %}
  4856   ins_encode(store_P_reg_enc(mem, src));
  4857   ins_pipe( ialu_storeI );
  4858 %}
  4860 // Store NULL Pointer, mark word, or other simple pointer constant.
  4861 instruct storeImmP0(memory mem, immP0 zero) %{
  4862   match(Set mem (StoreP mem zero));
  4864   ins_cost(125);
  4865   format %{ "mov    $mem, $zero #@storeImmP0" %}
  4866   ins_encode(store_P_immP0_enc(mem));
  4867   ins_pipe( ialu_storeI );
  4868 %}
  4870 // Store Compressed Pointer
  4871 instruct storeN(memory mem, mRegN src)
  4872 %{
  4873   match(Set mem (StoreN mem src));
  4875   ins_cost(125); // XXX
  4876   format %{ "sw    $mem, $src\t# compressed ptr @ storeN" %}
  4877   ins_encode(store_N_reg_enc(mem, src)); 
  4878   ins_pipe( ialu_storeI );
  4879 %}
  4881 instruct storeP2N(memory mem, mRegP src)
  4882 %{
  4883   match(Set mem (StoreN mem (EncodeP src)));
  4884   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  4886   ins_cost(125); // XXX
  4887   format %{ "sw    $mem, $src\t# @ storeP2N" %}
  4888   ins_encode(store_N_reg_enc(mem, src)); 
  4889   ins_pipe( ialu_storeI );
  4890 %}
  4892 instruct storeNKlass(memory mem, mRegN src)
  4893 %{
  4894   match(Set mem (StoreNKlass mem src));
  4896   ins_cost(125); // XXX
  4897   format %{ "sw    $mem, $src\t# compressed klass ptr @ storeNKlass" %}
  4898   ins_encode(store_N_reg_enc(mem, src));
  4899   ins_pipe( ialu_storeI );
  4900 %}
  4902 instruct storeP2NKlass(memory mem, mRegP src)
  4903 %{
  4904   match(Set mem (StoreNKlass mem (EncodePKlass src)));
  4905   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  4907   ins_cost(125); // XXX
  4908   format %{ "sw    $mem, $src\t# @ storeP2NKlass" %}
  4909   ins_encode(store_N_reg_enc(mem, src));
  4910   ins_pipe( ialu_storeI );
  4911 %}
  4913 instruct storeImmN0(memory mem, immN0 zero)
  4914 %{
  4915   match(Set mem (StoreN mem zero));
  4917   ins_cost(125); // XXX
  4918   format %{ "storeN0    $mem, R12\t# compressed ptr" %}
  4919   ins_encode(storeImmN0_enc(mem));
  4920   ins_pipe( ialu_storeI );
  4921 %}
  4923 // Store Byte
  4924 instruct storeB(memory mem, mRegI src) %{
  4925   match(Set mem (StoreB mem src));
  4927   ins_cost(125);
  4928   format %{ "sb    $src, $mem #@storeB" %}
  4929   ins_encode(store_B_reg_enc(mem, src));
  4930   ins_pipe( ialu_storeI );
  4931 %}
  4933 instruct storeB0(memory mem, immI0 zero) %{
  4934   match(Set mem (StoreB mem zero));
  4936   ins_cost(100);
  4937   format %{ "sb    $zero, $mem #@storeB0" %}
  4938   ins_encode(store_B0_enc(mem));
  4939   ins_pipe( ialu_storeI );
  4940 %}
  4942 instruct storeB_convL2I(memory mem, mRegL src) %{
  4943   match(Set mem (StoreB mem (ConvL2I src)));
  4945   ins_cost(125);
  4946   format %{ "sb    $src, $mem #@storeB_convL2I" %}
  4947   ins_encode(store_B_reg_enc(mem, src));
  4948   ins_pipe( ialu_storeI );
  4949 %}
  4951 // Load Byte (8bit signed)
  4952 instruct loadB(mRegI dst, memory mem) %{
  4953   match(Set dst (LoadB mem));
  4955   ins_cost(125);
  4956   format %{ "lb   $dst, $mem #@loadB" %}
  4957   ins_encode(load_B_enc(dst, mem));
  4958   ins_pipe( ialu_loadI );
  4959 %}
  4961 instruct loadB_convI2L(mRegL dst, memory mem) %{
  4962   match(Set dst (ConvI2L (LoadB mem)));
  4964   ins_cost(125);
  4965   format %{ "lb   $dst, $mem #@loadB_convI2L" %}
  4966   ins_encode(load_B_enc(dst, mem));
  4967   ins_pipe( ialu_loadI );
  4968 %}
  4970 // Load Byte (8bit UNsigned)
  4971 instruct loadUB(mRegI dst, umemory mem) %{
  4972   match(Set dst (LoadUB mem));
  4974   ins_cost(125);
  4975   format %{ "lbu   $dst, $mem #@loadUB" %}
  4976   ins_encode(load_UB_enc(dst, mem));
  4977   ins_pipe( ialu_loadI );
  4978 %}
  4980 instruct loadUB_convI2L(mRegL dst, umemory mem) %{
  4981   match(Set dst (ConvI2L (LoadUB mem)));
  4983   ins_cost(125);
  4984   format %{ "lbu   $dst, $mem #@loadUB_convI2L" %}
  4985   ins_encode(load_UB_enc(dst, mem));
  4986   ins_pipe( ialu_loadI );
  4987 %}
  4989 // Load Short (16bit signed)
  4990 instruct loadS(mRegI dst, memory mem) %{
  4991   match(Set dst (LoadS mem));
  4993   ins_cost(125);
  4994   format %{ "lh   $dst, $mem #@loadS" %}
  4995   ins_encode(load_S_enc(dst, mem));
  4996   ins_pipe( ialu_loadI );
  4997 %}
  4999 // Load Short (16 bit signed) to Byte (8 bit signed)
  5000 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  5001   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
  5003   ins_cost(125);
  5004   format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
  5005   ins_encode(load_B_enc(dst, mem));
  5006   ins_pipe(ialu_loadI);
  5007 %}
  5009 instruct loadS_convI2L(mRegL dst, memory mem) %{
  5010   match(Set dst (ConvI2L (LoadS mem)));
  5012   ins_cost(125);
  5013   format %{ "lh   $dst, $mem #@loadS_convI2L" %}
  5014   ins_encode(load_S_enc(dst, mem));
  5015   ins_pipe( ialu_loadI );
  5016 %}
  5018 // Store Integer Immediate
  5019 instruct storeI0(memory mem, immI0 zero) %{
  5020   match(Set mem (StoreI mem zero));
  5022   ins_cost(100);
  5023   format %{ "sw    $mem, $zero #@storeI0" %}
  5024   ins_encode(store_I_immI0_enc(mem));
  5025   ins_pipe( ialu_storeI );
  5026 %}
  5028 // Store Integer
  5029 instruct storeI(memory mem, mRegI src) %{
  5030   match(Set mem (StoreI mem src));
  5032   ins_cost(125);
  5033   format %{ "sw    $mem, $src #@storeI" %}
  5034   ins_encode(store_I_reg_enc(mem, src));
  5035   ins_pipe( ialu_storeI );
  5036 %}
  5038 instruct storeI_convL2I(memory mem, mRegL src) %{
  5039   match(Set mem (StoreI mem (ConvL2I src)));
  5041   ins_cost(125);
  5042   format %{ "sw    $mem, $src #@storeI_convL2I" %}
  5043   ins_encode(store_I_reg_enc(mem, src));
  5044   ins_pipe( ialu_storeI );
  5045 %}
  5047 // Load Float
  5048 instruct loadF(regF dst, memory mem) %{
  5049   match(Set dst (LoadF mem));
  5051   ins_cost(150);
  5052   format %{ "loadF $dst, $mem #@loadF" %}
  5053   ins_encode(load_F_enc(dst, mem));
  5054   ins_pipe( ialu_loadI );
  5055 %}
  5057 instruct loadConP_general(mRegP dst, immP src) %{
  5058   match(Set dst src);
  5060   ins_cost(120);
  5061   format %{ "li   $dst, $src #@loadConP_general" %}
  5063   ins_encode %{
  5064     Register dst = $dst$$Register;
  5065     long* value = (long*)$src$$constant;
  5067     if($src->constant_reloc() == relocInfo::metadata_type){
  5068     	int klass_index = __ oop_recorder()->find_index((Klass*)value);
  5069     	RelocationHolder rspec = metadata_Relocation::spec(klass_index);
  5071     	__ relocate(rspec);
  5072     	__ patchable_set48(dst, (long)value);
  5073     }else if($src->constant_reloc() == relocInfo::oop_type){
  5074     	int oop_index = __ oop_recorder()->find_index((jobject)value);
  5075     	RelocationHolder rspec = oop_Relocation::spec(oop_index);
  5077     	__ relocate(rspec);
  5078     	__ patchable_set48(dst, (long)value);
  5079     } else if ($src->constant_reloc() == relocInfo::none) {
  5080         __ set64(dst, (long)value);
  5082   %}
  5084   ins_pipe( ialu_regI_regI );
  5085 %}
  5087 /*
  5088 instruct loadConP_load(mRegP dst, immP_load src) %{
  5089   match(Set dst src);
  5091   ins_cost(100);
  5092   format %{ "ld     $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
  5094   ins_encode %{
  5096     int con_offset = $constantoffset($src);
  5098     if (Assembler::is_simm16(con_offset)) {
  5099        __ ld($dst$$Register, $constanttablebase, con_offset);
  5100     } else {
  5101        __ set64(AT, con_offset);
  5102        if (UseLoongsonISA) {
  5103           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  5104        } else {
  5105           __ daddu(AT, $constanttablebase, AT);
  5106           __ ld($dst$$Register, AT, 0);
  5109   %}
  5111   ins_pipe(ialu_loadI);
  5112 %}
  5113 */
  5115 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
  5116   match(Set dst src);
  5118   ins_cost(80);
  5119   format %{ "li    $dst, $src @ loadConP_no_oop_cheap" %}
  5121   ins_encode %{
  5122     __ set64($dst$$Register, $src$$constant);
  5123   %}
  5125   ins_pipe(ialu_regI_regI);
  5126 %}
  5129 instruct loadConP_poll(mRegP dst, immP_poll src) %{
  5130   match(Set dst src);
  5132   ins_cost(50);
  5133   format %{ "li   $dst, $src #@loadConP_poll" %}
  5135   ins_encode %{
  5136     Register dst = $dst$$Register;
  5137     intptr_t value = (intptr_t)$src$$constant;
  5139     __ set64(dst, (jlong)value);
  5140   %}
  5142   ins_pipe( ialu_regI_regI );
  5143 %}
  5145 instruct loadConP0(mRegP dst, immP0 src)
  5146 %{
  5147   match(Set dst src); 
  5149   ins_cost(50);
  5150   format %{ "mov    $dst, R0\t# ptr" %}
  5151   ins_encode %{
  5152      Register dst_reg = $dst$$Register;
  5153      __ daddu(dst_reg, R0, R0);
  5154   %}
  5155   ins_pipe( ialu_regI_regI );
  5156 %}
  5158 instruct loadConN0(mRegN dst, immN0 src) %{
  5159   match(Set dst src);
  5160   format %{ "move    $dst, R0\t# compressed NULL ptr" %}
  5161   ins_encode %{
  5162     __ move($dst$$Register, R0);
  5163   %}
  5164   ins_pipe( ialu_regI_regI );
  5165 %}
  5167 instruct loadConN(mRegN dst, immN src) %{
  5168   match(Set dst src);
  5170   ins_cost(125);
  5171   format %{ "li    $dst, $src\t# compressed ptr @ loadConN" %}
  5172   ins_encode %{
  5173     Register dst = $dst$$Register;
  5174     __ set_narrow_oop(dst, (jobject)$src$$constant);
  5175   %}
  5176   ins_pipe( ialu_regI_regI ); // XXX
  5177 %}
  5179 instruct loadConNKlass(mRegN dst, immNKlass src) %{
  5180   match(Set dst src);
  5182   ins_cost(125);
  5183   format %{ "li    $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
  5184   ins_encode %{
  5185     Register dst = $dst$$Register;
  5186     __ set_narrow_klass(dst, (Klass*)$src$$constant);
  5187   %}
  5188   ins_pipe( ialu_regI_regI ); // XXX
  5189 %}
  5191 //FIXME
  5192 // Tail Call; Jump from runtime stub to Java code.
  5193 // Also known as an 'interprocedural jump'.
  5194 // Target of jump will eventually return to caller.
  5195 // TailJump below removes the return address.
  5196 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
  5197   match(TailCall jump_target method_oop );
  5198   ins_cost(300);
  5199   format %{ "JMP    $jump_target \t# @TailCalljmpInd" %}
  5201   ins_encode %{
  5202     Register target = $jump_target$$Register;
  5203     Register    oop = $method_oop$$Register;
  5205     /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
  5206     __ push(RA);
  5208     __ move(S3, oop);
  5209     __ jr(target);
  5210     __ nop();
  5211   %}
  5213   ins_pipe( pipe_jump );
  5214 %}
  5216 // Create exception oop: created by stack-crawling runtime code.
  5217 // Created exception is now available to this handler, and is setup
  5218 // just prior to jumping to this handler.  No code emitted.
  5219 instruct CreateException( a0_RegP ex_oop )
  5220 %{
  5221   match(Set ex_oop (CreateEx));
  5223   // use the following format syntax
  5224   format %{ "# exception oop is in A0; no code emitted @CreateException" %}
  5225   ins_encode %{
  5226     /* Jin: X86 leaves this function empty */
  5227     __ block_comment("CreateException is empty in X86/MIPS");
  5228   %}
  5229   ins_pipe( empty );
  5230 //  ins_pipe( pipe_jump );
  5231 %}
  5234 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
  5236 - Common try/catch:
  5237  2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
  5238                     |- V0, V1 are created
  5239                     |- T9 <= SharedRuntime::exception_handler_for_return_address
  5240                     `- jr T9
  5241                          `- the caller's exception_handler
  5242                                `- jr OptoRuntime::exception_blob
  5243                                       `- here
  5244 - Rethrow(e.g. 'unwind'):
  5245   * The callee:
  5246      |- an exception is triggered during execution
  5247      `- exits the callee method through RethrowException node
  5248           |- The callee pushes exception_oop(T0) and exception_pc(RA)
  5249           `- The callee jumps to OptoRuntime::rethrow_stub()
  5250   * In OptoRuntime::rethrow_stub:
  5251      |- The VM calls _rethrow_Java to determine the return address in the caller method
  5252      `- exits the stub with tailjmpInd
  5253           |- pops exception_oop(V0) and exception_pc(V1)
  5254           `- jumps to the return address(usually an exception_handler)
  5255   * The caller:
  5256      `- continues processing the exception_blob with V0/V1
  5257 */
  5259 /*
  5260 Disassembling OptoRuntime::rethrow_stub()
  5262 ; locals
  5263    0x2d3bf320: addiu sp, sp, 0xfffffff8
  5264    0x2d3bf324: sw ra, 0x4(sp)
  5265    0x2d3bf328: sw fp, 0x0(sp)
  5266    0x2d3bf32c: addu fp, sp, zero
  5267    0x2d3bf330: addiu sp, sp, 0xfffffff0
  5268    0x2d3bf334: sw ra, 0x8(sp)
  5269    0x2d3bf338: sw t0, 0x4(sp)
  5270    0x2d3bf33c: sw sp, 0x0(sp)
  5272 ; get_thread(S2)
  5273    0x2d3bf340: addu s2, sp, zero
  5274    0x2d3bf344: srl s2, s2, 12
  5275    0x2d3bf348: sll s2, s2, 2
  5276    0x2d3bf34c: lui at, 0x2c85
  5277    0x2d3bf350: addu at, at, s2
  5278    0x2d3bf354: lw s2, 0xffffcc80(at)
  5280    0x2d3bf358: lw s0, 0x0(sp)
  5281    0x2d3bf35c: sw s0, 0x118(s2)		// last_sp -> threa
  5282    0x2d3bf360: sw s2, 0xc(sp)
  5284 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
  5285    0x2d3bf364: lw a0, 0x4(sp)
  5286    0x2d3bf368: lw a1, 0xc(sp)
  5287    0x2d3bf36c: lw a2, 0x8(sp)
  5288   ;; Java_To_Runtime
  5289    0x2d3bf370: lui t9, 0x2c34
  5290    0x2d3bf374: addiu t9, t9, 0xffff8a48
  5291    0x2d3bf378: jalr t9
  5292    0x2d3bf37c: nop
  5294    0x2d3bf380: addu s3, v0, zero		 ; S3: SharedRuntime::raw_exception_handler_for_return_address()
  5296    0x2d3bf384: lw s0, 0xc(sp)
  5297    0x2d3bf388: sw zero, 0x118(s0)
  5298    0x2d3bf38c: sw zero, 0x11c(s0)
  5299    0x2d3bf390: lw s1, 0x144(s0)			; ex_oop: S1
  5300    0x2d3bf394: addu s2, s0, zero
  5301    0x2d3bf398: sw zero, 0x144(s2)
  5302    0x2d3bf39c: lw s0, 0x4(s2)
  5303    0x2d3bf3a0: addiu s4, zero, 0x0
  5304    0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
  5305    0x2d3bf3a8: nop
  5306    0x2d3bf3ac: addiu sp, sp, 0x10
  5307    0x2d3bf3b0: addiu sp, sp, 0x8
  5308    0x2d3bf3b4: lw ra, 0xfffffffc(sp)
  5309    0x2d3bf3b8: lw fp, 0xfffffff8(sp)
  5310    0x2d3bf3bc: lui at, 0x2b48
  5311    0x2d3bf3c0: lw at, 0x100(at)
  5313 ; tailjmpInd: Restores exception_oop & exception_pc
  5314    0x2d3bf3c4: addu v1, ra, zero
  5315    0x2d3bf3c8: addu v0, s1, zero
  5316    0x2d3bf3cc: jr s3
  5317    0x2d3bf3d0: nop
  5318 ; Exception:
  5319    0x2d3bf3d4: lui s1, 0x2cc8		; generate_forward_exception()
  5320    0x2d3bf3d8: addiu s1, s1, 0x40
  5321    0x2d3bf3dc: addiu s2, zero, 0x0
  5322    0x2d3bf3e0: addiu sp, sp, 0x10
  5323    0x2d3bf3e4: addiu sp, sp, 0x8
  5324    0x2d3bf3e8: lw ra, 0xfffffffc(sp)
  5325    0x2d3bf3ec: lw fp, 0xfffffff8(sp)
  5326    0x2d3bf3f0: lui at, 0x2b48
  5327    0x2d3bf3f4: lw at, 0x100(at)
  5328 ; TailCalljmpInd 
  5329               __ push(RA);		; to be used in generate_forward_exception()
  5330    0x2d3bf3f8: addu t7, s2, zero
  5331    0x2d3bf3fc: jr s1
  5332    0x2d3bf400: nop
  5333 */
  5334 // Rethrow exception:
  5335 // The exception oop will come in the first argument position.
  5336 // Then JUMP (not call) to the rethrow stub code.
  5337 instruct RethrowException()
  5338 %{
  5339   match(Rethrow);
  5341   // use the following format syntax
  5342   format %{ "JMP    rethrow_stub #@RethrowException" %}
  5343   ins_encode %{
  5344     __ block_comment("@ RethrowException");
  5346     cbuf.set_insts_mark();
  5347     cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
  5349     // call OptoRuntime::rethrow_stub to get the exception handler in parent method
  5350     __ patchable_jump((address)OptoRuntime::rethrow_stub());
  5351   %}
  5352   ins_pipe( pipe_jump );
  5353 %}
  5355 instruct branchConP_zero(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  5356   match(If cmp (CmpP op1 zero));
  5357   effect(USE labl);
  5359   ins_cost(180);
  5360   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero" %}
  5362   ins_encode %{
  5363     Register op1 = $op1$$Register;
  5364     Register op2 = R0;
  5365     Label    &L  = *($labl$$label);
  5366     int     flag = $cmp$$cmpcode;
  5368     switch(flag)
  5370       case 0x01: //equal
  5371 	if (&L)
  5372         	__ beq(op1, op2, L); 
  5373 	else 
  5374         	__ beq(op1, op2, (int)0); 
  5375         break;
  5376       case 0x02: //not_equal
  5377 	if (&L)
  5378         	__ bne(op1, op2, L); 
  5379 	else
  5380         	__ bne(op1, op2, (int)0); 
  5381         break;
  5382 /*
  5383       case 0x03: //above
  5384         __ sltu(AT, op2, op1);
  5385         if(&L)
  5386         	__ bne(R0, AT, L); 
  5387         else
  5388                 __ bne(R0, AT, (int)0);
  5389         break;
  5390       case 0x04: //above_equal
  5391         __ sltu(AT, op1, op2);
  5392         if(&L)
  5393        	        __ beq(AT, R0, L);
  5394         else
  5395        	        __ beq(AT, R0, (int)0);
  5396         break;
  5397       case 0x05: //below
  5398         __ sltu(AT, op1, op2);
  5399         if(&L)
  5400       		 __ bne(R0, AT, L); 
  5401         else
  5402         	 __ bne(R0, AT, (int)0);
  5403         break;
  5404       case 0x06: //below_equal
  5405         __ sltu(AT, op2, op1);
  5406         if(&L)
  5407         	__ beq(AT, R0, L);
  5408         else
  5409         	__ beq(AT, R0, (int)0);
  5410        break;
  5411 */
  5412       default:
  5413           Unimplemented();
  5415     __ nop();
  5416   %}
  5418   ins_pc_relative(1);
  5419   ins_pipe( pipe_alu_branch );
  5420 %}
  5422 instruct branchConN2P_zero(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  5423   match(If cmp (CmpP (DecodeN op1) zero));
  5424   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  5425   effect(USE labl);
  5427   ins_cost(180);
  5428   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero" %}
  5430   ins_encode %{
  5431     Register op1 = $op1$$Register;
  5432     Register op2 = R0;
  5433     Label    &L  = *($labl$$label);
  5434     int     flag = $cmp$$cmpcode;
  5436     switch(flag)
  5438       case 0x01: //equal
  5439 	if (&L)
  5440         	__ beq(op1, op2, L); 
  5441 	else 
  5442         	__ beq(op1, op2, (int)0); 
  5443         break;
  5444       case 0x02: //not_equal
  5445 	if (&L)
  5446         	__ bne(op1, op2, L); 
  5447 	else
  5448         	__ bne(op1, op2, (int)0); 
  5449         break;
  5450       default:
  5451           Unimplemented();
  5453     __ nop();
  5454   %}
  5456   ins_pc_relative(1);
  5457   ins_pipe( pipe_alu_branch );
  5458 %}
  5461 instruct branchConP(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  5462   match(If cmp (CmpP op1 op2));
  5463 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  5464   effect(USE labl);
  5466   ins_cost(200);
  5467   format %{ "b$cmp   $op1, $op2, $labl #@branchConP" %}
  5469   ins_encode %{
  5470     Register op1 = $op1$$Register;
  5471     Register op2 = $op2$$Register;
  5472     Label    &L  = *($labl$$label);
  5473     int     flag = $cmp$$cmpcode;
  5475     switch(flag)
  5477       case 0x01: //equal
  5478 	if (&L)
  5479         	__ beq(op1, op2, L); 
  5480 	else 
  5481         	__ beq(op1, op2, (int)0); 
  5482         break;
  5483       case 0x02: //not_equal
  5484 	if (&L)
  5485         	__ bne(op1, op2, L); 
  5486 	else
  5487         	__ bne(op1, op2, (int)0); 
  5488         break;
  5489       case 0x03: //above
  5490         __ sltu(AT, op2, op1);
  5491         if(&L)
  5492         	__ bne(R0, AT, L); 
  5493         else
  5494                 __ bne(R0, AT, (int)0);
  5495         break;
  5496       case 0x04: //above_equal
  5497         __ sltu(AT, op1, op2);
  5498         if(&L)
  5499        	        __ beq(AT, R0, L);
  5500         else
  5501        	        __ beq(AT, R0, (int)0);
  5502         break;
  5503       case 0x05: //below
  5504         __ sltu(AT, op1, op2);
  5505         if(&L)
  5506       		 __ bne(R0, AT, L); 
  5507         else
  5508         	 __ bne(R0, AT, (int)0);
  5509         break;
  5510       case 0x06: //below_equal
  5511         __ sltu(AT, op2, op1);
  5512         if(&L)
  5513         	__ beq(AT, R0, L);
  5514         else
  5515         	__ beq(AT, R0, (int)0);
  5516        break;
  5517       default:
  5518           Unimplemented();
  5520     __ nop();
  5521   %}
  5523   ins_pc_relative(1);
  5524   ins_pipe( pipe_alu_branch );
  5525 %}
  5527 instruct cmpN_null_branch(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  5528   match(If cmp (CmpN op1 null));
  5529   effect(USE labl);
  5531   ins_cost(180);
  5532   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  5533             "BP$cmp   $labl @ cmpN_null_branch" %}
  5534   ins_encode %{
  5535     Register op1 = $op1$$Register;
  5536     Register op2 = R0;
  5537     Label    &L  = *($labl$$label);
  5538     int     flag = $cmp$$cmpcode;
  5540     switch(flag)
  5542 		case 0x01: //equal
  5543 			if (&L)
  5544 				__ beq(op1, op2, L); 
  5545 			else 
  5546 				__ beq(op1, op2, (int)0); 
  5547 			break;
  5548 		case 0x02: //not_equal
  5549 			if (&L)
  5550 				__ bne(op1, op2, L); 
  5551 			else
  5552 				__ bne(op1, op2, (int)0); 
  5553 			break;
  5554 		default:
  5555           Unimplemented();
  5557     __ nop();
  5558   %}
  5559 //TODO: pipe_branchP or create pipe_branchN LEE
  5560   ins_pc_relative(1);
  5561   ins_pipe( pipe_alu_branch );
  5562 %}
  5564 instruct cmpN_reg_branch(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  5565   match(If cmp (CmpN op1 op2));
  5566   effect(USE labl);
  5568   ins_cost(180);
  5569   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  5570             "BP$cmp   $labl" %}
  5571   ins_encode %{
  5572     Register op1_reg = $op1$$Register;
  5573     Register op2_reg = $op2$$Register;
  5574     Label    &L  = *($labl$$label);
  5575     int     flag = $cmp$$cmpcode;
  5577     switch(flag)
  5579 		case 0x01: //equal
  5580 			if (&L)
  5581 				__ beq(op1_reg, op2_reg, L); 
  5582 			else 
  5583 				__ beq(op1_reg, op2_reg, (int)0); 
  5584 			break;
  5585 		case 0x02: //not_equal
  5586 			if (&L)
  5587 				__ bne(op1_reg, op2_reg, L); 
  5588 			else
  5589 				__ bne(op1_reg, op2_reg, (int)0); 
  5590 			break;
  5591 		case 0x03: //above
  5592 			__ sltu(AT, op2_reg, op1_reg);
  5593 			if(&L)
  5594 				__ bne(R0, AT, L); 
  5595 			else
  5596 				__ bne(R0, AT, (int)0);
  5597 			break;
  5598 		case 0x04: //above_equal
  5599 			__ sltu(AT, op1_reg, op2_reg);
  5600 			if(&L)
  5601 				__ beq(AT, R0, L);
  5602 			else
  5603 				__ beq(AT, R0, (int)0);
  5604 			break;
  5605 		case 0x05: //below
  5606 			__ sltu(AT, op1_reg, op2_reg);
  5607 			if(&L)
  5608 				__ bne(R0, AT, L); 
  5609 			else
  5610 				__ bne(R0, AT, (int)0);
  5611 			break;
  5612 		case 0x06: //below_equal
  5613 			__ sltu(AT, op2_reg, op1_reg);
  5614 			if(&L)
  5615 				__ beq(AT, R0, L);
  5616 			else
  5617 				__ beq(AT, R0, (int)0);
  5618 			break;
  5619 		default:
  5620           Unimplemented();
  5622     __ nop();
  5623   %}
  5624   ins_pc_relative(1);
  5625   ins_pipe( pipe_alu_branch );
  5626 %}
  5628 instruct branchConIU_reg_reg(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  5629   match( If cmp (CmpU src1 src2) );
  5630   effect(USE labl);
  5631   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg" %}
  5633   ins_encode %{
  5634     Register op1 = $src1$$Register;
  5635     Register op2 = $src2$$Register;
  5636     Label     &L = *($labl$$label);
  5637     int     flag = $cmp$$cmpcode;
  5639     switch(flag)
  5641       case 0x01: //equal
  5642 	if (&L)
  5643         	__ beq(op1, op2, L); 
  5644 	else 
  5645         	__ beq(op1, op2, (int)0); 
  5646         break;
  5647       case 0x02: //not_equal
  5648 	if (&L)
  5649         	__ bne(op1, op2, L); 
  5650 	else
  5651         	__ bne(op1, op2, (int)0); 
  5652         break;
  5653       case 0x03: //above
  5654         __ sltu(AT, op2, op1);
  5655         if(&L)
  5656         	__ bne(AT, R0, L); 
  5657         else
  5658                 __ bne(AT, R0, (int)0);
  5659         break;
  5660       case 0x04: //above_equal
  5661         __ sltu(AT, op1, op2);
  5662         if(&L)
  5663         	__ beq(AT, R0, L);
  5664         else
  5665                 __ beq(AT, R0, (int)0);
  5666         break;
  5667       case 0x05: //below
  5668         __ sltu(AT, op1, op2);
  5669         if(&L)
  5670       		 __ bne(AT, R0, L); 
  5671         else
  5672         	 __ bne(AT, R0, (int)0);
  5673         break;
  5674       case 0x06: //below_equal
  5675         __ sltu(AT, op2, op1);
  5676         if(&L)
  5677         	__ beq(AT, R0, L);
  5678         else
  5679         	__ beq(AT, R0, (int)0);
  5680         break;
  5681       default:
  5682           Unimplemented();
  5684     __ nop();
  5685   %}
  5687   ins_pc_relative(1);
  5688   ins_pipe( pipe_alu_branch );
  5689 %}
  5692 instruct branchConIU_reg_imm(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  5693   match( If cmp (CmpU src1 src2) );
  5694   effect(USE labl);
  5695   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm" %}
  5697   ins_encode %{
  5698     Register op1 = $src1$$Register;
  5699     int      val = $src2$$constant;
  5700     Label     &L = *($labl$$label);
  5701     int     flag = $cmp$$cmpcode;
  5703     __ move(AT, val);
  5704     switch(flag)
  5706       case 0x01: //equal
  5707 	if (&L)
  5708         	__ beq(op1, AT, L); 
  5709 	else 
  5710         	__ beq(op1, AT, (int)0); 
  5711         break;
  5712       case 0x02: //not_equal
  5713 	if (&L)
  5714         	__ bne(op1, AT, L); 
  5715 	else
  5716         	__ bne(op1, AT, (int)0); 
  5717         break;
  5718       case 0x03: //above
  5719         __ sltu(AT, AT, op1);
  5720         if(&L)
  5721         	__ bne(R0, AT, L); 
  5722         else
  5723                 __ bne(R0, AT, (int)0);
  5724         break;
  5725       case 0x04: //above_equal
  5726         __ sltu(AT, op1, AT);
  5727         if(&L)
  5728         	__ beq(AT, R0, L);
  5729         else
  5730                 __ beq(AT, R0, (int)0);
  5731         break;
  5732       case 0x05: //below
  5733         __ sltu(AT, op1, AT);
  5734         if(&L)
  5735       		 __ bne(R0, AT, L); 
  5736         else
  5737         	 __ bne(R0, AT, (int)0);
  5738         break;
  5739       case 0x06: //below_equal
  5740         __ sltu(AT, AT, op1);
  5741         if(&L)
  5742         	__ beq(AT, R0, L);
  5743         else
  5744         	__ beq(AT, R0, (int)0);
  5745        break;
  5746       default:
  5747           Unimplemented();
  5749     __ nop();
  5750   %}
  5752   ins_pc_relative(1);
  5753   ins_pipe( pipe_alu_branch );
  5754 %}
  5756 instruct branchConI_reg_reg(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  5757   match( If cmp (CmpI src1 src2) );
  5758   effect(USE labl);
  5759   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg" %}
  5761   ins_encode %{
  5762     Register op1 = $src1$$Register;
  5763     Register op2 = $src2$$Register;
  5764     Label     &L = *($labl$$label);
  5765     int     flag = $cmp$$cmpcode;
  5767     switch(flag)
  5769       case 0x01: //equal
  5770 	if (&L)
  5771         	__ beq(op1, op2, L); 
  5772 	else 
  5773         	__ beq(op1, op2, (int)0); 
  5774         break;
  5775       case 0x02: //not_equal
  5776 	if (&L)
  5777         	__ bne(op1, op2, L); 
  5778 	else
  5779         	__ bne(op1, op2, (int)0); 
  5780         break;
  5781       case 0x03: //above
  5782         __ slt(AT, op2, op1);
  5783         if(&L)
  5784         	__ bne(R0, AT, L); 
  5785         else
  5786                 __ bne(R0, AT, (int)0);
  5787         break;
  5788       case 0x04: //above_equal
  5789         __ slt(AT, op1, op2);
  5790         if(&L)
  5791         	__ beq(AT, R0, L);
  5792         else
  5793                 __ beq(AT, R0, (int)0);
  5794         break;
  5795       case 0x05: //below
  5796         __ slt(AT, op1, op2);
  5797         if(&L)
  5798       		 __ bne(R0, AT, L); 
  5799         else
  5800         	 __ bne(R0, AT, (int)0);
  5801         break;
  5802       case 0x06: //below_equal
  5803         __ slt(AT, op2, op1);
  5804         if(&L)
  5805         	__ beq(AT, R0, L);
  5806         else
  5807         	__ beq(AT, R0, (int)0);
  5808        break;
  5809       default:
  5810           Unimplemented();
  5812     __ nop();
  5813   %}
  5815   ins_pc_relative(1);
  5816   ins_pipe( pipe_alu_branch );
  5817 %}
  5819 instruct branchConI_reg_imm0(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  5820   match( If cmp (CmpI src1 src2) );
  5821   effect(USE labl);
  5822   ins_cost(170);
  5823   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0" %}
  5825   ins_encode %{
  5826     Register op1 = $src1$$Register;
  5827 //    int      val = $src2$$constant;
  5828     Label     &L =  *($labl$$label);
  5829     int     flag = $cmp$$cmpcode;
  5831     //__ move(AT, val);
  5832     switch(flag)
  5834       case 0x01: //equal
  5835 	if (&L)
  5836         	__ beq(op1, R0, L); 
  5837 	else 
  5838         	__ beq(op1, R0, (int)0); 
  5839         break;
  5840       case 0x02: //not_equal
  5841 	if (&L)
  5842         	__ bne(op1, R0, L); 
  5843 	else
  5844         	__ bne(op1, R0, (int)0); 
  5845         break;
  5846       case 0x03: //greater
  5847         if(&L)
  5848                __ bgtz(op1, L);
  5849         else
  5850                __ bgtz(op1, (int)0);
  5851         break;
  5852       case 0x04: //greater_equal
  5853         if(&L)
  5854                __ bgez(op1, L);
  5855         else
  5856                __ bgez(op1, (int)0);
  5857         break;
  5858       case 0x05: //less
  5859         if(&L)
  5860                 __ bltz(op1, L);
  5861         else
  5862                 __ bltz(op1, (int)0);
  5863         break;
  5864       case 0x06: //less_equal
  5865         if(&L)
  5866                __ blez(op1, L);
  5867         else
  5868                __ blez(op1, (int)0);
  5869        break;
  5870       default:
  5871           Unimplemented();
  5873     __ nop();
  5874   %}
  5876   ins_pc_relative(1);
  5877   ins_pipe( pipe_alu_branch );
  5878 %}
  5881 instruct branchConI_reg_imm(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  5882   match( If cmp (CmpI src1 src2) );
  5883   effect(USE labl);
  5884   ins_cost(200);
  5885   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm" %}
  5887   ins_encode %{
  5888     Register op1 = $src1$$Register;
  5889     int      val = $src2$$constant;
  5890     Label     &L =  *($labl$$label);
  5891     int     flag = $cmp$$cmpcode;
  5893     __ move(AT, val);
  5894     switch(flag)
  5896       case 0x01: //equal
  5897 	if (&L)
  5898         	__ beq(op1, AT, L); 
  5899 	else 
  5900         	__ beq(op1, AT, (int)0); 
  5901         break;
  5902       case 0x02: //not_equal
  5903 	if (&L)
  5904         	__ bne(op1, AT, L); 
  5905 	else
  5906         	__ bne(op1, AT, (int)0); 
  5907         break;
  5908       case 0x03: //greater
  5909         __ slt(AT, AT, op1);
  5910         if(&L)
  5911         	__ bne(R0, AT, L); 
  5912         else
  5913                 __ bne(R0, AT, (int)0);
  5914         break;
  5915       case 0x04: //greater_equal
  5916         __ slt(AT, op1, AT);
  5917         if(&L)
  5918         	__ beq(AT, R0, L);
  5919         else
  5920                 __ beq(AT, R0, (int)0);
  5921         break;
  5922       case 0x05: //less
  5923         __ slt(AT, op1, AT);
  5924         if(&L)
  5925       		 __ bne(R0, AT, L); 
  5926         else
  5927         	 __ bne(R0, AT, (int)0);
  5928         break;
  5929       case 0x06: //less_equal
  5930         __ slt(AT, AT, op1);
  5931         if(&L)
  5932         	__ beq(AT, R0, L);
  5933         else
  5934         	__ beq(AT, R0, (int)0);
  5935        break;
  5936       default:
  5937           Unimplemented();
  5939     __ nop();
  5940   %}
  5942   ins_pc_relative(1);
  5943   ins_pipe( pipe_alu_branch );
  5944 %}
  5946 instruct branchConIU_reg_imm0(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  5947   match( If cmp (CmpU src1 zero) );
  5948   effect(USE labl);
  5949   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0" %}
  5951   ins_encode %{
  5952     Register op1 = $src1$$Register;
  5953     Label     &L = *($labl$$label);
  5954     int     flag = $cmp$$cmpcode;
  5956     switch(flag)
  5958       case 0x01: //equal
  5959        if (&L)
  5960                __ beq(op1, R0, L); 
  5961        else 
  5962                __ beq(op1, R0, (int)0); 
  5963         break;
  5964       case 0x02: //not_equal
  5965        if (&L)
  5966                __ bne(op1, R0, L); 
  5967        else
  5968                __ bne(op1, R0, (int)0); 
  5969         break;
  5970       case 0x03: //above
  5971         if(&L)
  5972                __ bne(R0, op1, L); 
  5973         else
  5974                 __ bne(R0, op1, (int)0);
  5975         break;
  5976       case 0x04: //above_equal
  5977         if(&L)
  5978                __ beq(R0, R0, L);
  5979         else
  5980                 __ beq(R0, R0, (int)0);
  5981         break;
  5982       case 0x05: //below
  5983         return;
  5984         break;
  5985       case 0x06: //below_equal
  5986         if(&L)
  5987                __ beq(op1, R0, L);
  5988         else
  5989                __ beq(op1, R0, (int)0);
  5990        break;
  5991       default:
  5992           Unimplemented();
  5994     __ nop();
  5995   %}
  5997   ins_pc_relative(1);
  5998   ins_pipe( pipe_alu_branch );
  5999 %}
  6002 instruct branchConIU_reg_immI16(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  6003   match( If cmp (CmpU src1 src2) );
  6004   effect(USE labl);
  6005   ins_cost(180);
  6006   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16" %}
  6008   ins_encode %{
  6009     Register op1 = $src1$$Register;
  6010     int      val = $src2$$constant;
  6011     Label     &L = *($labl$$label);
  6012     int     flag = $cmp$$cmpcode;
  6014     switch(flag)
  6016       case 0x01: //equal
  6017         __ move(AT, val);
  6018        if (&L)
  6019                __ beq(op1, AT, L); 
  6020        else 
  6021                __ beq(op1, AT, (int)0); 
  6022         break;
  6023       case 0x02: //not_equal
  6024         __ move(AT, val);
  6025        if (&L)
  6026                __ bne(op1, AT, L); 
  6027        else
  6028                __ bne(op1, AT, (int)0); 
  6029         break;
  6030       case 0x03: //above
  6031         __ move(AT, val);
  6032         __ sltu(AT, AT, op1);
  6033         if(&L)
  6034                __ bne(R0, AT, L); 
  6035         else
  6036                 __ bne(R0, AT, (int)0);
  6037         break;
  6038       case 0x04: //above_equal
  6039         __ sltiu(AT, op1, val);
  6040         if(&L)
  6041                __ beq(AT, R0, L);
  6042         else
  6043                 __ beq(AT, R0, (int)0);
  6044         break;
  6045       case 0x05: //below
  6046         __ sltiu(AT, op1, val);
  6047         if(&L)
  6048                 __ bne(R0, AT, L); 
  6049         else
  6050                 __ bne(R0, AT, (int)0);
  6051         break;
  6052       case 0x06: //below_equal
  6053         __ move(AT, val);
  6054         __ sltu(AT, AT, op1);
  6055         if(&L)
  6056                __ beq(AT, R0, L);
  6057         else
  6058                __ beq(AT, R0, (int)0);
  6059        break;
  6060       default:
  6061           Unimplemented();
  6063     __ nop();
  6064   %}
  6066   ins_pc_relative(1);
  6067   ins_pipe( pipe_alu_branch );
  6068 %}
  6071 instruct branchConL_regL_regL(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  6072   match( If cmp (CmpL src1 src2) );
  6073   effect(USE labl);
  6074   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL" %}
  6075   ins_cost(250);
  6077   ins_encode %{
  6078     Register opr1_reg = as_Register($src1$$reg);
  6079     Register opr2_reg = as_Register($src2$$reg);
  6081     Label   &target = *($labl$$label);
  6082     int     flag = $cmp$$cmpcode;
  6084     switch(flag)
  6086       case 0x01: //equal
  6087         if (&target) 
  6088 			__ beq(opr1_reg, opr2_reg, target);
  6089         else
  6090 			__ beq(opr1_reg, opr2_reg, (int)0);
  6091         __ delayed()->nop();
  6092         break;
  6094       case 0x02: //not_equal
  6095         if(&target)
  6096            __ bne(opr1_reg, opr2_reg, target);
  6097         else
  6098            __ bne(opr1_reg, opr2_reg, (int)0);
  6099         __ delayed()->nop();
  6100         break;
  6102       case 0x03: //greater
  6103         __ slt(AT, opr2_reg, opr1_reg);
  6104         if(&target)
  6105            __ bne(AT, R0, target);
  6106         else
  6107            __ bne(AT, R0, (int)0);
  6108         __ delayed()->nop();
  6109         break;
  6111       case 0x04: //greater_equal
  6112         __ slt(AT, opr1_reg, opr2_reg);
  6113         if(&target)
  6114            __ beq(AT, R0, target);
  6115         else
  6116            __ beq(AT, R0, (int)0);
  6117         __ delayed()->nop();
  6119         break;
  6121       case 0x05: //less
  6122         __ slt(AT, opr1_reg, opr2_reg);
  6123         if(&target)
  6124            __ bne(AT, R0, target);
  6125         else
  6126            __ bne(AT, R0, (int)0);
  6127         __ delayed()->nop();
  6129         break;
  6131       case 0x06: //less_equal
  6132        __ slt(AT, opr2_reg, opr1_reg);
  6134        if(&target)
  6135           __ beq(AT, R0, target);
  6136        else
  6137           __ beq(AT, R0, (int)0);
  6138        __ delayed()->nop();
  6140        break;
  6142       default:
  6143           Unimplemented();
  6145   %}
  6148   ins_pc_relative(1);
  6149   ins_pipe( pipe_alu_branch );
  6150 %}
  6152 instruct branchConL_reg_immL16_sub(cmpOp cmp, mRegL src1, immL16_sub src2, label labl) %{
  6153   match( If cmp (CmpL src1 src2) );
  6154   effect(USE labl);
  6155   ins_cost(180);
  6156   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_reg_immL16_sub" %}
  6158   ins_encode %{
  6159     Register op1 = $src1$$Register;
  6160     int      val = $src2$$constant;
  6161     Label     &L =  *($labl$$label);
  6162     int     flag = $cmp$$cmpcode;
  6164     __ daddiu(AT, op1, -1 * val);
  6165     switch(flag)
  6167       case 0x01: //equal
  6168        if (&L)
  6169                __ beq(R0, AT, L); 
  6170        else 
  6171                __ beq(R0, AT, (int)0); 
  6172         break;
  6173       case 0x02: //not_equal
  6174        if (&L)
  6175                __ bne(R0, AT, L); 
  6176        else
  6177                __ bne(R0, AT, (int)0); 
  6178         break;
  6179       case 0x03: //greater
  6180         if(&L)
  6181                __ bgtz(AT, L); 
  6182         else
  6183                 __ bgtz(AT, (int)0);
  6184         break;
  6185       case 0x04: //greater_equal
  6186         if(&L)
  6187                __ bgez(AT, L);
  6188         else
  6189                 __ bgez(AT, (int)0);
  6190         break;
  6191       case 0x05: //less
  6192         if(&L)
  6193                 __ bltz(AT, L); 
  6194         else
  6195                 __ bltz(AT, (int)0);
  6196         break;
  6197       case 0x06: //less_equal
  6198         if(&L)
  6199                __ blez(AT, L);
  6200         else
  6201                __ blez(AT, (int)0);
  6202        break;
  6203       default:
  6204           Unimplemented();
  6206     __ nop();
  6207   %}
  6209   ins_pc_relative(1);
  6210   ins_pipe( pipe_alu_branch );
  6211 %}
  6214 instruct branchConI_reg_imm16_sub(cmpOp cmp, mRegI src1, immI16_sub src2, label labl) %{
  6215   match( If cmp (CmpI src1 src2) );
  6216   effect(USE labl);
  6217   ins_cost(180);
  6218   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm16_sub" %}
  6220   ins_encode %{
  6221     Register op1 = $src1$$Register;
  6222     int      val = $src2$$constant;
  6223     Label     &L =  *($labl$$label);
  6224     int     flag = $cmp$$cmpcode;
  6226     __ addiu32(AT, op1, -1 * val);
  6227     switch(flag)
  6229       case 0x01: //equal
  6230        if (&L)
  6231                __ beq(R0, AT, L); 
  6232        else 
  6233                __ beq(R0, AT, (int)0); 
  6234         break;
  6235       case 0x02: //not_equal
  6236        if (&L)
  6237                __ bne(R0, AT, L); 
  6238        else
  6239                __ bne(R0, AT, (int)0); 
  6240         break;
  6241       case 0x03: //greater
  6242         if(&L)
  6243                __ bgtz(AT, L); 
  6244         else
  6245                 __ bgtz(AT, (int)0);
  6246         break;
  6247       case 0x04: //greater_equal
  6248         if(&L)
  6249                __ bgez(AT, L);
  6250         else
  6251                 __ bgez(AT, (int)0);
  6252         break;
  6253       case 0x05: //less
  6254         if(&L)
  6255                 __ bltz(AT, L); 
  6256         else
  6257                 __ bltz(AT, (int)0);
  6258         break;
  6259       case 0x06: //less_equal
  6260         if(&L)
  6261                __ blez(AT, L);
  6262         else
  6263                __ blez(AT, (int)0);
  6264        break;
  6265       default:
  6266           Unimplemented();
  6268     __ nop();
  6269   %}
  6271   ins_pc_relative(1);
  6272   ins_pipe( pipe_alu_branch );
  6273 %}
  6275 instruct branchConL_regL_immL0(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  6276   match( If cmp (CmpL src1 zero) );
  6277   effect(USE labl);
  6278   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0" %}
  6279   ins_cost(150);
  6281   ins_encode %{
  6282     Register opr1_reg = as_Register($src1$$reg);
  6283     Label   &target = *($labl$$label);
  6284     int     flag = $cmp$$cmpcode;
  6286     switch(flag)
  6288       case 0x01: //equal
  6289         if (&target) 
  6290            __ beq(opr1_reg, R0, target);
  6291         else
  6292            __ beq(opr1_reg, R0, int(0));
  6293         break;
  6295       case 0x02: //not_equal
  6296         if(&target)
  6297            __ bne(opr1_reg, R0, target);
  6298         else
  6299            __ bne(opr1_reg, R0, (int)0);
  6300         break;
  6302       case 0x03: //greater
  6303         if(&target)
  6304            __ bgtz(opr1_reg, target);
  6305         else
  6306            __ bgtz(opr1_reg, (int)0);
  6307        break;
  6309       case 0x04: //greater_equal
  6310         if(&target)
  6311            __ bgez(opr1_reg, target);
  6312         else
  6313            __ bgez(opr1_reg, (int)0);
  6314         break;
  6316       case 0x05: //less
  6317         __ slt(AT, opr1_reg, R0);
  6318         if(&target)
  6319            __ bne(AT, R0, target);
  6320         else
  6321            __ bne(AT, R0, (int)0);
  6322         break;
  6324       case 0x06: //less_equal
  6325         if (&target) 
  6326            __ blez(opr1_reg, target);
  6327         else
  6328            __ blez(opr1_reg, int(0));
  6329         break;
  6331       default:
  6332           Unimplemented();
  6334 	__ delayed()->nop();
  6335   %}
  6338   ins_pc_relative(1);
  6339   ins_pipe( pipe_alu_branch );
  6340 %}
  6343 //FIXME
  6344 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{
  6345   match( If cmp (CmpF src1 src2) );
  6346   effect(USE labl);
  6347   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg" %}
  6349   ins_encode %{
  6350     FloatRegister reg_op1 = $src1$$FloatRegister;
  6351     FloatRegister reg_op2 = $src2$$FloatRegister;
  6352     Label     &L =  *($labl$$label);
  6353     int     flag = $cmp$$cmpcode;
  6355     switch(flag)
  6357       case 0x01: //equal
  6358         __ c_eq_s(reg_op1, reg_op2);
  6359 	if (&L)
  6360                 __ bc1t(L);
  6361 	else 
  6362                 __ bc1t((int)0);
  6363         break;
  6364       case 0x02: //not_equal
  6365         __ c_eq_s(reg_op1, reg_op2);
  6366 	if (&L)
  6367                 __ bc1f(L);
  6368 	else
  6369                 __ bc1f((int)0);
  6370         break;
  6371       case 0x03: //greater
  6372         __ c_ule_s(reg_op1, reg_op2);
  6373         if(&L)
  6374                 __ bc1f(L);
  6375         else
  6376                 __ bc1f((int)0);
  6377         break;
  6378       case 0x04: //greater_equal
  6379         __ c_ult_s(reg_op1, reg_op2);
  6380         if(&L)
  6381                 __ bc1f(L);
  6382         else
  6383                 __ bc1f((int)0);
  6384         break;
  6385       case 0x05: //less
  6386         __ c_ult_s(reg_op1, reg_op2);
  6387         if(&L)
  6388                 __ bc1t(L);
  6389         else
  6390                 __ bc1t((int)0);
  6391         break;
  6392       case 0x06: //less_equal
  6393         __ c_ule_s(reg_op1, reg_op2);
  6394         if(&L)
  6395                 __ bc1t(L);
  6396         else
  6397                 __ bc1t((int)0);
  6398        break;
  6399       default:
  6400           Unimplemented();
  6402     __ nop();
  6403   %}
  6405   ins_pc_relative(1);
  6406   ins_pipe(pipe_slow);
  6407 %}
  6409 instruct branchConD_reg_reg(cmpOp cmp, regD src1, regD src2, label labl) %{
  6410   match( If cmp (CmpD src1 src2) );
  6411   effect(USE labl);
  6412   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg" %}
  6414   ins_encode %{
  6415     FloatRegister reg_op1 = $src1$$FloatRegister;
  6416     FloatRegister reg_op2 = $src2$$FloatRegister;
  6417     Label     &L =  *($labl$$label);
  6418     int     flag = $cmp$$cmpcode;
  6420     switch(flag)
  6422       case 0x01: //equal
  6423         __ c_eq_d(reg_op1, reg_op2);
  6424 	if (&L)
  6425                 __ bc1t(L);
  6426 	else 
  6427                 __ bc1t((int)0);
  6428         break;
  6429       case 0x02: //not_equal
  6430 //2016/4/19 aoqi: c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
  6431         __ c_eq_d(reg_op1, reg_op2);
  6432 	if (&L)
  6433                 __ bc1f(L);
  6434 	else
  6435                 __ bc1f((int)0);
  6436         break;
  6437       case 0x03: //greater
  6438         __ c_ule_d(reg_op1, reg_op2);
  6439         if(&L)
  6440                 __ bc1f(L);
  6441         else
  6442                 __ bc1f((int)0);
  6443         break;
  6444       case 0x04: //greater_equal
  6445         __ c_ult_d(reg_op1, reg_op2);
  6446         if(&L)
  6447                 __ bc1f(L);
  6448         else
  6449                 __ bc1f((int)0);
  6450         break;
  6451       case 0x05: //less
  6452         __ c_ult_d(reg_op1, reg_op2);
  6453         if(&L)
  6454                 __ bc1t(L);
  6455         else
  6456                 __ bc1t((int)0);
  6457         break;
  6458       case 0x06: //less_equal
  6459         __ c_ule_d(reg_op1, reg_op2);
  6460         if(&L)
  6461                 __ bc1t(L);
  6462         else
  6463                 __ bc1t((int)0);
  6464        break;
  6465       default:
  6466           Unimplemented();
  6468     __ nop();
  6469   %}
  6471   ins_pc_relative(1);
  6472   ins_pipe(pipe_slow);
  6473 %}
  6476 // Call Runtime Instruction
  6477 instruct CallRuntimeDirect(method meth) %{
  6478   match(CallRuntime );
  6479   effect(USE meth);
  6481   ins_cost(300);
  6482   format %{ "CALL,runtime #@CallRuntimeDirect" %}
  6483   ins_encode( Java_To_Runtime( meth ) );
  6484   ins_pipe( pipe_slow );
  6485   ins_alignment(16);
  6486 %}
  6490 //------------------------MemBar Instructions-------------------------------
  6491 //Memory barrier flavors
  6493 instruct membar_acquire() %{
  6494   match(MemBarAcquire);
  6495   ins_cost(0);
  6497   size(0);
  6498   format %{ "MEMBAR-acquire (empty) @ membar_acquire" %}
  6499   ins_encode();
  6500   ins_pipe(empty);
  6501 %}
  6503 instruct load_fence() %{
  6504   match(LoadFence);
  6505   ins_cost(400);
  6507   format %{ "MEMBAR @ load_fence" %}
  6508   ins_encode %{
  6509     __ sync(); 
  6510   %}
  6511   ins_pipe(pipe_slow);
  6512 %}
  6514 instruct membar_acquire_lock()
  6515 %{
  6516   match(MemBarAcquireLock);
  6517   ins_cost(0);
  6519   size(0);
  6520   format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
  6521   ins_encode();
  6522   ins_pipe(empty);
  6523 %}
  6525 instruct membar_release() %{
  6526   match(MemBarRelease);
  6527   ins_cost(0);
  6529   size(0);
  6530   format %{ "MEMBAR-release (empty) @ membar_release" %}
  6531   ins_encode();
  6532   ins_pipe(empty);
  6533 %}
  6535 instruct store_fence() %{
  6536   match(StoreFence);
  6537   ins_cost(400);
  6539   format %{ "MEMBAR @ store_fence" %}
  6541   ins_encode %{
  6542     __ sync(); 
  6543   %}
  6545   ins_pipe(pipe_slow);
  6546 %}
  6548 instruct membar_release_lock()
  6549 %{
  6550   match(MemBarReleaseLock);
  6551   ins_cost(0);
  6553   size(0);
  6554   format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
  6555   ins_encode();
  6556   ins_pipe(empty);
  6557 %}
  6560 instruct membar_volatile() %{
  6561   match(MemBarVolatile);
  6562   ins_cost(400);
  6564   format %{ "MEMBAR-volatile" %}
  6565   ins_encode %{
  6566     if( !os::is_MP() ) return;     // Not needed on single CPU
  6567     __ sync();
  6569   %}
  6570   ins_pipe(pipe_slow);
  6571 %}
  6573 instruct unnecessary_membar_volatile() %{
  6574   match(MemBarVolatile);
  6575   predicate(Matcher::post_store_load_barrier(n));
  6576   ins_cost(0);
  6578   size(0);
  6579   format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
  6580   ins_encode( );
  6581   ins_pipe(empty);
  6582 %}
  6584 instruct membar_storestore() %{
  6585   match(MemBarStoreStore);
  6587   ins_cost(0);
  6588   size(0);
  6589   format %{ "MEMBAR-storestore (empty encoding) @ membar_storestore" %}
  6590   ins_encode( );
  6591   ins_pipe(empty);
  6592 %}
  6594 //----------Move Instructions--------------------------------------------------
  6595 instruct castX2P(mRegP dst, mRegL src) %{
  6596   match(Set dst (CastX2P src));
  6597   format %{ "castX2P  $dst, $src @ castX2P" %}
  6598   ins_encode %{
  6599     Register src = $src$$Register;
  6600     Register dst = $dst$$Register;
  6602 	if(src != dst)
  6603 		__ move(dst, src);
  6604   %}
  6605   ins_cost(10);
  6606   ins_pipe( ialu_regI_mov );
  6607 %}
  6609 instruct castP2X(mRegL dst, mRegP src ) %{
  6610   match(Set dst (CastP2X src));
  6612   format %{ "mov    $dst, $src\t  #@castP2X" %}
  6613   ins_encode %{
  6614     Register src = $src$$Register;
  6615     Register dst = $dst$$Register;
  6617 	if(src != dst)
  6618 		__ move(dst, src);    
  6619   %}
  6620   ins_pipe( ialu_regI_mov );
  6621 %}
  6623 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
  6624   match(Set dst (MoveF2I src));
  6625   effect(DEF dst, USE src);
  6626   ins_cost(85);
  6627   format %{ "MoveF2I   $dst, $src @ MoveF2I_reg_reg" %}
  6628   ins_encode %{
  6629     Register dst = as_Register($dst$$reg);
  6630     FloatRegister src = as_FloatRegister($src$$reg);
  6632     __ mfc1(dst, src);
  6633   %}
  6634   ins_pipe( pipe_slow );
  6635 %}
  6637 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
  6638   match(Set dst (MoveI2F src));
  6639   effect(DEF dst, USE src);
  6640   ins_cost(85);
  6641   format %{ "MoveI2F   $dst, $src @ MoveI2F_reg_reg" %}
  6642   ins_encode %{
  6643     Register src = as_Register($src$$reg);
  6644     FloatRegister dst = as_FloatRegister($dst$$reg);
  6646     __ mtc1(src, dst);
  6647   %}
  6648   ins_pipe( pipe_slow );
  6649 %}
  6651 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
  6652   match(Set dst (MoveD2L src));
  6653   effect(DEF dst, USE src);
  6654   ins_cost(85);
  6655   format %{ "MoveD2L   $dst, $src @ MoveD2L_reg_reg" %}
  6656   ins_encode %{
  6657     Register dst = as_Register($dst$$reg);
  6658     FloatRegister src = as_FloatRegister($src$$reg);
  6660     __ dmfc1(dst, src);
  6661   %}
  6662   ins_pipe( pipe_slow );
  6663 %}
  6665 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
  6666   match(Set dst (MoveL2D src));
  6667   effect(DEF dst, USE src);
  6668   ins_cost(85);
  6669   format %{ "MoveL2D   $dst, $src @ MoveL2D_reg_reg" %}
  6670   ins_encode %{
  6671     FloatRegister dst = as_FloatRegister($dst$$reg);
  6672     Register src = as_Register($src$$reg);
  6674     __ dmtc1(src, dst);
  6675   %}
  6676   ins_pipe( pipe_slow );
  6677 %}
  6679 //----------Conditional Move---------------------------------------------------
  6680 // Conditional move
  6681 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  6682   match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  6683   ins_cost(80);
  6684   format %{
  6685              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpI_reg_reg\n"
  6686              "\tCMOV  $dst,$src \t @cmovI_cmpI_reg_reg"
  6687          %}
  6689   ins_encode %{
  6690     Register op1 = $tmp1$$Register;
  6691     Register op2 = $tmp2$$Register;
  6692     Register dst = $dst$$Register;
  6693     Register src = $src$$Register;
  6694     int     flag = $cop$$cmpcode;
  6696     switch(flag)
  6698       case 0x01: //equal
  6699         __ subu32(AT, op1, op2);
  6700         __ movz(dst, src, AT);
  6701         break;
  6703       case 0x02: //not_equal
  6704         __ subu32(AT, op1, op2);
  6705         __ movn(dst, src, AT);
  6706         break;
  6708       case 0x03: //great
  6709         __ slt(AT, op2, op1);
  6710         __ movn(dst, src, AT);
  6711         break;
  6713       case 0x04: //great_equal
  6714         __ slt(AT, op1, op2);
  6715         __ movz(dst, src, AT);
  6716         break;
  6718       case 0x05: //less
  6719         __ slt(AT, op1, op2);
  6720         __ movn(dst, src, AT);
  6721         break;
  6723       case 0x06: //less_equal
  6724         __ slt(AT, op2, op1);
  6725         __ movz(dst, src, AT);
  6726        break;
  6728       default:
  6729           Unimplemented();
  6731   %}
  6733   ins_pipe( pipe_slow );
  6734 %}
  6736 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  6737   match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  6738   ins_cost(80);
  6739   format %{
  6740              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
  6741              "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
  6742          %}
  6743   ins_encode %{
  6744     Register op1 = $tmp1$$Register;
  6745     Register op2 = $tmp2$$Register;
  6746     Register dst = $dst$$Register;
  6747     Register src = $src$$Register;
  6748     int     flag = $cop$$cmpcode;
  6750     switch(flag)
  6752       case 0x01: //equal
  6753         __ subu(AT, op1, op2);
  6754         __ movz(dst, src, AT);
  6755         break;
  6757       case 0x02: //not_equal
  6758         __ subu(AT, op1, op2);
  6759         __ movn(dst, src, AT);
  6760         break;
  6762       case 0x03: //above
  6763         __ sltu(AT, op2, op1);
  6764         __ movn(dst, src, AT);
  6765         break;
  6767       case 0x04: //above_equal
  6768         __ sltu(AT, op1, op2);
  6769         __ movz(dst, src, AT);
  6770         break;
  6772       case 0x05: //below
  6773         __ sltu(AT, op1, op2);
  6774         __ movn(dst, src, AT);
  6775         break;
  6777       case 0x06: //below_equal
  6778         __ sltu(AT, op2, op1);
  6779         __ movz(dst, src, AT);
  6780        break;
  6782       default:
  6783           Unimplemented();
  6785   %}
  6787   ins_pipe( pipe_slow );
  6788 %}
  6790 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  6791   match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  6792   ins_cost(80);
  6793   format %{
  6794              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
  6795              "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
  6796          %}
  6797   ins_encode %{
  6798     Register op1 = $tmp1$$Register;
  6799     Register op2 = $tmp2$$Register;
  6800     Register dst = $dst$$Register;
  6801     Register src = $src$$Register;
  6802     int     flag = $cop$$cmpcode;
  6804     switch(flag)
  6806       case 0x01: //equal
  6807         __ subu32(AT, op1, op2);
  6808         __ movz(dst, src, AT);
  6809         break;
  6811       case 0x02: //not_equal
  6812         __ subu32(AT, op1, op2);
  6813         __ movn(dst, src, AT);
  6814         break;
  6816       case 0x03: //above
  6817         __ sltu(AT, op2, op1);
  6818         __ movn(dst, src, AT);
  6819         break;
  6821       case 0x04: //above_equal
  6822         __ sltu(AT, op1, op2);
  6823         __ movz(dst, src, AT);
  6824         break;
  6826       case 0x05: //below
  6827         __ sltu(AT, op1, op2);
  6828         __ movn(dst, src, AT);
  6829         break;
  6831       case 0x06: //below_equal
  6832         __ sltu(AT, op2, op1);
  6833         __ movz(dst, src, AT);
  6834        break;
  6836       default:
  6837           Unimplemented();
  6839   %}
  6841   ins_pipe( pipe_slow );
  6842 %}
  6844 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  6845   match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  6846   ins_cost(80);
  6847   format %{
  6848              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
  6849              "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
  6850          %}
  6851   ins_encode %{
  6852     Register op1 = $tmp1$$Register;
  6853     Register op2 = $tmp2$$Register;
  6854     Register dst = $dst$$Register;
  6855     Register src = $src$$Register;
  6856     int     flag = $cop$$cmpcode;
  6858     switch(flag)
  6860       case 0x01: //equal
  6861         __ subu32(AT, op1, op2);
  6862         __ movz(dst, src, AT);
  6863         break;
  6865       case 0x02: //not_equal
  6866         __ subu32(AT, op1, op2);
  6867         __ movn(dst, src, AT);
  6868         break;
  6870       case 0x03: //above
  6871         __ sltu(AT, op2, op1);
  6872         __ movn(dst, src, AT);
  6873         break;
  6875       case 0x04: //above_equal
  6876         __ sltu(AT, op1, op2);
  6877         __ movz(dst, src, AT);
  6878         break;
  6880       case 0x05: //below
  6881         __ sltu(AT, op1, op2);
  6882         __ movn(dst, src, AT);
  6883         break;
  6885       case 0x06: //below_equal
  6886         __ sltu(AT, op2, op1);
  6887         __ movz(dst, src, AT);
  6888        break;
  6890       default:
  6891           Unimplemented();
  6893   %}
  6895   ins_pipe( pipe_slow );
  6896 %}
  6898 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  6899   match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  6900   ins_cost(80);
  6901   format %{
  6902              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
  6903              "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
  6904          %}
  6905   ins_encode %{
  6906     Register op1 = $tmp1$$Register;
  6907     Register op2 = $tmp2$$Register;
  6908     Register dst = $dst$$Register;
  6909     Register src = $src$$Register;
  6910     int     flag = $cop$$cmpcode;
  6912     switch(flag)
  6914       case 0x01: //equal
  6915         __ subu(AT, op1, op2);
  6916         __ movz(dst, src, AT);
  6917         break;
  6919       case 0x02: //not_equal
  6920         __ subu(AT, op1, op2);
  6921         __ movn(dst, src, AT);
  6922         break;
  6924       case 0x03: //above
  6925         __ sltu(AT, op2, op1);
  6926         __ movn(dst, src, AT);
  6927         break;
  6929       case 0x04: //above_equal
  6930         __ sltu(AT, op1, op2);
  6931         __ movz(dst, src, AT);
  6932         break;
  6934       case 0x05: //below
  6935         __ sltu(AT, op1, op2);
  6936         __ movn(dst, src, AT);
  6937         break;
  6939       case 0x06: //below_equal
  6940         __ sltu(AT, op2, op1);
  6941         __ movz(dst, src, AT);
  6942        break;
  6944       default:
  6945           Unimplemented();
  6947   %}
  6949   ins_pipe( pipe_slow );
  6950 %}
  6952 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
  6953   match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  6954   ins_cost(80);
  6955   format %{
  6956              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpD_reg_reg\n"
  6957              "\tCMOV  $dst,$src \t @cmovP_cmpD_reg_reg"
  6958          %}
  6959   ins_encode %{
  6960     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  6961     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  6962     Register dst = as_Register($dst$$reg);
  6963     Register src = as_Register($src$$reg);
  6965     int     flag = $cop$$cmpcode;
  6967     switch(flag)
  6969       case 0x01: //equal
  6970         __ c_eq_d(reg_op1, reg_op2);
  6971         __ movt(dst, src);
  6972         break;
  6973       case 0x02: //not_equal
  6974         __ c_eq_d(reg_op1, reg_op2);
  6975         __ movf(dst, src);
  6976         break;
  6977       case 0x03: //greater
  6978         __ c_ole_d(reg_op1, reg_op2);
  6979         __ movf(dst, src);
  6980         break;
  6981       case 0x04: //greater_equal
  6982         __ c_olt_d(reg_op1, reg_op2);
  6983         __ movf(dst, src);
  6984         break;
  6985       case 0x05: //less
  6986         __ c_ult_d(reg_op1, reg_op2);
  6987         __ movt(dst, src);
  6988         break;
  6989       case 0x06: //less_equal
  6990         __ c_ule_d(reg_op1, reg_op2);
  6991         __ movt(dst, src);
  6992         break;
  6993       default:
  6994           Unimplemented();
  6996   %}
  6998   ins_pipe( pipe_slow );
  6999 %}
  7002 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  7003   match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  7004   ins_cost(80);
  7005   format %{
  7006              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
  7007              "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
  7008          %}
  7009   ins_encode %{
  7010     Register op1 = $tmp1$$Register;
  7011     Register op2 = $tmp2$$Register;
  7012     Register dst = $dst$$Register;
  7013     Register src = $src$$Register;
  7014     int     flag = $cop$$cmpcode;
  7016     switch(flag)
  7018       case 0x01: //equal
  7019         __ subu32(AT, op1, op2);
  7020         __ movz(dst, src, AT);
  7021         break;
  7023       case 0x02: //not_equal
  7024         __ subu32(AT, op1, op2);
  7025         __ movn(dst, src, AT);
  7026         break;
  7028       case 0x03: //above
  7029         __ sltu(AT, op2, op1);
  7030         __ movn(dst, src, AT);
  7031         break;
  7033       case 0x04: //above_equal
  7034         __ sltu(AT, op1, op2);
  7035         __ movz(dst, src, AT);
  7036         break;
  7038       case 0x05: //below
  7039         __ sltu(AT, op1, op2);
  7040         __ movn(dst, src, AT);
  7041         break;
  7043       case 0x06: //below_equal
  7044         __ sltu(AT, op2, op1);
  7045         __ movz(dst, src, AT);
  7046        break;
  7048       default:
  7049           Unimplemented();
  7051   %}
  7053   ins_pipe( pipe_slow );
  7054 %}
  7057 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  7058   match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  7059   ins_cost(80);
  7060   format %{
  7061              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
  7062              "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
  7063          %}
  7064   ins_encode %{
  7065     Register op1 = $tmp1$$Register;
  7066     Register op2 = $tmp2$$Register;
  7067     Register dst = $dst$$Register;
  7068     Register src = $src$$Register;
  7069     int     flag = $cop$$cmpcode;
  7071     switch(flag)
  7073       case 0x01: //equal
  7074         __ subu(AT, op1, op2);
  7075         __ movz(dst, src, AT);
  7076         break;
  7078       case 0x02: //not_equal
  7079         __ subu(AT, op1, op2);
  7080         __ movn(dst, src, AT);
  7081         break;
  7083       case 0x03: //above
  7084         __ sltu(AT, op2, op1);
  7085         __ movn(dst, src, AT);
  7086         break;
  7088       case 0x04: //above_equal
  7089         __ sltu(AT, op1, op2);
  7090         __ movz(dst, src, AT);
  7091         break;
  7093       case 0x05: //below
  7094         __ sltu(AT, op1, op2);
  7095         __ movn(dst, src, AT);
  7096         break;
  7098       case 0x06: //below_equal
  7099         __ sltu(AT, op2, op1);
  7100         __ movz(dst, src, AT);
  7101        break;
  7103       default:
  7104           Unimplemented();
  7106   %}
  7108   ins_pipe( pipe_slow );
  7109 %}
  7111 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  7112   match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  7113   ins_cost(80);
  7114   format %{
  7115              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpL_reg_reg\n"
  7116              "\tCMOV  $dst,$src \t @cmovI_cmpL_reg_reg"
  7117          %}
  7118   ins_encode %{
  7119     Register opr1 = as_Register($tmp1$$reg);
  7120     Register opr2 = as_Register($tmp2$$reg);
  7121     Register dst     = $dst$$Register;
  7122     Register src     = $src$$Register;
  7123     int     flag = $cop$$cmpcode;
  7125     switch(flag)
  7127       case 0x01: //equal
  7128         __ subu(AT, opr1, opr2);
  7129         __ movz(dst, src, AT);
  7130         break;
  7132       case 0x02: //not_equal
  7133         __ subu(AT, opr1, opr2);
  7134         __ movn(dst, src, AT);
  7135         break;
  7137       case 0x03: //greater
  7138 	__ slt(AT, opr2, opr1);
  7139         __ movn(dst, src, AT);
  7140         break;
  7142       case 0x04: //greater_equal
  7143         __ slt(AT, opr1, opr2);
  7144         __ movz(dst, src, AT);
  7145         break;
  7147       case 0x05: //less
  7148         __ slt(AT, opr1, opr2);
  7149         __ movn(dst, src, AT);
  7150         break;
  7152       case 0x06: //less_equal
  7153         __ slt(AT, opr2, opr1);
  7154         __ movz(dst, src, AT);
  7155         break;
  7157       default:
  7158           Unimplemented();
  7160   %}
  7162   ins_pipe( pipe_slow );
  7163 %}
  7165 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  7166   match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  7167   ins_cost(80);
  7168   format %{
  7169              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpL_reg_reg\n"
  7170              "\tCMOV  $dst,$src \t @cmovP_cmpL_reg_reg"
  7171          %}
  7172   ins_encode %{
  7173     Register opr1 = as_Register($tmp1$$reg);
  7174     Register opr2 = as_Register($tmp2$$reg);
  7175     Register dst     = $dst$$Register;
  7176     Register src     = $src$$Register;
  7177     int     flag = $cop$$cmpcode;
  7179     switch(flag)
  7181       case 0x01: //equal
  7182         __ subu(AT, opr1, opr2);
  7183         __ movz(dst, src, AT);
  7184         break;
  7186       case 0x02: //not_equal
  7187         __ subu(AT, opr1, opr2);
  7188         __ movn(dst, src, AT);
  7189         break;
  7191       case 0x03: //greater
  7192         __ slt(AT, opr2, opr1);
  7193         __ movn(dst, src, AT);
  7194         break;
  7196       case 0x04: //greater_equal
  7197         __ slt(AT, opr1, opr2);
  7198         __ movz(dst, src, AT);
  7199         break;
  7201       case 0x05: //less
  7202         __ slt(AT, opr1, opr2);
  7203         __ movn(dst, src, AT);
  7204         break;
  7206       case 0x06: //less_equal
  7207         __ slt(AT, opr2, opr1);
  7208         __ movz(dst, src, AT);
  7209         break;
  7211       default:
  7212           Unimplemented();
  7214   %}
  7216   ins_pipe( pipe_slow );
  7217 %}
  7219 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
  7220   match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  7221   ins_cost(80);
  7222   format %{
  7223              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpD_reg_reg\n"
  7224              "\tCMOV  $dst,$src \t @cmovI_cmpD_reg_reg"
  7225          %}
  7226   ins_encode %{
  7227     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  7228     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  7229     Register dst = as_Register($dst$$reg);
  7230     Register src = as_Register($src$$reg);
  7232     int     flag = $cop$$cmpcode;
  7234     switch(flag)
  7236       case 0x01: //equal
  7237         __ c_eq_d(reg_op1, reg_op2);
  7238         __ movt(dst, src);
  7239         break;
  7240       case 0x02: //not_equal
  7241 //2016/4/19 aoqi: See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
  7242         __ c_eq_d(reg_op1, reg_op2);
  7243         __ movf(dst, src);
  7244         break;
  7245       case 0x03: //greater
  7246         __ c_ole_d(reg_op1, reg_op2);
  7247         __ movf(dst, src);
  7248         break;
  7249       case 0x04: //greater_equal
  7250         __ c_olt_d(reg_op1, reg_op2);
  7251         __ movf(dst, src);
  7252         break;
  7253       case 0x05: //less
  7254         __ c_ult_d(reg_op1, reg_op2);
  7255         __ movt(dst, src);
  7256         break;
  7257       case 0x06: //less_equal
  7258         __ c_ule_d(reg_op1, reg_op2);
  7259         __ movt(dst, src);
  7260         break;
  7261       default:
  7262           Unimplemented();
  7264   %}
  7266   ins_pipe( pipe_slow );
  7267 %}
  7270 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  7271   match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  7272   ins_cost(80);
  7273   format %{
  7274              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
  7275              "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
  7276          %}
  7277   ins_encode %{
  7278     Register op1 = $tmp1$$Register;
  7279     Register op2 = $tmp2$$Register;
  7280     Register dst = $dst$$Register;
  7281     Register src = $src$$Register;
  7282     int     flag = $cop$$cmpcode;
  7284     switch(flag)
  7286       case 0x01: //equal
  7287         __ subu(AT, op1, op2);
  7288         __ movz(dst, src, AT);
  7289         break;
  7291       case 0x02: //not_equal
  7292         __ subu(AT, op1, op2);
  7293         __ movn(dst, src, AT);
  7294         break;
  7296       case 0x03: //above
  7297         __ sltu(AT, op2, op1);
  7298         __ movn(dst, src, AT);
  7299         break;
  7301       case 0x04: //above_equal
  7302         __ sltu(AT, op1, op2);
  7303         __ movz(dst, src, AT);
  7304         break;
  7306       case 0x05: //below
  7307         __ sltu(AT, op1, op2);
  7308         __ movn(dst, src, AT);
  7309         break;
  7311       case 0x06: //below_equal
  7312         __ sltu(AT, op2, op1);
  7313         __ movz(dst, src, AT);
  7314        break;
  7316       default:
  7317           Unimplemented();
  7319   %}
  7321   ins_pipe( pipe_slow );
  7322 %}
  7324 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  7325   match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  7326   ins_cost(80);
  7327   format %{
  7328              "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
  7329              "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
  7330          %}
  7331   ins_encode %{
  7332     Register op1 = $tmp1$$Register;
  7333     Register op2 = $tmp2$$Register;
  7334     Register dst = $dst$$Register;
  7335     Register src = $src$$Register;
  7336     int     flag = $cop$$cmpcode;
  7338     switch(flag)
  7340       case 0x01: //equal
  7341         __ subu32(AT, op1, op2);
  7342         __ movz(dst, src, AT);
  7343         break;
  7345       case 0x02: //not_equal
  7346         __ subu32(AT, op1, op2);
  7347         __ movn(dst, src, AT);
  7348         break;
  7350       case 0x03: //above
  7351         __ slt(AT, op2, op1);
  7352         __ movn(dst, src, AT);
  7353         break;
  7355       case 0x04: //above_equal
  7356         __ slt(AT, op1, op2);
  7357         __ movz(dst, src, AT);
  7358         break;
  7360       case 0x05: //below
  7361         __ slt(AT, op1, op2);
  7362         __ movn(dst, src, AT);
  7363         break;
  7365       case 0x06: //below_equal
  7366         __ slt(AT, op2, op1);
  7367         __ movz(dst, src, AT);
  7368        break;
  7370       default:
  7371           Unimplemented();
  7373   %}
  7375   ins_pipe( pipe_slow );
  7376 %}
  7378 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  7379   match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  7380   ins_cost(80);
  7381   format %{
  7382              "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
  7383              "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
  7384          %}
  7385   ins_encode %{
  7386     Register op1 = $tmp1$$Register;
  7387     Register op2 = $tmp2$$Register;
  7388     Register dst = $dst$$Register;
  7389     Register src = $src$$Register;
  7390     int     flag = $cop$$cmpcode;
  7392     switch(flag)
  7394       case 0x01: //equal
  7395         __ subu32(AT, op1, op2);
  7396         __ movz(dst, src, AT);
  7397         break;
  7399       case 0x02: //not_equal
  7400         __ subu32(AT, op1, op2);
  7401         __ movn(dst, src, AT);
  7402         break;
  7404       case 0x03: //above
  7405         __ slt(AT, op2, op1);
  7406         __ movn(dst, src, AT);
  7407         break;
  7409       case 0x04: //above_equal
  7410         __ slt(AT, op1, op2);
  7411         __ movz(dst, src, AT);
  7412         break;
  7414       case 0x05: //below
  7415         __ slt(AT, op1, op2);
  7416         __ movn(dst, src, AT);
  7417         break;
  7419       case 0x06: //below_equal
  7420         __ slt(AT, op2, op1);
  7421         __ movz(dst, src, AT);
  7422        break;
  7424       default:
  7425           Unimplemented();
  7427   %}
  7429   ins_pipe( pipe_slow );
  7430 %}
  7433 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  7434   match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  7435   ins_cost(80);
  7436   format %{
  7437              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpI_reg_reg\n"
  7438              "\tCMOV  $dst,$src \t @cmovL_cmpI_reg_reg"
  7439          %}
  7441   ins_encode %{
  7442     Register op1 = $tmp1$$Register;
  7443     Register op2 = $tmp2$$Register;
  7444     Register dst = as_Register($dst$$reg);
  7445     Register src = as_Register($src$$reg);
  7446     int     flag = $cop$$cmpcode;
  7448     switch(flag)
  7450       case 0x01: //equal
  7451         __ subu32(AT, op1, op2);
  7452         __ movz(dst, src, AT);
  7453         break;
  7455       case 0x02: //not_equal
  7456         __ subu32(AT, op1, op2);
  7457         __ movn(dst, src, AT);
  7458         break;
  7460       case 0x03: //great
  7461         __ slt(AT, op2, op1);
  7462         __ movn(dst, src, AT);
  7463         break;
  7465       case 0x04: //great_equal
  7466         __ slt(AT, op1, op2);
  7467         __ movz(dst, src, AT);
  7468         break;
  7470       case 0x05: //less
  7471         __ slt(AT, op1, op2);
  7472         __ movn(dst, src, AT);
  7473         break;
  7475       case 0x06: //less_equal
  7476         __ slt(AT, op2, op1);
  7477         __ movz(dst, src, AT);
  7478        break;
  7480       default:
  7481           Unimplemented();
  7483   %}
  7485   ins_pipe( pipe_slow );
  7486 %}
  7488 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  7489   match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  7490   ins_cost(80);
  7491   format %{
  7492              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpL_reg_reg\n"
  7493              "\tCMOV  $dst,$src \t @cmovL_cmpL_reg_reg"
  7494          %}
  7495   ins_encode %{
  7496     Register opr1 = as_Register($tmp1$$reg);
  7497     Register opr2 = as_Register($tmp2$$reg);
  7498     Register dst  = as_Register($dst$$reg);
  7499     Register src  = as_Register($src$$reg);
  7500     int     flag = $cop$$cmpcode;
  7502     switch(flag)
  7504       case 0x01: //equal
  7505         __ subu(AT, opr1, opr2);
  7506         __ movz(dst, src, AT);
  7507         break;
  7509       case 0x02: //not_equal
  7510         __ subu(AT, opr1, opr2);
  7511         __ movn(dst, src, AT);
  7512         break;
  7514       case 0x03: //greater
  7515         __ slt(AT, opr2, opr1);
  7516         __ movn(dst, src, AT);
  7517         break;
  7519       case 0x04: //greater_equal
  7520         __ slt(AT, opr1, opr2);
  7521         __ movz(dst, src, AT);
  7522         break;
  7524       case 0x05: //less
  7525         __ slt(AT, opr1, opr2);
  7526         __ movn(dst, src, AT);
  7527         break;
  7529       case 0x06: //less_equal
  7530        __ slt(AT, opr2, opr1);
  7531        __ movz(dst, src, AT);
  7532        break;
  7534       default:
  7535           Unimplemented();
  7537   %}
  7539   ins_pipe( pipe_slow );
  7540 %}
  7542 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  7543   match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  7544   ins_cost(80);
  7545   format %{
  7546              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
  7547              "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
  7548          %}
  7549   ins_encode %{
  7550     Register op1 = $tmp1$$Register;
  7551     Register op2 = $tmp2$$Register;
  7552     Register dst = $dst$$Register;
  7553     Register src = $src$$Register;
  7554     int     flag = $cop$$cmpcode;
  7556     switch(flag)
  7558       case 0x01: //equal
  7559         __ subu32(AT, op1, op2);
  7560         __ movz(dst, src, AT);
  7561         break;
  7563       case 0x02: //not_equal
  7564         __ subu32(AT, op1, op2);
  7565         __ movn(dst, src, AT);
  7566         break;
  7568       case 0x03: //above
  7569         __ sltu(AT, op2, op1);
  7570         __ movn(dst, src, AT);
  7571         break;
  7573       case 0x04: //above_equal
  7574         __ sltu(AT, op1, op2);
  7575         __ movz(dst, src, AT);
  7576         break;
  7578       case 0x05: //below
  7579         __ sltu(AT, op1, op2);
  7580         __ movn(dst, src, AT);
  7581         break;
  7583       case 0x06: //below_equal
  7584         __ sltu(AT, op2, op1);
  7585         __ movz(dst, src, AT);
  7586         break;
  7588       default:
  7589           Unimplemented();
  7591   %}
  7593   ins_pipe( pipe_slow );
  7594 %}
  7597 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
  7598   match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  7599   ins_cost(80);
  7600   format %{
  7601              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpD_reg_reg\n"
  7602              "\tCMOV  $dst,$src \t @cmovL_cmpD_reg_reg"
  7603          %}
  7604   ins_encode %{
  7605     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  7606     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  7607     Register dst = as_Register($dst$$reg);
  7608     Register src = as_Register($src$$reg);
  7610     int     flag = $cop$$cmpcode;
  7612     switch(flag)
  7614       case 0x01: //equal
  7615         __ c_eq_d(reg_op1, reg_op2);
  7616         __ movt(dst, src);
  7617         break;
  7618       case 0x02: //not_equal
  7619         __ c_eq_d(reg_op1, reg_op2);
  7620         __ movf(dst, src);
  7621         break;
  7622       case 0x03: //greater
  7623         __ c_ole_d(reg_op1, reg_op2);
  7624         __ movf(dst, src);
  7625         break;
  7626       case 0x04: //greater_equal
  7627         __ c_olt_d(reg_op1, reg_op2);
  7628         __ movf(dst, src);
  7629         break;
  7630       case 0x05: //less
  7631         __ c_ult_d(reg_op1, reg_op2);
  7632         __ movt(dst, src);
  7633         break;
  7634       case 0x06: //less_equal
  7635         __ c_ule_d(reg_op1, reg_op2);
  7636         __ movt(dst, src);
  7637         break;
  7638       default:
  7639           Unimplemented();
  7641   %}
  7643   ins_pipe( pipe_slow );
  7644 %}
  7646 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
  7647   match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  7648   ins_cost(200);
  7649   format %{
  7650              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpD_reg_reg\n"
  7651              "\tCMOV  $dst,$src \t @cmovD_cmpD_reg_reg"
  7652          %}
  7653   ins_encode %{
  7654     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  7655     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  7656     FloatRegister dst = as_FloatRegister($dst$$reg);
  7657     FloatRegister src = as_FloatRegister($src$$reg);
  7659     int     flag = $cop$$cmpcode;
  7661     Label L;
  7663     switch(flag)
  7665       case 0x01: //equal
  7666         __ c_eq_d(reg_op1, reg_op2);
  7667         __ bc1f(L);
  7668         __ nop();
  7669         __ mov_d(dst, src);
  7670         __ bind(L); 
  7671         break;
  7672       case 0x02: //not_equal
  7673 //2016/4/19 aoqi: See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
  7674         __ c_eq_d(reg_op1, reg_op2);
  7675         __ bc1t(L);
  7676         __ nop();
  7677         __ mov_d(dst, src);
  7678         __ bind(L); 
  7679         break;
  7680       case 0x03: //greater
  7681         __ c_ole_d(reg_op1, reg_op2);
  7682         __ bc1t(L);
  7683         __ nop();
  7684         __ mov_d(dst, src);
  7685         __ bind(L); 
  7686         break;
  7687       case 0x04: //greater_equal
  7688         __ c_olt_d(reg_op1, reg_op2);
  7689         __ bc1t(L);
  7690         __ nop();
  7691         __ mov_d(dst, src);
  7692         __ bind(L); 
  7693         break;
  7694       case 0x05: //less
  7695         __ c_ult_d(reg_op1, reg_op2);
  7696         __ bc1f(L);
  7697         __ nop();
  7698         __ mov_d(dst, src);
  7699         __ bind(L); 
  7700         break;
  7701       case 0x06: //less_equal
  7702         __ c_ule_d(reg_op1, reg_op2);
  7703         __ bc1f(L);
  7704         __ nop();
  7705         __ mov_d(dst, src);
  7706         __ bind(L); 
  7707         break;
  7708       default:
  7709           Unimplemented();
  7711   %}
  7713   ins_pipe( pipe_slow );
  7714 %}
  7716 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  7717   match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  7718   ins_cost(200);
  7719   format %{
  7720              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpI_reg_reg\n"
  7721              "\tCMOV  $dst, $src \t @cmovF_cmpI_reg_reg"
  7722          %}
  7724   ins_encode %{
  7725     Register op1 = $tmp1$$Register;
  7726     Register op2 = $tmp2$$Register;
  7727     FloatRegister dst = as_FloatRegister($dst$$reg);
  7728     FloatRegister src = as_FloatRegister($src$$reg);
  7729     int     flag = $cop$$cmpcode;
  7730     Label      L; 
  7732     switch(flag)
  7734       case 0x01: //equal
  7735        	__ bne(op1, op2, L); 
  7736         __ nop();
  7737         __ mov_s(dst, src);
  7738         __ bind(L);
  7739         break;
  7740       case 0x02: //not_equal
  7741        	__ beq(op1, op2, L); 
  7742         __ nop();
  7743         __ mov_s(dst, src);
  7744         __ bind(L);
  7745         break;
  7746       case 0x03: //great
  7747         __ slt(AT, op2, op1);
  7748        	__ beq(AT, R0, L);
  7749         __ nop();
  7750         __ mov_s(dst, src);
  7751         __ bind(L);
  7752         break;
  7753       case 0x04: //great_equal
  7754         __ slt(AT, op1, op2);
  7755         __ bne(AT, R0, L); 
  7756         __ nop();
  7757         __ mov_s(dst, src);
  7758         __ bind(L);
  7759         break;
  7760       case 0x05: //less
  7761         __ slt(AT, op1, op2);
  7762        	__ beq(AT, R0, L);
  7763         __ nop();
  7764         __ mov_s(dst, src);
  7765         __ bind(L);
  7766         break;
  7767       case 0x06: //less_equal
  7768         __ slt(AT, op2, op1);
  7769        	__ bne(AT, R0, L); 
  7770         __ nop();
  7771         __ mov_s(dst, src);
  7772         __ bind(L);
  7773        break;
  7774       default:
  7775           Unimplemented();
  7777   %}
  7779   ins_pipe( pipe_slow );
  7780 %}
  7782 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  7783   match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  7784   ins_cost(200);
  7785   format %{
  7786              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpI_reg_reg\n"
  7787              "\tCMOV  $dst, $src \t @cmovD_cmpI_reg_reg"
  7788          %}
  7790   ins_encode %{
  7791     Register op1 = $tmp1$$Register;
  7792     Register op2 = $tmp2$$Register;
  7793     FloatRegister dst = as_FloatRegister($dst$$reg);
  7794     FloatRegister src = as_FloatRegister($src$$reg);
  7795     int     flag = $cop$$cmpcode;
  7796     Label      L; 
  7798     switch(flag)
  7800       case 0x01: //equal
  7801        	__ bne(op1, op2, L); 
  7802         __ nop();
  7803         __ mov_d(dst, src);
  7804         __ bind(L);
  7805         break;
  7806       case 0x02: //not_equal
  7807        	__ beq(op1, op2, L); 
  7808         __ nop();
  7809         __ mov_d(dst, src);
  7810         __ bind(L);
  7811         break;
  7812       case 0x03: //great
  7813         __ slt(AT, op2, op1);
  7814        	__ beq(AT, R0, L);
  7815         __ nop();
  7816         __ mov_d(dst, src);
  7817         __ bind(L);
  7818         break;
  7819       case 0x04: //great_equal
  7820         __ slt(AT, op1, op2);
  7821         __ bne(AT, R0, L); 
  7822         __ nop();
  7823         __ mov_d(dst, src);
  7824         __ bind(L);
  7825         break;
  7826       case 0x05: //less
  7827         __ slt(AT, op1, op2);
  7828        	__ beq(AT, R0, L);
  7829         __ nop();
  7830         __ mov_d(dst, src);
  7831         __ bind(L);
  7832         break;
  7833       case 0x06: //less_equal
  7834         __ slt(AT, op2, op1);
  7835        	__ bne(AT, R0, L); 
  7836         __ nop();
  7837         __ mov_d(dst, src);
  7838         __ bind(L);
  7839        break;
  7840       default:
  7841           Unimplemented();
  7843   %}
  7845   ins_pipe( pipe_slow );
  7846 %}
  7848 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
  7849   match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  7850   ins_cost(200);
  7851   format %{
  7852              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpP_reg_reg\n"
  7853              "\tCMOV  $dst, $src \t @cmovD_cmpP_reg_reg"
  7854          %}
  7856   ins_encode %{
  7857     Register op1 = $tmp1$$Register;
  7858     Register op2 = $tmp2$$Register;
  7859     FloatRegister dst = as_FloatRegister($dst$$reg);
  7860     FloatRegister src = as_FloatRegister($src$$reg);
  7861     int     flag = $cop$$cmpcode;
  7862     Label      L; 
  7864     switch(flag)
  7866       case 0x01: //equal
  7867        	__ bne(op1, op2, L); 
  7868         __ nop();
  7869         __ mov_d(dst, src);
  7870         __ bind(L);
  7871         break;
  7872       case 0x02: //not_equal
  7873        	__ beq(op1, op2, L); 
  7874         __ nop();
  7875         __ mov_d(dst, src);
  7876         __ bind(L);
  7877         break;
  7878       case 0x03: //great
  7879         __ slt(AT, op2, op1);
  7880        	__ beq(AT, R0, L);
  7881         __ nop();
  7882         __ mov_d(dst, src);
  7883         __ bind(L);
  7884         break;
  7885       case 0x04: //great_equal
  7886         __ slt(AT, op1, op2);
  7887         __ bne(AT, R0, L); 
  7888         __ nop();
  7889         __ mov_d(dst, src);
  7890         __ bind(L);
  7891         break;
  7892       case 0x05: //less
  7893         __ slt(AT, op1, op2);
  7894        	__ beq(AT, R0, L);
  7895         __ nop();
  7896         __ mov_d(dst, src);
  7897         __ bind(L);
  7898         break;
  7899       case 0x06: //less_equal
  7900         __ slt(AT, op2, op1);
  7901        	__ bne(AT, R0, L); 
  7902         __ nop();
  7903         __ mov_d(dst, src);
  7904         __ bind(L);
  7905        break;
  7906       default:
  7907           Unimplemented();
  7909   %}
  7911   ins_pipe( pipe_slow );
  7912 %}
  7914 //FIXME
  7915 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
  7916   match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  7917   ins_cost(80);
  7918   format %{
  7919              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpF_reg_reg\n"
  7920              "\tCMOV  $dst,$src \t @cmovI_cmpF_reg_reg"
  7921          %}
  7923   ins_encode %{
  7924     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  7925     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  7926     Register dst = $dst$$Register;
  7927     Register src = $src$$Register;
  7928     int     flag = $cop$$cmpcode;
  7930     switch(flag)
  7932       case 0x01: //equal
  7933         __ c_eq_s(reg_op1, reg_op2);
  7934         __ movt(dst, src);
  7935         break;
  7936       case 0x02: //not_equal
  7937         __ c_eq_s(reg_op1, reg_op2);
  7938         __ movf(dst, src);
  7939         break;
  7940       case 0x03: //greater
  7941         __ c_ole_s(reg_op1, reg_op2);
  7942         __ movf(dst, src);
  7943         break;
  7944       case 0x04: //greater_equal
  7945         __ c_olt_s(reg_op1, reg_op2);
  7946         __ movf(dst, src);
  7947         break;
  7948       case 0x05: //less
  7949         __ c_ult_s(reg_op1, reg_op2);
  7950         __ movt(dst, src);
  7951         break;
  7952       case 0x06: //less_equal
  7953         __ c_ule_s(reg_op1, reg_op2);
  7954         __ movt(dst, src);
  7955        break;
  7956       default:
  7957           Unimplemented();
  7959   %}
  7960   ins_pipe( pipe_slow );
  7961 %}
  7963 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
  7964   match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  7965   ins_cost(200);
  7966   format %{
  7967              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpF_reg_reg\n"
  7968              "\tCMOV  $dst,$src \t @cmovF_cmpF_reg_reg"
  7969          %}
  7971   ins_encode %{
  7972     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  7973     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  7974     FloatRegister dst = $dst$$FloatRegister;
  7975     FloatRegister src = $src$$FloatRegister;
  7976     Label  L;
  7977     int    flag = $cop$$cmpcode;
  7979     switch(flag)
  7981       case 0x01: //equal
  7982         __ c_eq_s(reg_op1, reg_op2);
  7983         __ bc1f(L);
  7984         __ nop();
  7985         __ mov_s(dst, src);
  7986         __ bind(L);
  7987         break;
  7988       case 0x02: //not_equal
  7989         __ c_eq_s(reg_op1, reg_op2);
  7990         __ bc1t(L);
  7991         __ nop();
  7992         __ mov_s(dst, src);
  7993         __ bind(L);
  7994         break;
  7995       case 0x03: //greater
  7996         __ c_ole_s(reg_op1, reg_op2);
  7997         __ bc1t(L);
  7998         __ nop();
  7999         __ mov_s(dst, src);
  8000         __ bind(L);
  8001         break;
  8002       case 0x04: //greater_equal
  8003         __ c_olt_s(reg_op1, reg_op2);
  8004         __ bc1t(L);
  8005         __ nop();
  8006         __ mov_s(dst, src);
  8007         __ bind(L);
  8008         break;
  8009       case 0x05: //less
  8010         __ c_ult_s(reg_op1, reg_op2);
  8011         __ bc1f(L);
  8012         __ nop();
  8013         __ mov_s(dst, src);
  8014         __ bind(L);
  8015         break;
  8016       case 0x06: //less_equal
  8017         __ c_ule_s(reg_op1, reg_op2);
  8018         __ bc1f(L);
  8019         __ nop();
  8020         __ mov_s(dst, src);
  8021         __ bind(L);
  8022        break;
  8023       default:
  8024           Unimplemented();
  8026   %}
  8027   ins_pipe( pipe_slow );
  8028 %}
  8030 // Manifest a CmpL result in an integer register.  Very painful.
  8031 // This is the test to avoid.
  8032 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
  8033   match(Set dst (CmpL3 src1 src2));
  8034   ins_cost(1000);
  8035   format %{ "cmpL3  $dst, $src1, $src2 @ cmpL3_reg_reg" %}
  8036   ins_encode %{
  8037     Register opr1 = as_Register($src1$$reg);
  8038     Register opr2 = as_Register($src2$$reg);
  8039     Register dst  = as_Register($dst$$reg);
  8041     Label Done;
  8043     __ subu(AT, opr1, opr2);
  8044     __ bltz(AT, Done);
  8045     __ delayed()->daddiu(dst, R0, -1);
  8047     __ move(dst, 1);
  8048     __ movz(dst, R0, AT);
  8050     __ bind(Done);
  8051   %}
  8052   ins_pipe( pipe_slow );
  8053 %}
  8055 //
  8056 // less_rsult     = -1 
  8057 // greater_result =  1
  8058 // equal_result   =  0 
  8059 // nan_result     = -1
  8060 //
  8061 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
  8062   match(Set dst (CmpF3 src1 src2));
  8063   ins_cost(1000);
  8064   format %{ "cmpF3  $dst, $src1, $src2 @ cmpF3_reg_reg" %}
  8065   ins_encode %{
  8066     FloatRegister src1 = as_FloatRegister($src1$$reg);
  8067     FloatRegister src2 = as_FloatRegister($src2$$reg);
  8068     Register dst = as_Register($dst$$reg);
  8070     Label Done;
  8072     __ c_ult_s(src1, src2);
  8073     __ bc1t(Done);
  8074     __ delayed()->daddiu(dst, R0, -1);
  8076     __ c_eq_s(src1, src2);
  8077     __ move(dst, 1);
  8078     __ movt(dst, R0);
  8080     __ bind(Done);
  8081   %}
  8082   ins_pipe( pipe_slow );
  8083 %}
  8085 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
  8086   match(Set dst (CmpD3 src1 src2));
  8087   ins_cost(1000);
  8088   format %{ "cmpD3  $dst, $src1, $src2 @ cmpD3_reg_reg" %}
  8089   ins_encode %{
  8090     FloatRegister src1 = as_FloatRegister($src1$$reg);
  8091     FloatRegister src2 = as_FloatRegister($src2$$reg);
  8092     Register dst = as_Register($dst$$reg);
  8094     Label Done;
  8096     __ c_ult_d(src1, src2);
  8097     __ bc1t(Done);
  8098     __ delayed()->daddiu(dst, R0, -1);
  8100     __ c_eq_d(src1, src2);
  8101     __ move(dst, 1);
  8102     __ movt(dst, R0);
  8104     __ bind(Done);
  8105   %}
  8106   ins_pipe( pipe_slow );
  8107 %}
  8109 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
  8110   match(Set dummy (ClearArray cnt base));
  8111   format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
  8112   ins_encode %{
  8113     //Assume cnt is the number of bytes in an array to be cleared,
  8114     //and base points to the starting address of the array.
  8115     Register base = $base$$Register;
  8116     Register num  = $cnt$$Register;
  8117     Label Loop, done;
  8119     __ beq(num, R0, done);
  8120     __ delayed()->daddu(AT, base, R0);
  8122     __ move(T9, num);	/* T9 = words */
  8124     __ bind(Loop);
  8125     __ sd(R0, AT, 0);
  8126     __ daddi(T9, T9, -1);
  8127     __ bne(T9, R0, Loop);
  8128     __ delayed()->daddi(AT, AT, wordSize);
  8130     __ bind(done);
  8131   %}
  8132   ins_pipe( pipe_slow );
  8133 %}
  8135 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2,  mA7RegI cnt2, no_Ax_mRegI result) %{
  8136   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
  8137   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
  8139   format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
  8140   ins_encode %{
  8141     // Get the first character position in both strings
  8142     //         [8] char array, [12] offset, [16] count 
  8143     Register str1   = $str1$$Register;
  8144     Register str2   = $str2$$Register;
  8145     Register cnt1   = $cnt1$$Register;
  8146     Register cnt2   = $cnt2$$Register;
  8147     Register result = $result$$Register;
  8149     Label L, Loop, haveResult, done;
  8151    // compute the and difference of lengths (in result)
  8152    __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
  8154    // compute the shorter length (in cnt1)
  8155    __ slt(AT, cnt2, cnt1);
  8156    __ movn(cnt1, cnt2, AT);
  8158    // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register 
  8159    __ bind(Loop);                        // Loop begin
  8160    __ beq(cnt1, R0, done);
  8161    __ delayed()->lhu(AT, str1, 0);;
  8163    // compare current character
  8164    __ lhu(cnt2, str2, 0);
  8165    __ bne(AT, cnt2, haveResult);
  8166    __ delayed()->addi(str1, str1, 2);
  8167    __ addi(str2, str2, 2);
  8168    __ b(Loop);
  8169    __ delayed()->addi(cnt1, cnt1, -1);   // Loop end
  8171    __ bind(haveResult);
  8172    __ subu(result, AT, cnt2);
  8174    __ bind(done);
  8175   %}
  8177   ins_pipe( pipe_slow );
  8178 %}
  8180 // intrinsic optimization
  8181 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
  8182   match(Set result (StrEquals (Binary str1 str2) cnt));
  8183   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
  8185   format %{ "String Equal $str1, $str2, len:$cnt  tmp:$temp -> $result @ string_equals" %}
  8186   ins_encode %{
  8187     // Get the first character position in both strings
  8188     //         [8] char array, [12] offset, [16] count 
  8189     Register str1   = $str1$$Register;
  8190     Register str2   = $str2$$Register;
  8191     Register cnt    = $cnt$$Register;
  8192     Register tmp    = $temp$$Register;
  8193     Register result = $result$$Register;
  8195     Label    Loop, done;
  8198    __ beq(str1, str2, done);  // same char[] ?
  8199    __ daddiu(result, R0, 1);
  8201    __ bind(Loop);             // Loop begin
  8202    __ beq(cnt, R0, done);
  8203    __ daddiu(result, R0, 1); // count == 0
  8205    // compare current character
  8206    __ lhu(AT, str1, 0);;
  8207    __ lhu(tmp, str2, 0);
  8208    __ bne(AT, tmp, done);
  8209    __ delayed()->daddi(result, R0, 0);
  8210    __ addi(str1, str1, 2);
  8211    __ addi(str2, str2, 2);
  8212    __ b(Loop);
  8213    __ delayed()->addi(cnt, cnt, -1);  // Loop end
  8215    __ bind(done);
  8216   %}
  8218   ins_pipe( pipe_slow );
  8219 %}
  8221 //----------Arithmetic Instructions-------------------------------------------
  8222 //----------Addition Instructions---------------------------------------------
  8223 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  8224   match(Set dst (AddI src1 src2));
  8226   format %{ "add   $dst, $src1, $src2 #@addI_Reg_Reg" %}
  8227   ins_encode %{
  8228     Register  dst = $dst$$Register;
  8229     Register src1 = $src1$$Register;
  8230     Register src2 = $src2$$Register;
  8231     __ addu32(dst, src1, src2);
  8232   %}
  8233   ins_pipe( ialu_regI_regI );
  8234 %}
  8236 instruct addI_Reg_imm(mRegI dst, mRegI src1,  immI src2) %{
  8237   match(Set dst (AddI src1 src2));
  8239   format %{ "add    $dst, $src1, $src2 #@addI_Reg_imm" %}
  8240   ins_encode %{
  8241     Register  dst = $dst$$Register;
  8242     Register src1 = $src1$$Register;
  8243     int       imm = $src2$$constant;
  8245     if(Assembler::is_simm16(imm)) {
  8246        __ addiu32(dst, src1, imm);
  8247     } else {
  8248        __ move(AT, imm);
  8249        __ addu32(dst, src1, AT);
  8251   %}
  8252   ins_pipe( ialu_regI_regI );
  8253 %}
  8255 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
  8256   match(Set dst (AddP src1 src2));
  8258   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg" %}
  8260   ins_encode %{
  8261     Register  dst = $dst$$Register;
  8262     Register src1 = $src1$$Register;
  8263     Register src2 = $src2$$Register;
  8264     __ daddu(dst, src1, src2);  
  8265   %}
  8267   ins_pipe( ialu_regI_regI );
  8268 %}
  8270 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
  8271   match(Set dst (AddP src1 (ConvI2L src2)));
  8273   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
  8275   ins_encode %{
  8276     Register  dst = $dst$$Register;
  8277     Register src1 = $src1$$Register;
  8278     Register src2 = $src2$$Register;
  8279     __ daddu(dst, src1, src2);  
  8280   %}
  8282   ins_pipe( ialu_regI_regI );
  8283 %}
  8285 instruct addP_reg_imm(mRegP dst, mRegP src1,  immL src2) %{
  8286   match(Set dst (AddP src1 src2));
  8288   format %{ "daddi   $dst, $src1, $src2 #@addP_reg_imm" %}
  8289   ins_encode %{
  8290     Register src1 = $src1$$Register;
  8291     long      src2 = $src2$$constant;
  8292     Register  dst = $dst$$Register;
  8294     if(Assembler::is_simm16(src2)) {
  8295        __ daddiu(dst, src1, src2);
  8296     } else {
  8297        __ set64(AT, src2);
  8298        __ daddu(dst, src1, AT);
  8300   %}
  8301   ins_pipe( ialu_regI_imm16 );
  8302 %}
  8304 // Add Long Register with Register
  8305 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  8306   match(Set dst (AddL src1 src2));
  8307   ins_cost(200);
  8308   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
  8310   ins_encode %{
  8311     Register dst_reg = as_Register($dst$$reg);
  8312     Register src1_reg = as_Register($src1$$reg);
  8313     Register src2_reg = as_Register($src2$$reg);
  8315     __ daddu(dst_reg, src1_reg, src2_reg);
  8316   %}
  8318   ins_pipe( ialu_regL_regL );
  8319 %}
  8321 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
  8322 %{
  8323   match(Set dst (AddL src1 src2));
  8325   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_imm " %}
  8326   ins_encode %{
  8327     Register dst_reg  = as_Register($dst$$reg);
  8328     Register src1_reg = as_Register($src1$$reg);
  8329     int      src2_imm = $src2$$constant;
  8331     __ daddiu(dst_reg, src1_reg, src2_imm);
  8332   %}
  8334   ins_pipe( ialu_regL_regL );
  8335 %}
  8337 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
  8338 %{
  8339   match(Set dst (AddL (ConvI2L src1) src2));
  8341   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_imm " %}
  8342   ins_encode %{
  8343     Register dst_reg  = as_Register($dst$$reg);
  8344     Register src1_reg = as_Register($src1$$reg);
  8345     int      src2_imm = $src2$$constant;
  8347     __ daddiu(dst_reg, src1_reg, src2_imm);
  8348   %}
  8350   ins_pipe( ialu_regL_regL );
  8351 %}
  8353 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
  8354   match(Set dst (AddL (ConvI2L src1) src2));
  8355   ins_cost(200);
  8356   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
  8358   ins_encode %{
  8359     Register dst_reg = as_Register($dst$$reg);
  8360     Register src1_reg = as_Register($src1$$reg);
  8361     Register src2_reg = as_Register($src2$$reg);
  8363     __ daddu(dst_reg, src1_reg, src2_reg);
  8364   %}
  8366   ins_pipe( ialu_regL_regL );
  8367 %}
  8369 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
  8370   match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
  8371   ins_cost(200);
  8372   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
  8374   ins_encode %{
  8375     Register dst_reg = as_Register($dst$$reg);
  8376     Register src1_reg = as_Register($src1$$reg);
  8377     Register src2_reg = as_Register($src2$$reg);
  8379     __ daddu(dst_reg, src1_reg, src2_reg);
  8380   %}
  8382   ins_pipe( ialu_regL_regL );
  8383 %}
  8385 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
  8386   match(Set dst (AddL src1 (ConvI2L src2)));
  8387   ins_cost(200);
  8388   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
  8390   ins_encode %{
  8391     Register dst_reg = as_Register($dst$$reg);
  8392     Register src1_reg = as_Register($src1$$reg);
  8393     Register src2_reg = as_Register($src2$$reg);
  8395     __ daddu(dst_reg, src1_reg, src2_reg);
  8396   %}
  8398   ins_pipe( ialu_regL_regL );
  8399 %}
  8401 //----------Subtraction Instructions-------------------------------------------
  8402 // Integer Subtraction Instructions
  8403 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  8404   match(Set dst (SubI src1 src2));
  8405   ins_cost(100);
  8407   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_Reg" %}
  8408   ins_encode %{
  8409     Register  dst = $dst$$Register;
  8410     Register src1 = $src1$$Register;
  8411     Register src2 = $src2$$Register;
  8412     __ subu32(dst, src1, src2);
  8413   %}
  8414   ins_pipe( ialu_regI_regI );
  8415 %}
  8417 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1,  immI16_sub src2) %{
  8418   match(Set dst (SubI src1 src2));
  8419   ins_cost(80);
  8421   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
  8422   ins_encode %{
  8423     Register  dst = $dst$$Register;
  8424     Register src1 = $src1$$Register;
  8425     __ addiu32(dst, src1, -1 * $src2$$constant);
  8426   %}
  8427   ins_pipe( ialu_regI_regI );
  8428 %}
  8430 instruct negI_Reg(mRegI dst, immI0 zero,  mRegI src) %{
  8431   match(Set dst (SubI zero src));
  8432   ins_cost(80);
  8434   format %{ "neg    $dst, $src #@negI_Reg" %}
  8435   ins_encode %{
  8436     Register  dst = $dst$$Register;
  8437     Register  src = $src$$Register;
  8438     __ subu32(dst, R0, src);
  8439   %}
  8440   ins_pipe( ialu_regI_regI );
  8441 %}
  8443 instruct negL_Reg(mRegL dst, immL0 zero,  mRegL src) %{
  8444   match(Set dst (SubL zero src));
  8445   ins_cost(80);
  8447   format %{ "neg    $dst, $src #@negL_Reg" %}
  8448   ins_encode %{
  8449     Register  dst = $dst$$Register;
  8450     Register  src = $src$$Register;
  8451     __ subu(dst, R0, src);
  8452   %}
  8453   ins_pipe( ialu_regI_regI );
  8454 %}
  8456 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1,  immL16_sub src2) %{
  8457   match(Set dst (SubL src1 src2));
  8458   ins_cost(80);
  8460   format %{ "sub    $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
  8461   ins_encode %{
  8462     Register  dst = $dst$$Register;
  8463     Register src1 = $src1$$Register;
  8464     __ daddiu(dst, src1, -1 * $src2$$constant);
  8465   %}
  8466   ins_pipe( ialu_regI_regI );
  8467 %}
  8469 // Subtract Long Register with Register.
  8470 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  8471   match(Set dst (SubL src1 src2));
  8472   ins_cost(100);
  8473   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_Reg" %}
  8474   ins_encode %{
  8475     Register dst  = as_Register($dst$$reg);
  8476     Register src1 = as_Register($src1$$reg);
  8477     Register src2 = as_Register($src2$$reg);
  8479     __ subu(dst, src1, src2);
  8480   %}
  8481   ins_pipe( ialu_regL_regL );
  8482 %}
  8484 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
  8485   match(Set dst (SubL src1 (ConvI2L src2)));
  8486   ins_cost(100);
  8487   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
  8488   ins_encode %{
  8489     Register dst  = as_Register($dst$$reg);
  8490     Register src1 = as_Register($src1$$reg);
  8491     Register src2 = as_Register($src2$$reg);
  8493     __ subu(dst, src1, src2);
  8494   %}
  8495   ins_pipe( ialu_regL_regL );
  8496 %}
  8498 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
  8499   match(Set dst (SubL (ConvI2L src1) src2));
  8500   ins_cost(200);
  8501   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
  8502   ins_encode %{
  8503     Register dst  = as_Register($dst$$reg);
  8504     Register src1 = as_Register($src1$$reg);
  8505     Register src2 = as_Register($src2$$reg);
  8507     __ subu(dst, src1, src2);
  8508   %}
  8509   ins_pipe( ialu_regL_regL );
  8510 %}
  8512 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
  8513   match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
  8514   ins_cost(200);
  8515   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
  8516   ins_encode %{
  8517     Register dst  = as_Register($dst$$reg);
  8518     Register src1 = as_Register($src1$$reg);
  8519     Register src2 = as_Register($src2$$reg);
  8521     __ subu(dst, src1, src2);
  8522   %}
  8523   ins_pipe( ialu_regL_regL );
  8524 %}
  8526 // Integer MOD with Register
  8527 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  8528   match(Set dst (ModI src1 src2));
  8529   ins_cost(300);
  8530   format %{ "modi   $dst, $src1, $src2 @ modI_Reg_Reg" %}
  8531   ins_encode %{
  8532     Register  dst = $dst$$Register;
  8533     Register src1 = $src1$$Register;
  8534     Register src2 = $src2$$Register;
  8536     //if (UseLoongsonISA) {
  8537     if (0) {
  8538       // 2016.08.10 
  8539       // Experiments show that gsmod is slower that div+mfhi.
  8540       // So I just disable it here.
  8541       __ gsmod(dst, src1, src2);
  8542     } else {
  8543       __ div(src1, src2); 
  8544       __ mfhi(dst);  
  8546   %}
  8548   //ins_pipe( ialu_mod );
  8549   ins_pipe( ialu_regI_regI );
  8550 %}
  8552 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  8553   match(Set dst (ModL src1 src2));
  8554   format %{ "modL  $dst, $src1, $src2 @modL_reg_reg" %}
  8556   ins_encode %{
  8557     Register dst = as_Register($dst$$reg);
  8558     Register op1 = as_Register($src1$$reg);
  8559     Register op2 = as_Register($src2$$reg);
  8561     if (UseLoongsonISA) {
  8562       __ gsdmod(dst, op1, op2);
  8563     } else {
  8564       __ ddiv(op1, op2);
  8565       __ mfhi(dst);
  8567   %}
  8568   ins_pipe( pipe_slow );
  8569 %}
  8571 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  8572   match(Set dst (MulI src1 src2));
  8574   ins_cost(300);
  8575   format %{ "mul   $dst, $src1, $src2 @ mulI_Reg_Reg" %}
  8576   ins_encode %{
  8577      Register src1 = $src1$$Register;
  8578      Register src2 = $src2$$Register;
  8579      Register dst  = $dst$$Register;
  8581      __ mul(dst, src1, src2);
  8582   %}
  8583   ins_pipe( ialu_mult );
  8584 %}
  8586 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
  8587   match(Set dst (AddI (MulI src1 src2) src3));
  8589   ins_cost(999);
  8590   format %{ "madd   $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
  8591   ins_encode %{
  8592      Register src1 = $src1$$Register;
  8593      Register src2 = $src2$$Register;
  8594      Register src3 = $src3$$Register;
  8595      Register dst  = $dst$$Register;
  8597      __ mtlo(src3);
  8598      __ madd(src1, src2);
  8599      __ mflo(dst);
  8600   %}
  8601   ins_pipe( ialu_mult );
  8602 %}
  8604 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  8605   match(Set dst (DivI src1 src2));
  8607   ins_cost(300);
  8608   format %{ "div   $dst, $src1, $src2 @ divI_Reg_Reg" %}
  8609   ins_encode %{
  8610      Register src1 = $src1$$Register;
  8611      Register src2 = $src2$$Register;
  8612      Register dst  = $dst$$Register;
  8614     /* 2012/4/21 Jin: In MIPS, div does not cause exception.
  8615        We must trap an exception manually. */   
  8616     __ teq(R0, src2, 0x7);
  8618     if (UseLoongsonISA) {
  8619       __ gsdiv(dst, src1, src2);
  8620     } else {
  8621       __ div(src1, src2);
  8623       __ nop();
  8624       __ nop();
  8625       __ mflo(dst);
  8627   %}
  8628   ins_pipe( ialu_mod );
  8629 %}
  8631 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
  8632   match(Set dst (DivF src1 src2));
  8634   ins_cost(300);
  8635   format %{ "divF   $dst, $src1, $src2 @ divF_Reg_Reg" %}
  8636   ins_encode %{
  8637      FloatRegister src1 = $src1$$FloatRegister;
  8638      FloatRegister src2 = $src2$$FloatRegister;
  8639      FloatRegister dst  = $dst$$FloatRegister;
  8641     /* Here do we need to trap an exception manually ? */   
  8642     __ div_s(dst, src1, src2);
  8643   %}
  8644   ins_pipe( pipe_slow );
  8645 %}
  8647 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
  8648   match(Set dst (DivD src1 src2));
  8650   ins_cost(300);
  8651   format %{ "divD   $dst, $src1, $src2 @ divD_Reg_Reg" %}
  8652   ins_encode %{
  8653      FloatRegister src1 = $src1$$FloatRegister;
  8654      FloatRegister src2 = $src2$$FloatRegister;
  8655      FloatRegister dst  = $dst$$FloatRegister;
  8657     /* Here do we need to trap an exception manually ? */   
  8658     __ div_d(dst, src1, src2);
  8659   %}
  8660   ins_pipe( pipe_slow );
  8661 %}
  8663 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  8664   match(Set dst (MulL src1 src2));
  8665   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_reg" %}
  8666   ins_encode %{
  8667     Register dst = as_Register($dst$$reg);
  8668     Register op1 = as_Register($src1$$reg);
  8669     Register op2 = as_Register($src2$$reg);
  8671     if (UseLoongsonISA) {
  8672       __ gsdmult(dst, op1, op2);
  8673     } else {
  8674       __ dmult(op1, op2);
  8675       __ mflo(dst);
  8677   %}
  8678   ins_pipe( pipe_slow );
  8679 %}
  8681 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
  8682   match(Set dst (MulL src1 (ConvI2L src2)));
  8683   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_regI2L" %}
  8684   ins_encode %{
  8685     Register dst = as_Register($dst$$reg);
  8686     Register op1 = as_Register($src1$$reg);
  8687     Register op2 = as_Register($src2$$reg);
  8689     if (UseLoongsonISA) {
  8690       __ gsdmult(dst, op1, op2);
  8691     } else {
  8692       __ dmult(op1, op2);
  8693       __ mflo(dst);
  8695   %}
  8696   ins_pipe( pipe_slow );
  8697 %}
  8699 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  8700   match(Set dst (DivL src1 src2));
  8701   format %{ "divL  $dst, $src1, $src2 @divL_reg_reg" %}
  8703   ins_encode %{
  8704     Register dst = as_Register($dst$$reg);
  8705     Register op1 = as_Register($src1$$reg);
  8706     Register op2 = as_Register($src2$$reg);
  8708     if (UseLoongsonISA) {
  8709       __ gsddiv(dst, op1, op2);
  8710     } else {
  8711       __ ddiv(op1, op2);
  8712       __ mflo(dst);
  8714   %}
  8715   ins_pipe( pipe_slow );
  8716 %}
  8718 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
  8719   match(Set dst (AddF src1 src2));
  8720   format %{ "AddF  $dst, $src1, $src2 @addF_reg_reg" %}
  8721   ins_encode %{
  8722     FloatRegister src1 = as_FloatRegister($src1$$reg);
  8723     FloatRegister src2 = as_FloatRegister($src2$$reg);
  8724     FloatRegister dst  = as_FloatRegister($dst$$reg);
  8726     __ add_s(dst, src1, src2);  
  8727   %}
  8728   ins_pipe( fpu_regF_regF );
  8729 %}
  8731 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
  8732   match(Set dst (SubF src1 src2));
  8733   format %{ "SubF  $dst, $src1, $src2 @subF_reg_reg" %}
  8734   ins_encode %{
  8735     FloatRegister src1 = as_FloatRegister($src1$$reg);
  8736     FloatRegister src2 = as_FloatRegister($src2$$reg);
  8737     FloatRegister dst  = as_FloatRegister($dst$$reg);
  8739     __ sub_s(dst, src1, src2);  
  8740   %}
  8741   ins_pipe( fpu_regF_regF );
  8742 %}
  8743 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
  8744   match(Set dst (AddD src1 src2));
  8745   format %{ "AddD  $dst, $src1, $src2 @addD_reg_reg" %}
  8746   ins_encode %{
  8747     FloatRegister src1 = as_FloatRegister($src1$$reg);
  8748     FloatRegister src2 = as_FloatRegister($src2$$reg);
  8749     FloatRegister dst  = as_FloatRegister($dst$$reg);
  8751     __ add_d(dst, src1, src2);  
  8752   %}
  8753   ins_pipe( fpu_regF_regF );
  8754 %}
  8756 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
  8757   match(Set dst (SubD src1 src2));
  8758   format %{ "SubD  $dst, $src1, $src2 @subD_reg_reg" %}
  8759   ins_encode %{
  8760     FloatRegister src1 = as_FloatRegister($src1$$reg);
  8761     FloatRegister src2 = as_FloatRegister($src2$$reg);
  8762     FloatRegister dst  = as_FloatRegister($dst$$reg);
  8764     __ sub_d(dst, src1, src2);  
  8765   %}
  8766   ins_pipe( fpu_regF_regF );
  8767 %}
  8769 instruct negF_reg(regF dst, regF src) %{
  8770   match(Set dst (NegF src));
  8771   format %{ "negF  $dst, $src @negF_reg" %}
  8772   ins_encode %{
  8773     FloatRegister src = as_FloatRegister($src$$reg);
  8774     FloatRegister dst = as_FloatRegister($dst$$reg);
  8776     __ neg_s(dst, src);
  8777   %}
  8778   ins_pipe( fpu_regF_regF );
  8779 %}
  8781 instruct negD_reg(regD dst, regD src) %{
  8782   match(Set dst (NegD src));
  8783   format %{ "negD  $dst, $src @negD_reg" %}
  8784   ins_encode %{
  8785     FloatRegister src = as_FloatRegister($src$$reg);
  8786     FloatRegister dst = as_FloatRegister($dst$$reg);
  8788     __ neg_d(dst, src);  
  8789   %}
  8790   ins_pipe( fpu_regF_regF );
  8791 %}
  8794 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
  8795   match(Set dst (MulF src1 src2));
  8796   format %{ "MULF  $dst, $src1, $src2 @mulF_reg_reg" %}
  8797   ins_encode %{
  8798     FloatRegister src1 = $src1$$FloatRegister;
  8799     FloatRegister src2 = $src2$$FloatRegister;
  8800     FloatRegister dst  = $dst$$FloatRegister;
  8802     __ mul_s(dst, src1, src2);  
  8803   %}
  8804   ins_pipe( fpu_regF_regF );
  8805 %}
  8807 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
  8808   match(Set dst (AddF (MulF src1 src2) src3));
  8809   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
  8810   ins_cost(44444);
  8811   format %{ "maddF  $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
  8812   ins_encode %{
  8813     FloatRegister src1 = $src1$$FloatRegister;
  8814     FloatRegister src2 = $src2$$FloatRegister;
  8815     FloatRegister src3 = $src3$$FloatRegister;
  8816     FloatRegister dst  = $dst$$FloatRegister;
  8818     __ madd_s(dst, src1, src2, src3);  
  8819   %}
  8820   ins_pipe( fpu_regF_regF );
  8821 %}
  8823 // Mul two double precision floating piont number
  8824 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
  8825   match(Set dst (MulD src1 src2));
  8826   format %{ "MULD  $dst, $src1, $src2 @mulD_reg_reg" %}
  8827   ins_encode %{
  8828     FloatRegister src1 = $src1$$FloatRegister;
  8829     FloatRegister src2 = $src2$$FloatRegister;
  8830     FloatRegister dst  = $dst$$FloatRegister;
  8832     __ mul_d(dst, src1, src2);  
  8833   %}
  8834   ins_pipe( fpu_regF_regF );
  8835 %}
  8837 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
  8838   match(Set dst (AddD (MulD src1 src2) src3));
  8839   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
  8840   ins_cost(44444);
  8841   format %{ "maddD  $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
  8842   ins_encode %{
  8843     FloatRegister src1 = $src1$$FloatRegister;
  8844     FloatRegister src2 = $src2$$FloatRegister;
  8845     FloatRegister src3 = $src3$$FloatRegister;
  8846     FloatRegister dst  = $dst$$FloatRegister;
  8848     __ madd_d(dst, src1, src2, src3);  
  8849   %}
  8850   ins_pipe( fpu_regF_regF );
  8851 %}
  8853 instruct absF_reg(regF dst, regF src) %{
  8854   match(Set dst (AbsF src));
  8855   ins_cost(100);
  8856   format %{ "absF  $dst, $src @absF_reg" %}
  8857   ins_encode %{
  8858     FloatRegister src = as_FloatRegister($src$$reg);
  8859     FloatRegister dst = as_FloatRegister($dst$$reg);
  8861     __ abs_s(dst, src);  
  8862   %}
  8863   ins_pipe( fpu_regF_regF );
  8864 %}
  8867 // intrinsics for math_native.
  8868 // AbsD  SqrtD  CosD  SinD  TanD  LogD  Log10D
  8870 instruct absD_reg(regD dst, regD src) %{
  8871   match(Set dst (AbsD src));
  8872   ins_cost(100);
  8873   format %{ "absD  $dst, $src @absD_reg" %}
  8874   ins_encode %{
  8875     FloatRegister src = as_FloatRegister($src$$reg);
  8876     FloatRegister dst = as_FloatRegister($dst$$reg);
  8878     __ abs_d(dst, src);  
  8879   %}
  8880   ins_pipe( fpu_regF_regF );
  8881 %}
  8883 instruct sqrtD_reg(regD dst, regD src) %{
  8884   match(Set dst (SqrtD src));
  8885   ins_cost(100);
  8886   format %{ "SqrtD  $dst, $src @sqrtD_reg" %}
  8887   ins_encode %{
  8888     FloatRegister src = as_FloatRegister($src$$reg);
  8889     FloatRegister dst = as_FloatRegister($dst$$reg);
  8891     __ sqrt_d(dst, src);  
  8892   %}
  8893   ins_pipe( fpu_regF_regF );
  8894 %}
  8896 instruct sqrtF_reg(regF dst, regF src) %{
  8897   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
  8898   ins_cost(100);
  8899   format %{ "SqrtF  $dst, $src @sqrtF_reg" %}
  8900   ins_encode %{
  8901     FloatRegister src = as_FloatRegister($src$$reg);
  8902     FloatRegister dst = as_FloatRegister($dst$$reg);
  8904     __ sqrt_s(dst, src);
  8905   %}
  8906   ins_pipe( fpu_regF_regF );
  8907 %}
  8908 //----------------------------------Logical Instructions----------------------
  8909 //__________________________________Integer Logical Instructions-------------
  8911 //And Instuctions
  8912 // And Register with Immediate
  8913 instruct andI_Reg_immI(mRegI dst, mRegI src1,  immI src2) %{
  8914   match(Set dst (AndI src1 src2));
  8916   format %{ "and  $dst, $src1, $src2 #@andI_Reg_immI" %}
  8917   ins_encode %{
  8918     Register dst = $dst$$Register;
  8919     Register src = $src1$$Register;
  8920     int      val = $src2$$constant;
  8922        __ move(AT, val);
  8923        __ andr(dst, src, AT);
  8924   %}
  8925   ins_pipe( ialu_regI_regI );
  8926 %}
  8928 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
  8929   match(Set dst (AndI src1 src2));
  8930   ins_cost(60);
  8932   format %{ "and  $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
  8933   ins_encode %{
  8934     Register dst = $dst$$Register;
  8935     Register src = $src1$$Register;
  8936     int      val = $src2$$constant;
  8938        __ andi(dst, src, val);
  8939   %}
  8940   ins_pipe( ialu_regI_regI );
  8941 %}
  8943 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1,  immI_nonneg_mask mask) %{
  8944   match(Set dst (AndI src1 mask));
  8945   ins_cost(60);
  8947   format %{ "and  $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
  8948   ins_encode %{
  8949     Register dst = $dst$$Register;
  8950     Register src = $src1$$Register;
  8951     int     size = Assembler::is_int_mask($mask$$constant);
  8953     __ ext(dst, src, 0, size);
  8954   %}
  8955   ins_pipe( ialu_regI_regI );
  8956 %}
  8958 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1,  immL_nonneg_mask mask) %{
  8959   match(Set dst (AndL src1 mask));
  8960   ins_cost(60);
  8962   format %{ "and  $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
  8963   ins_encode %{
  8964     Register dst = $dst$$Register;
  8965     Register src = $src1$$Register;
  8966     int     size = Assembler::is_jlong_mask($mask$$constant);
  8968     __ dext(dst, src, 0, size);
  8969   %}
  8970   ins_pipe( ialu_regI_regI );
  8971 %}
  8973 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
  8974   match(Set dst (XorI src1 src2));
  8975   ins_cost(60);
  8977   format %{ "xori  $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
  8978   ins_encode %{
  8979     Register dst = $dst$$Register;
  8980     Register src = $src1$$Register;
  8981     int      val = $src2$$constant;
  8983        __ xori(dst, src, val);
  8984   %}
  8985   ins_pipe( ialu_regI_regI );
  8986 %}
  8988 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1,  immI_M1 M1) %{
  8989   match(Set dst (XorI src1 M1));
  8990   predicate(UseLoongsonISA && Use3A2000);
  8991   ins_cost(60);
  8993   format %{ "xor  $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
  8994   ins_encode %{
  8995     Register dst = $dst$$Register;
  8996     Register src = $src1$$Register;
  8998        __ gsorn(dst, R0, src);
  8999   %}
  9000   ins_pipe( ialu_regI_regI );
  9001 %}
  9003 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1,  immI_M1 M1) %{
  9004   match(Set dst (XorI (ConvL2I src1) M1));
  9005   predicate(UseLoongsonISA && Use3A2000);
  9006   ins_cost(60);
  9008   format %{ "xor  $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
  9009   ins_encode %{
  9010     Register dst = $dst$$Register;
  9011     Register src = $src1$$Register;
  9013        __ gsorn(dst, R0, src);
  9014   %}
  9015   ins_pipe( ialu_regI_regI );
  9016 %}
  9018 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
  9019   match(Set dst (XorL src1 src2));
  9020   ins_cost(60);
  9022   format %{ "xori  $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
  9023   ins_encode %{
  9024     Register dst = $dst$$Register;
  9025     Register src = $src1$$Register;
  9026     int      val = $src2$$constant;
  9028        __ xori(dst, src, val);
  9029   %}
  9030   ins_pipe( ialu_regI_regI );
  9031 %}
  9033 /*
  9034 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1,  immL_M1 M1) %{
  9035   match(Set dst (XorL src1 M1));
  9036   predicate(UseLoongsonISA);
  9037   ins_cost(60);
  9039   format %{ "xor  $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
  9040   ins_encode %{
  9041     Register dst = $dst$$Register;
  9042     Register src = $src1$$Register;
  9044        __ gsorn(dst, R0, src);
  9045   %}
  9046   ins_pipe( ialu_regI_regI );
  9047 %}
  9048 */
  9050 instruct lbu_and_lmask(mRegI dst, umemory mem,  immI_255 mask) %{
  9051   match(Set dst (AndI mask (LoadB mem)));
  9052   ins_cost(60);
  9054   format %{ "lbu  $dst, $mem #@lbu_and_lmask" %}
  9055   ins_encode(load_UB_enc(dst, mem));
  9056   ins_pipe( ialu_loadI );
  9057 %}
  9059 instruct lbu_and_rmask(mRegI dst, umemory mem,  immI_255 mask) %{
  9060   match(Set dst (AndI (LoadB mem) mask));
  9061   ins_cost(60);
  9063   format %{ "lbu  $dst, $mem #@lbu_and_rmask" %}
  9064   ins_encode(load_UB_enc(dst, mem));
  9065   ins_pipe( ialu_loadI );
  9066 %}
  9068 instruct andI_Reg_Reg(mRegI dst, mRegI src1,  mRegI src2) %{
  9069   match(Set dst (AndI src1 src2));
  9071   format %{ "and    $dst, $src1, $src2 #@andI_Reg_Reg" %}
  9072   ins_encode %{
  9073     Register dst = $dst$$Register;
  9074     Register src1 = $src1$$Register;
  9075     Register src2 = $src2$$Register;
  9076     __ andr(dst, src1, src2);
  9077   %}
  9078   ins_pipe( ialu_regI_regI );
  9079 %}
  9081 instruct andnI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
  9082   match(Set dst (AndI src1 (XorI src2 M1)));
  9083   predicate(UseLoongsonISA && Use3A2000);
  9085   format %{ "andn   $dst, $src1, $src2 #@andnI_Reg_nReg" %}
  9086   ins_encode %{
  9087     Register dst = $dst$$Register;
  9088     Register src1 = $src1$$Register;
  9089     Register src2 = $src2$$Register;
  9091     __ gsandn(dst, src1, src2);
  9092   %}
  9093   ins_pipe( ialu_regI_regI );
  9094 %}
  9096 instruct ornI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
  9097   match(Set dst (OrI src1 (XorI src2 M1)));
  9098   predicate(UseLoongsonISA && Use3A2000);
  9100   format %{ "orn    $dst, $src1, $src2 #@ornI_Reg_nReg" %}
  9101   ins_encode %{
  9102     Register dst = $dst$$Register;
  9103     Register src1 = $src1$$Register;
  9104     Register src2 = $src2$$Register;
  9106     __ gsorn(dst, src1, src2);
  9107   %}
  9108   ins_pipe( ialu_regI_regI );
  9109 %}
  9111 instruct andnI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
  9112   match(Set dst (AndI (XorI src1 M1) src2));
  9113   predicate(UseLoongsonISA && Use3A2000);
  9115   format %{ "andn   $dst, $src2, $src1 #@andnI_nReg_Reg" %}
  9116   ins_encode %{
  9117     Register dst = $dst$$Register;
  9118     Register src1 = $src1$$Register;
  9119     Register src2 = $src2$$Register;
  9121     __ gsandn(dst, src2, src1);
  9122   %}
  9123   ins_pipe( ialu_regI_regI );
  9124 %}
  9126 instruct ornI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
  9127   match(Set dst (OrI (XorI src1 M1) src2));
  9128   predicate(UseLoongsonISA && Use3A2000);
  9130   format %{ "orn    $dst, $src2, $src1 #@ornI_nReg_Reg" %}
  9131   ins_encode %{
  9132     Register dst = $dst$$Register;
  9133     Register src1 = $src1$$Register;
  9134     Register src2 = $src2$$Register;
  9136     __ gsorn(dst, src2, src1);
  9137   %}
  9138   ins_pipe( ialu_regI_regI );
  9139 %}
  9141 // And Long Register with Register
  9142 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  9143   match(Set dst (AndL src1 src2));
  9144   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
  9145   ins_encode %{
  9146     Register dst_reg = as_Register($dst$$reg);
  9147     Register src1_reg = as_Register($src1$$reg);
  9148     Register src2_reg = as_Register($src2$$reg);
  9150     __ andr(dst_reg, src1_reg, src2_reg);
  9151   %}
  9152   ins_pipe( ialu_regL_regL );
  9153 %}
  9155 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
  9156   match(Set dst (AndL src1 (ConvI2L src2)));
  9157   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
  9158   ins_encode %{
  9159     Register dst_reg = as_Register($dst$$reg);
  9160     Register src1_reg = as_Register($src1$$reg);
  9161     Register src2_reg = as_Register($src2$$reg);
  9163     __ andr(dst_reg, src1_reg, src2_reg);
  9164   %}
  9165   ins_pipe( ialu_regL_regL );
  9166 %}
  9168 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
  9169   match(Set dst (AndL src1 src2));
  9170   ins_cost(60);
  9172   format %{ "and  $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
  9173   ins_encode %{
  9174     Register dst = $dst$$Register;
  9175     Register src = $src1$$Register;
  9176     long     val = $src2$$constant;
  9178        __ andi(dst, src, val);
  9179   %}
  9180   ins_pipe( ialu_regI_regI );
  9181 %}
  9183 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1,  immL_0_65535 src2) %{
  9184   match(Set dst (ConvL2I (AndL src1 src2)));
  9185   ins_cost(60);
  9187   format %{ "and  $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
  9188   ins_encode %{
  9189     Register dst = $dst$$Register;
  9190     Register src = $src1$$Register;
  9191     long     val = $src2$$constant;
  9193        __ andi(dst, src, val);
  9194   %}
  9195   ins_pipe( ialu_regI_regI );
  9196 %}
  9198 /*
  9199 instruct andnL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
  9200   match(Set dst (AndL src1 (XorL src2 M1)));
  9201   predicate(UseLoongsonISA);
  9203   format %{ "andn   $dst, $src1, $src2 #@andnL_Reg_nReg" %}
  9204   ins_encode %{
  9205     Register dst = $dst$$Register;
  9206     Register src1 = $src1$$Register;
  9207     Register src2 = $src2$$Register;
  9209     __ gsandn(dst, src1, src2);
  9210   %}
  9211   ins_pipe( ialu_regI_regI );
  9212 %}
  9213 */
  9215 /*
  9216 instruct ornL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
  9217   match(Set dst (OrL src1 (XorL src2 M1)));
  9218   predicate(UseLoongsonISA);
  9220   format %{ "orn    $dst, $src1, $src2 #@ornL_Reg_nReg" %}
  9221   ins_encode %{
  9222     Register dst = $dst$$Register;
  9223     Register src1 = $src1$$Register;
  9224     Register src2 = $src2$$Register;
  9226     __ gsorn(dst, src1, src2);
  9227   %}
  9228   ins_pipe( ialu_regI_regI );
  9229 %}
  9230 */
  9232 /*
  9233 instruct andnL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
  9234   match(Set dst (AndL (XorL src1 M1) src2));
  9235   predicate(UseLoongsonISA);
  9237   format %{ "andn   $dst, $src2, $src1 #@andnL_nReg_Reg" %}
  9238   ins_encode %{
  9239     Register dst = $dst$$Register;
  9240     Register src1 = $src1$$Register;
  9241     Register src2 = $src2$$Register;
  9243     __ gsandn(dst, src2, src1);
  9244   %}
  9245   ins_pipe( ialu_regI_regI );
  9246 %}
  9247 */
  9249 /*
  9250 instruct ornL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
  9251   match(Set dst (OrL (XorL src1 M1) src2));
  9252   predicate(UseLoongsonISA);
  9254   format %{ "orn    $dst, $src2, $src1 #@ornL_nReg_Reg" %}
  9255   ins_encode %{
  9256     Register dst = $dst$$Register;
  9257     Register src1 = $src1$$Register;
  9258     Register src2 = $src2$$Register;
  9260     __ gsorn(dst, src2, src1);
  9261   %}
  9262   ins_pipe( ialu_regI_regI );
  9263 %}
  9264 */
  9266 instruct andL_Reg_immL_M8(mRegL dst,  immL_M8 M8) %{
  9267   match(Set dst (AndL dst M8));
  9268   ins_cost(60);
  9270   format %{ "and  $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
  9271   ins_encode %{
  9272     Register dst = $dst$$Register;
  9274     __ dins(dst, R0, 0, 3);
  9275   %}
  9276   ins_pipe( ialu_regI_regI );
  9277 %}
  9279 instruct andL_Reg_immL_M5(mRegL dst,  immL_M5 M5) %{
  9280   match(Set dst (AndL dst M5));
  9281   ins_cost(60);
  9283   format %{ "and  $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
  9284   ins_encode %{
  9285     Register dst = $dst$$Register;
  9287     __ dins(dst, R0, 2, 1);
  9288   %}
  9289   ins_pipe( ialu_regI_regI );
  9290 %}
  9292 instruct andL_Reg_immL_M7(mRegL dst,  immL_M7 M7) %{
  9293   match(Set dst (AndL dst M7));
  9294   ins_cost(60);
  9296   format %{ "and  $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
  9297   ins_encode %{
  9298     Register dst = $dst$$Register;
  9300     __ dins(dst, R0, 1, 2);
  9301   %}
  9302   ins_pipe( ialu_regI_regI );
  9303 %}
  9305 instruct andL_Reg_immL_M4(mRegL dst,  immL_M4 M4) %{
  9306   match(Set dst (AndL dst M4));
  9307   ins_cost(60);
  9309   format %{ "and  $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
  9310   ins_encode %{
  9311     Register dst = $dst$$Register;
  9313     __ dins(dst, R0, 0, 2);
  9314   %}
  9315   ins_pipe( ialu_regI_regI );
  9316 %}
  9318 instruct andL_Reg_immL_M121(mRegL dst,  immL_M121 M121) %{
  9319   match(Set dst (AndL dst M121));
  9320   ins_cost(60);
  9322   format %{ "and  $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
  9323   ins_encode %{
  9324     Register dst = $dst$$Register;
  9326     __ dins(dst, R0, 3, 4);
  9327   %}
  9328   ins_pipe( ialu_regI_regI );
  9329 %}
  9331 // Or Long Register with Register
  9332 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  9333   match(Set dst (OrL src1 src2));
  9334   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
  9335   ins_encode %{
  9336     Register dst_reg  = $dst$$Register;
  9337     Register src1_reg = $src1$$Register;
  9338     Register src2_reg = $src2$$Register;
  9340     __ orr(dst_reg, src1_reg, src2_reg);
  9341   %}
  9342   ins_pipe( ialu_regL_regL );
  9343 %}
  9345 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
  9346   match(Set dst (OrL (CastP2X src1) src2));
  9347   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
  9348   ins_encode %{
  9349     Register dst_reg  = $dst$$Register;
  9350     Register src1_reg = $src1$$Register;
  9351     Register src2_reg = $src2$$Register;
  9353     __ orr(dst_reg, src1_reg, src2_reg);
  9354   %}
  9355   ins_pipe( ialu_regL_regL );
  9356 %}
  9358 // Xor Long Register with Register
  9359 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  9360   match(Set dst (XorL src1 src2));
  9361   format %{ "XOR    $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
  9362   ins_encode %{
  9363     Register dst_reg = as_Register($dst$$reg);
  9364     Register src1_reg = as_Register($src1$$reg);
  9365     Register src2_reg = as_Register($src2$$reg);
  9367     __ xorr(dst_reg, src1_reg, src2_reg);
  9368   %}
  9369   ins_pipe( ialu_regL_regL );
  9370 %}
  9372 // Shift Left by 8-bit immediate
  9373 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
  9374   match(Set dst (LShiftI src shift));
  9376   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm" %}
  9377   ins_encode %{
  9378     Register src = $src$$Register;
  9379     Register dst = $dst$$Register;
  9380     int    shamt = $shift$$constant;
  9382     __ sll(dst, src, shamt);
  9383   %}
  9384   ins_pipe( ialu_regI_regI );
  9385 %}
  9387 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
  9388   match(Set dst (LShiftI (ConvL2I src) shift));
  9390   format %{ "SHL    $dst, $src, $shift #@salL2I_Reg_imm" %}
  9391   ins_encode %{
  9392     Register src = $src$$Register;
  9393     Register dst = $dst$$Register;
  9394     int    shamt = $shift$$constant;
  9396     __ sll(dst, src, shamt);
  9397   %}
  9398   ins_pipe( ialu_regI_regI );
  9399 %}
  9401 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
  9402   match(Set dst (AndI (LShiftI src shift) mask));
  9404   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
  9405   ins_encode %{
  9406     Register src = $src$$Register;
  9407     Register dst = $dst$$Register;
  9409     __ sll(dst, src, 16);
  9410   %}
  9411   ins_pipe( ialu_regI_regI );
  9412 %}
  9414 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
  9415 %{
  9416   match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
  9418   format %{ "andi  $dst, $src, 7\t# @land7_2_s" %}
  9419   ins_encode %{
  9420     Register src = $src$$Register;
  9421     Register dst = $dst$$Register;
  9423     __ andi(dst, src, 7);
  9424   %}
  9425   ins_pipe(ialu_regI_regI);
  9426 %}
  9428 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
  9429 %{
  9430   match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
  9432   format %{ "ori  $dst, $src1, $src2\t# @ori2s" %}
  9433   ins_encode %{
  9434     Register src = $src1$$Register;
  9435     int      val = $src2$$constant;
  9436     Register dst = $dst$$Register;
  9438     __ ori(dst, src, val);
  9439   %}
  9440   ins_pipe(ialu_regI_regI);
  9441 %}
  9443 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
  9444 // This idiom is used by the compiler the i2s bytecode.
  9445 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
  9446 %{
  9447   match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
  9449   format %{ "i2s  $dst, $src\t# @i2s" %}
  9450   ins_encode %{
  9451     Register src = $src$$Register;
  9452     Register dst = $dst$$Register;
  9454     __ seh(dst, src);
  9455   %}
  9456   ins_pipe(ialu_regI_regI);
  9457 %}
  9459 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
  9460 // This idiom is used by the compiler for the i2b bytecode.
  9461 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
  9462 %{
  9463   match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
  9465   format %{ "i2b  $dst, $src\t# @i2b" %}
  9466   ins_encode %{
  9467     Register src = $src$$Register;
  9468     Register dst = $dst$$Register;
  9470     __ seb(dst, src);
  9471   %}
  9472   ins_pipe(ialu_regI_regI);
  9473 %}
  9476 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
  9477   match(Set dst (LShiftI (ConvL2I src) shift));
  9479   format %{ "SHL    $dst, $src, $shift #@salI_RegL2I_imm" %}
  9480   ins_encode %{
  9481     Register src = $src$$Register;
  9482     Register dst = $dst$$Register;
  9483     int    shamt = $shift$$constant;
  9485     __ sll(dst, src, shamt);
  9486   %}
  9487   ins_pipe( ialu_regI_regI );
  9488 %}
  9490 // Shift Left by 8-bit immediate
  9491 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
  9492   match(Set dst (LShiftI src shift));
  9494   format %{ "SHL    $dst, $src, $shift #@salI_Reg_Reg" %}
  9495   ins_encode %{
  9496     Register src = $src$$Register;
  9497     Register dst = $dst$$Register;
  9498     Register shamt = $shift$$Register;
  9499     __ sllv(dst, src, shamt);
  9500   %}
  9501   ins_pipe( ialu_regI_regI );
  9502 %}
  9505 // Shift Left Long 
  9506 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
  9507   //predicate(UseNewLongLShift);
  9508   match(Set dst (LShiftL src shift));
  9509   ins_cost(100);
  9510   format %{ "salL    $dst, $src, $shift @ salL_Reg_imm" %}
  9511   ins_encode %{
  9512     Register src_reg = as_Register($src$$reg);
  9513     Register dst_reg = as_Register($dst$$reg);
  9514     int      shamt = $shift$$constant;
  9516     if (__ is_simm(shamt, 5))
  9517         __ dsll(dst_reg, src_reg, shamt);
  9518     else
  9520        int sa = Assembler::low(shamt, 6);
  9521        if (sa < 32) { 
  9522           __ dsll(dst_reg, src_reg, sa);
  9523        } else {
  9524           __ dsll32(dst_reg, src_reg, sa - 32);
  9527   %}
  9528   ins_pipe( ialu_regL_regL );
  9529 %}
  9531 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
  9532   //predicate(UseNewLongLShift);
  9533   match(Set dst (LShiftL (ConvI2L src) shift));
  9534   ins_cost(100);
  9535   format %{ "salL    $dst, $src, $shift @ salL_RegI2L_imm" %}
  9536   ins_encode %{
  9537     Register src_reg = as_Register($src$$reg);
  9538     Register dst_reg = as_Register($dst$$reg);
  9539     int      shamt = $shift$$constant;
  9541     if (__ is_simm(shamt, 5))
  9542         __ dsll(dst_reg, src_reg, shamt);
  9543     else
  9545        int sa = Assembler::low(shamt, 6);
  9546        if (sa < 32) { 
  9547           __ dsll(dst_reg, src_reg, sa);
  9548        } else {
  9549           __ dsll32(dst_reg, src_reg, sa - 32);
  9552   %}
  9553   ins_pipe( ialu_regL_regL );
  9554 %}
  9556 // Shift Left Long 
  9557 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
  9558   //predicate(UseNewLongLShift);
  9559   match(Set dst (LShiftL src shift));
  9560   ins_cost(100);
  9561   format %{ "salL    $dst, $src, $shift @ salL_Reg_Reg" %}
  9562   ins_encode %{
  9563     Register src_reg = as_Register($src$$reg);
  9564     Register dst_reg = as_Register($dst$$reg);
  9566     __ dsllv(dst_reg, src_reg, $shift$$Register);
  9567   %}
  9568   ins_pipe( ialu_regL_regL );
  9569 %}
  9571 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
  9572   match(Set dst (LShiftL (ConvI2L src) shift));
  9573   ins_cost(100);
  9574   format %{ "salL    $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
  9575   ins_encode %{
  9576     Register src_reg = as_Register($src$$reg);
  9577     Register dst_reg = as_Register($dst$$reg);
  9578     int      shamt = $shift$$constant;
  9580     if (__ is_simm(shamt, 5)) {
  9581         __ dsll(dst_reg, src_reg, shamt);
  9582     } else {
  9583        int sa = Assembler::low(shamt, 6);
  9584        if (sa < 32) { 
  9585           __ dsll(dst_reg, src_reg, sa);
  9586        } else {
  9587           __ dsll32(dst_reg, src_reg, sa - 32);
  9590   %}
  9591   ins_pipe( ialu_regL_regL );
  9592 %}
  9594 // Shift Right Long 
  9595 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
  9596   match(Set dst (RShiftL src shift));
  9597   ins_cost(100);
  9598   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_imm" %}
  9599   ins_encode %{
  9600     Register src_reg = as_Register($src$$reg);
  9601     Register dst_reg = as_Register($dst$$reg);
  9602     int      shamt = ($shift$$constant & 0x3f);
  9603     if (__  is_simm(shamt, 5))
  9604 	__ dsra(dst_reg, src_reg, shamt);
  9605     else {
  9606         int sa = Assembler::low(shamt, 6);
  9607         if (sa < 32) {
  9608 	   __ dsra(dst_reg, src_reg, sa);
  9609         } else {
  9610 	   __ dsra32(dst_reg, src_reg, sa - 32);
  9613   %}
  9614   ins_pipe( ialu_regL_regL );
  9615 %}
  9617 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
  9618   match(Set dst (ConvL2I (RShiftL src shift)));
  9619   ins_cost(100);
  9620   format %{ "sarL    $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
  9621   ins_encode %{
  9622     Register src_reg = as_Register($src$$reg);
  9623     Register dst_reg = as_Register($dst$$reg);
  9624     int      shamt   = $shift$$constant;
  9626     __ dsra32(dst_reg, src_reg, shamt - 32);
  9627   %}
  9628   ins_pipe( ialu_regL_regL );
  9629 %}
  9631 // Shift Right Long arithmetically
  9632 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
  9633   //predicate(UseNewLongLShift);
  9634   match(Set dst (RShiftL src shift));
  9635   ins_cost(100);
  9636   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_Reg" %}
  9637   ins_encode %{
  9638     Register src_reg = as_Register($src$$reg);
  9639     Register dst_reg = as_Register($dst$$reg);
  9641     __ dsrav(dst_reg, src_reg, $shift$$Register);
  9642   %}
  9643   ins_pipe( ialu_regL_regL );
  9644 %}
  9646 // Shift Right Long logically
  9647 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
  9648   match(Set dst (URShiftL src shift));
  9649   ins_cost(100);
  9650   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_Reg" %}
  9651   ins_encode %{
  9652     Register src_reg = as_Register($src$$reg);
  9653     Register dst_reg = as_Register($dst$$reg);
  9655     __ dsrlv(dst_reg, src_reg, $shift$$Register);
  9656   %}
  9657   ins_pipe( ialu_regL_regL );
  9658 %}
  9660 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
  9661   match(Set dst (URShiftL src shift));
  9662   ins_cost(80);
  9663   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
  9664   ins_encode %{
  9665     Register src_reg = as_Register($src$$reg);
  9666     Register dst_reg = as_Register($dst$$reg);
  9667     int        shamt = $shift$$constant;
  9669     __ dsrl(dst_reg, src_reg, shamt);
  9670   %}
  9671   ins_pipe( ialu_regL_regL );
  9672 %}
  9674 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
  9675   match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
  9676   ins_cost(80);
  9677   format %{ "dext    $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
  9678   ins_encode %{
  9679     Register src_reg = as_Register($src$$reg);
  9680     Register dst_reg = as_Register($dst$$reg);
  9681     int        shamt = $shift$$constant;
  9683     __ dext(dst_reg, src_reg, shamt, 31);
  9684   %}
  9685   ins_pipe( ialu_regL_regL );
  9686 %}
  9688 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
  9689   match(Set dst (URShiftL (CastP2X src) shift));
  9690   ins_cost(80);
  9691   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
  9692   ins_encode %{
  9693     Register src_reg = as_Register($src$$reg);
  9694     Register dst_reg = as_Register($dst$$reg);
  9695     int        shamt = $shift$$constant;
  9697     __ dsrl(dst_reg, src_reg, shamt);
  9698   %}
  9699   ins_pipe( ialu_regL_regL );
  9700 %}
  9702 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
  9703   match(Set dst (URShiftL src shift));
  9704   ins_cost(80);
  9705   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
  9706   ins_encode %{
  9707     Register src_reg = as_Register($src$$reg);
  9708     Register dst_reg = as_Register($dst$$reg);
  9709     int        shamt = $shift$$constant;
  9711     __ dsrl32(dst_reg, src_reg, shamt - 32);
  9712   %}
  9713   ins_pipe( ialu_regL_regL );
  9714 %}
  9716 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
  9717   match(Set dst (ConvL2I (URShiftL src shift)));
  9718   predicate(n->in(1)->in(2)->get_int() > 32);
  9719   ins_cost(80);
  9720   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
  9721   ins_encode %{
  9722     Register src_reg = as_Register($src$$reg);
  9723     Register dst_reg = as_Register($dst$$reg);
  9724     int        shamt = $shift$$constant;
  9726     __ dsrl32(dst_reg, src_reg, shamt - 32);
  9727   %}
  9728   ins_pipe( ialu_regL_regL );
  9729 %}
  9731 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
  9732   match(Set dst (URShiftL (CastP2X src) shift));
  9733   ins_cost(80);
  9734   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
  9735   ins_encode %{
  9736     Register src_reg = as_Register($src$$reg);
  9737     Register dst_reg = as_Register($dst$$reg);
  9738     int        shamt = $shift$$constant;
  9740     __ dsrl32(dst_reg, src_reg, shamt - 32);
  9741   %}
  9742   ins_pipe( ialu_regL_regL );
  9743 %}
  9745 // Xor Instructions
  9746 // Xor Register with Register
  9747 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  9748   match(Set dst (XorI src1 src2));
  9750   format %{ "XOR    $dst, $src1, $src2 #@xorI_Reg_Reg" %}
  9752   ins_encode %{
  9753     Register  dst = $dst$$Register;
  9754     Register src1 = $src1$$Register;
  9755     Register src2 = $src2$$Register;
  9756     __ xorr(dst, src1, src2);
  9757     __ sll(dst, dst, 0); /* long -> int */
  9758   %}
  9760   ins_pipe( ialu_regI_regI );
  9761 %}
  9763 // Or Instructions
  9764 // Or Register with Register
  9765 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  9766   match(Set dst (OrI src1 src2));
  9768   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_Reg" %}
  9769   ins_encode %{
  9770     Register  dst = $dst$$Register;
  9771     Register src1 = $src1$$Register;
  9772     Register src2 = $src2$$Register;
  9773     __ orr(dst, src1, src2);
  9774   %}
  9776   ins_pipe( ialu_regI_regI );
  9777 %}
  9779 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
  9780   match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
  9781   predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
  9783   format %{ "rotr     $dst, $src, 1 ...\n\t" 
  9784             "srl      $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
  9785   ins_encode %{
  9786     Register   dst = $dst$$Register;
  9787     Register   src = $src$$Register;
  9788     int     rshift = $rshift$$constant;
  9790     __ rotr(dst, src, 1);
  9791     if (rshift - 1) {
  9792        __ srl(dst, dst, rshift - 1);
  9794   %}
  9796   ins_pipe( ialu_regI_regI );
  9797 %}
  9799 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
  9800   match(Set dst (OrI src1 (CastP2X src2)));
  9802   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_castP2X" %}
  9803   ins_encode %{
  9804     Register  dst = $dst$$Register;
  9805     Register src1 = $src1$$Register;
  9806     Register src2 = $src2$$Register;
  9807     __ orr(dst, src1, src2);
  9808   %}
  9810   ins_pipe( ialu_regI_regI );
  9811 %}
  9813 // Logical Shift Right by 8-bit immediate
  9814 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
  9815   match(Set dst (URShiftI src shift));
  9816  // effect(KILL cr);
  9818   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_imm" %}
  9819   ins_encode %{
  9820     Register src = $src$$Register;
  9821     Register dst = $dst$$Register;
  9822     int    shift = $shift$$constant;
  9824     __ srl(dst, src, shift);
  9825   %}
  9826   ins_pipe( ialu_regI_regI );
  9827 %}
  9829 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
  9830   match(Set dst (AndI (URShiftI src shift) mask));
  9832   format %{ "ext    $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
  9833   ins_encode %{
  9834     Register src = $src$$Register;
  9835     Register dst = $dst$$Register;
  9836     int      pos = $shift$$constant;
  9837     int     size = Assembler::is_int_mask($mask$$constant);
  9839     __ ext(dst, src, pos, size);
  9840   %}
  9841   ins_pipe( ialu_regI_regI );
  9842 %}
  9844 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
  9845 %{
  9846   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
  9847   match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
  9849   ins_cost(100);
  9850   format %{ "rotr    $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
  9851   ins_encode %{
  9852     Register dst = $dst$$Register;
  9853     int      sa  = $rshift$$constant;
  9855     __ rotr(dst, dst, sa);
  9856   %}
  9857   ins_pipe( ialu_regI_regI );
  9858 %}
  9860 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
  9861 %{
  9862   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
  9863   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
  9865   ins_cost(100);
  9866   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
  9867   ins_encode %{
  9868     Register dst = $dst$$Register;
  9869     int      sa  = $rshift$$constant;
  9871     __ drotr(dst, dst, sa);
  9872   %}
  9873   ins_pipe( ialu_regI_regI );
  9874 %}
  9876 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
  9877 %{
  9878   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
  9879   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
  9881   ins_cost(100);
  9882   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
  9883   ins_encode %{
  9884     Register dst = $dst$$Register;
  9885     int      sa  = $rshift$$constant;
  9887     __ drotr32(dst, dst, sa - 32);
  9888   %}
  9889   ins_pipe( ialu_regI_regI );
  9890 %}
  9892 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
  9893 %{
  9894   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
  9895   match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
  9897   ins_cost(100);
  9898   format %{ "rotr    $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
  9899   ins_encode %{
  9900     Register dst = $dst$$Register;
  9901     int      sa  = $rshift$$constant;
  9903     __ rotr(dst, dst, sa);
  9904   %}
  9905   ins_pipe( ialu_regI_regI );
  9906 %}
  9908 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
  9909 %{
  9910   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
  9911   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
  9913   ins_cost(100);
  9914   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
  9915   ins_encode %{
  9916     Register dst = $dst$$Register;
  9917     int      sa  = $rshift$$constant;
  9919     __ drotr(dst, dst, sa);
  9920   %}
  9921   ins_pipe( ialu_regI_regI );
  9922 %}
  9924 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
  9925 %{
  9926   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
  9927   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
  9929   ins_cost(100);
  9930   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
  9931   ins_encode %{
  9932     Register dst = $dst$$Register;
  9933     int      sa  = $rshift$$constant;
  9935     __ drotr32(dst, dst, sa - 32);
  9936   %}
  9937   ins_pipe( ialu_regI_regI );
  9938 %}
  9940 // Logical Shift Right 
  9941 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
  9942   match(Set dst (URShiftI src shift));
  9944   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_Reg" %}
  9945   ins_encode %{
  9946     Register src = $src$$Register;
  9947     Register dst = $dst$$Register;
  9948     Register shift = $shift$$Register;
  9949     __ srlv(dst, src, shift);
  9950   %}
  9951   ins_pipe( ialu_regI_regI );
  9952 %}
  9955 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
  9956   match(Set dst (RShiftI src shift));
  9957  // effect(KILL cr);
  9959   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_imm" %}
  9960   ins_encode %{
  9961     Register src = $src$$Register;
  9962     Register dst = $dst$$Register;
  9963     int    shift = $shift$$constant;
  9964     __ sra(dst, src, shift);
  9965   %}
  9966   ins_pipe( ialu_regI_regI );
  9967 %}
  9969 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
  9970   match(Set dst (RShiftI src shift));
  9971  // effect(KILL cr);
  9973   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_Reg" %}
  9974   ins_encode %{
  9975     Register src = $src$$Register;
  9976     Register dst = $dst$$Register;
  9977     Register shift = $shift$$Register;
  9978     __ srav(dst, src, shift);
  9979   %}
  9980   ins_pipe( ialu_regI_regI );
  9981 %}
  9983 //----------Convert Int to Boolean---------------------------------------------
  9985 instruct convI2B(mRegI dst, mRegI src) %{
  9986   match(Set dst (Conv2B src));
  9988   ins_cost(100);
  9989   format %{ "convI2B    $dst, $src @ convI2B"  %}
  9990   ins_encode %{
  9991     Register dst = as_Register($dst$$reg);
  9992     Register src = as_Register($src$$reg);
  9994     if (dst != src) {
  9995       __ daddiu(dst, R0, 1);
  9996       __ movz(dst, R0, src);
  9997     } else {
  9998       __ move(AT, src);
  9999       __ daddiu(dst, R0, 1);
 10000       __ movz(dst, R0, AT);
 10002   %}
 10004   ins_pipe( ialu_regL_regL );
 10005 %}
 10007 instruct convI2L_reg( mRegL dst, mRegI src) %{
 10008   match(Set dst (ConvI2L src));
 10010   ins_cost(100);
 10011   format %{ "SLL    $dst, $src @ convI2L_reg\t"  %}
 10012   ins_encode %{
 10013     Register dst = as_Register($dst$$reg);
 10014     Register src = as_Register($src$$reg);
 10016     if(dst != src) __ sll(dst, src, 0);
 10017   %}
 10018   ins_pipe( ialu_regL_regL );
 10019 %}
 10022 instruct convL2I_reg( mRegI dst, mRegL src ) %{
 10023   match(Set dst (ConvL2I src));
 10025   format %{ "MOV    $dst, $src @ convL2I_reg" %}
 10026   ins_encode %{
 10027     Register dst = as_Register($dst$$reg);
 10028     Register src = as_Register($src$$reg);
 10030     __ sll(dst, src, 0);
 10031   %}
 10033   ins_pipe( ialu_regI_regI );
 10034 %}
 10036 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
 10037   match(Set dst (ConvI2L (ConvL2I src)));
 10039   format %{ "sll    $dst, $src, 0 @ convL2I2L_reg" %}
 10040   ins_encode %{
 10041     Register dst = as_Register($dst$$reg);
 10042     Register src = as_Register($src$$reg);
 10044     __ sll(dst, src, 0);
 10045   %}
 10047   ins_pipe( ialu_regI_regI );
 10048 %}
 10050 instruct convL2D_reg( regD dst, mRegL src ) %{
 10051   match(Set dst (ConvL2D src));
 10052   format %{ "convL2D    $dst, $src @ convL2D_reg" %}
 10053   ins_encode %{
 10054     Register src = as_Register($src$$reg);
 10055     FloatRegister dst = as_FloatRegister($dst$$reg);
 10057     __ dmtc1(src, dst);
 10058     __ cvt_d_l(dst, dst);
 10059   %}
 10061   ins_pipe( pipe_slow );
 10062 %}
 10064 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
 10065   match(Set dst (ConvD2L src));
 10066   ins_cost(150);
 10067   format %{ "convD2L    $dst, $src @ convD2L_reg_fast" %}
 10068   ins_encode %{
 10069     Register dst = as_Register($dst$$reg);
 10070     FloatRegister src = as_FloatRegister($src$$reg);
 10072     Label Done;
 10074     __ trunc_l_d(F30, src);
 10075     // max_long:    0x7fffffffffffffff 
 10076     // __ set64(AT, 0x7fffffffffffffff);
 10077     __ daddiu(AT, R0, -1);
 10078     __ dsrl(AT, AT, 1);
 10079     __ dmfc1(dst, F30);
 10081     __ bne(dst, AT, Done);
 10082     __ delayed()->mtc1(R0, F30);
 10084     __ cvt_d_w(F30, F30);
 10085     __ c_ult_d(src, F30);
 10086     __ bc1f(Done);
 10087     __ delayed()->daddiu(T9, R0, -1);
 10089     __ c_un_d(src, src);    //NaN?
 10090     __ subu(dst, T9, AT);
 10091     __ movt(dst, R0);
 10093     __ bind(Done);
 10094   %}
 10096   ins_pipe( pipe_slow );
 10097 %}
 10099 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
 10100   match(Set dst (ConvD2L src));
 10101   ins_cost(250);
 10102   format %{ "convD2L    $dst, $src @ convD2L_reg_slow" %}
 10103   ins_encode %{
 10104     Register dst = as_Register($dst$$reg);
 10105     FloatRegister src = as_FloatRegister($src$$reg);
 10107     Label L;
 10109     __ c_un_d(src, src);    //NaN?
 10110     __ bc1t(L);
 10111     __ delayed();
 10112     __ move(dst, R0);
 10114     __ trunc_l_d(F30, src);
 10115     __ cfc1(AT, 31);
 10116     __ li(T9, 0x10000);
 10117     __ andr(AT, AT, T9);
 10118     __ beq(AT, R0, L);
 10119     __ delayed()->dmfc1(dst, F30);
 10121     __ mov_d(F12, src);
 10122     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
 10123     __ move(dst, V0);
 10124     __ bind(L);
 10125   %}
 10127   ins_pipe( pipe_slow );
 10128 %}
 10130 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
 10131   match(Set dst (ConvF2I src));
 10132   ins_cost(150);
 10133   format %{ "convf2i    $dst, $src @ convF2I_reg_fast" %}
 10134   ins_encode %{
 10135     Register      dreg = $dst$$Register;
 10136     FloatRegister fval = $src$$FloatRegister;
 10138     __ trunc_w_s(F30, fval);
 10139     __ mfc1(dreg, F30);
 10140     __ c_un_s(fval, fval);    //NaN?
 10141     __ movt(dreg, R0);
 10142   %}
 10144   ins_pipe( pipe_slow );
 10145 %}
 10147 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
 10148   match(Set dst (ConvF2I src));
 10149   ins_cost(250);
 10150   format %{ "convf2i    $dst, $src @ convF2I_reg_slow" %}
 10151   ins_encode %{
 10152     Register      dreg = $dst$$Register;
 10153     FloatRegister fval = $src$$FloatRegister;
 10154     Label L;
 10156     __ c_un_s(fval, fval);    //NaN?
 10157     __ bc1t(L);
 10158     __ delayed();
 10159     __ move(dreg, R0);
 10161     __ trunc_w_s(F30, fval);
 10163     /* Call SharedRuntime:f2i() to do valid convention */
 10164     __ cfc1(AT, 31);
 10165     __ li(T9, 0x10000);
 10166     __ andr(AT, AT, T9);
 10167     __ beq(AT, R0, L);
 10168     __ delayed()->mfc1(dreg, F30);
 10170     __ mov_s(F12, fval);
 10172     /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
 10173      *    J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
 10175      * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE. 
 10176      * V0 is corrupted during call_VM_leaf(), and should be preserved.
 10177      */
 10178     if(dreg != V0) {
 10179       __ push(V0); 
 10181     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
 10182     if(dreg != V0) {
 10183       __ move(dreg, V0);
 10184       __ pop(V0);
 10186     __ bind(L);
 10187   %}
 10189   ins_pipe( pipe_slow );
 10190 %}
 10192 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
 10193   match(Set dst (ConvF2L src));
 10194   ins_cost(150);
 10195   format %{ "convf2l    $dst, $src @ convF2L_reg_fast" %}
 10196   ins_encode %{
 10197     Register      dreg = $dst$$Register;
 10198     FloatRegister fval = $src$$FloatRegister;
 10200     __ trunc_l_s(F30, fval);
 10201     __ dmfc1(dreg, F30);
 10202     __ c_un_s(fval, fval);    //NaN?
 10203     __ movt(dreg, R0);
 10204   %}
 10206   ins_pipe( pipe_slow );
 10207 %}
 10209 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
 10210   match(Set dst (ConvF2L src));
 10211   ins_cost(250);
 10212   format %{ "convf2l    $dst, $src @ convF2L_reg_slow" %}
 10213   ins_encode %{
 10214     Register dst = as_Register($dst$$reg);
 10215     FloatRegister fval = $src$$FloatRegister;
 10216     Label L;
 10218     __ c_un_s(fval, fval);    //NaN?
 10219     __ bc1t(L);
 10220     __ delayed();
 10221     __ move(dst, R0);
 10223     __ trunc_l_s(F30, fval);
 10224     __ cfc1(AT, 31);
 10225     __ li(T9, 0x10000);
 10226     __ andr(AT, AT, T9);
 10227     __ beq(AT, R0, L);
 10228     __ delayed()->dmfc1(dst, F30);
 10230     __ mov_s(F12, fval);
 10231     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
 10232     __ move(dst, V0);
 10233     __ bind(L);
 10234   %}
 10236   ins_pipe( pipe_slow );
 10237 %}
 10239 instruct convL2F_reg( regF dst, mRegL src ) %{
 10240   match(Set dst (ConvL2F src));
 10241   format %{ "convl2f    $dst, $src @ convL2F_reg" %}
 10242   ins_encode %{
 10243     FloatRegister dst = $dst$$FloatRegister;
 10244     Register src = as_Register($src$$reg);
 10245     Label L;
 10247     __ dmtc1(src, dst);
 10248     __ cvt_s_l(dst, dst);
 10249   %}
 10251   ins_pipe( pipe_slow );
 10252 %}
 10254 instruct convI2F_reg( regF dst, mRegI src ) %{
 10255   match(Set dst (ConvI2F src));
 10256   format %{ "convi2f    $dst, $src @ convI2F_reg" %}
 10257   ins_encode %{
 10258     Register      src = $src$$Register;
 10259     FloatRegister dst = $dst$$FloatRegister;
 10261     __ mtc1(src, dst);
 10262     __ cvt_s_w(dst, dst);
 10263   %}
 10265   ins_pipe( fpu_regF_regF );
 10266 %}
 10268 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
 10269   match(Set dst (CmpLTMask p zero));
 10270   ins_cost(100);
 10272   format %{ "sra    $dst, $p, 31 @ cmpLTMask_immI0" %}
 10273     ins_encode %{
 10274        Register src = $p$$Register;
 10275        Register dst = $dst$$Register;
 10277        __ sra(dst, src, 31);
 10278     %}
 10279     ins_pipe( pipe_slow );
 10280 %}
 10283 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
 10284   match(Set dst (CmpLTMask p q));
 10285   ins_cost(400);
 10287   format %{ "cmpLTMask    $dst, $p, $q @ cmpLTMask" %}
 10288     ins_encode %{
 10289        Register p   = $p$$Register;
 10290        Register q   = $q$$Register;
 10291        Register dst = $dst$$Register;
 10293        __ slt(dst, p, q);
 10294        __ subu(dst, R0, dst);
 10295     %}
 10296     ins_pipe( pipe_slow );
 10297 %}
 10299 instruct convP2B(mRegI dst, mRegP src) %{
 10300   match(Set dst (Conv2B src));
 10302   ins_cost(100);
 10303   format %{ "convP2B    $dst, $src @ convP2B"  %}
 10304   ins_encode %{
 10305     Register dst = as_Register($dst$$reg);
 10306     Register src = as_Register($src$$reg);
 10308     if (dst != src) {
 10309       __ daddiu(dst, R0, 1);
 10310       __ movz(dst, R0, src);
 10311     } else {
 10312       __ move(AT, src);
 10313       __ daddiu(dst, R0, 1);
 10314       __ movz(dst, R0, AT);
 10316   %}
 10318   ins_pipe( ialu_regL_regL );
 10319 %}
 10322 instruct convI2D_reg_reg(regD dst, mRegI src) %{
 10323   match(Set dst (ConvI2D src));
 10324   format %{ "conI2D $dst, $src @convI2D_reg" %}
 10325   ins_encode %{
 10326      Register      src = $src$$Register;
 10327      FloatRegister dst = $dst$$FloatRegister;
 10328      __ mtc1(src, dst);
 10329      __ cvt_d_w(dst, dst);
 10330   %}
 10331   ins_pipe( fpu_regF_regF );
 10332 %}
 10334 instruct convF2D_reg_reg(regD dst, regF src) %{
 10335   match(Set dst (ConvF2D src));
 10336   format %{ "convF2D  $dst, $src\t# @convF2D_reg_reg" %}
 10337   ins_encode %{
 10338     FloatRegister dst = $dst$$FloatRegister;
 10339     FloatRegister src = $src$$FloatRegister;
 10341     __ cvt_d_s(dst, src);
 10342   %}
 10343   ins_pipe( fpu_regF_regF );
 10344 %}
 10346 instruct convD2F_reg_reg(regF dst, regD src) %{
 10347   match(Set dst (ConvD2F src));
 10348   format %{ "convD2F  $dst, $src\t# @convD2F_reg_reg" %}
 10349   ins_encode %{
 10350     FloatRegister dst = $dst$$FloatRegister;
 10351     FloatRegister src = $src$$FloatRegister;
 10353     __ cvt_s_d(dst, src);
 10354   %}
 10355   ins_pipe( fpu_regF_regF );
 10356 %}
 10358 // Convert a double to an int.  If the double is a NAN, stuff a zero in instead.
 10359 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
 10360   match(Set dst (ConvD2I src));
 10362   ins_cost(150);
 10363   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
 10365   ins_encode %{
 10366       FloatRegister src = $src$$FloatRegister;
 10367       Register      dst = $dst$$Register;
 10369       Label Done;
 10371       __ trunc_w_d(F30, src);
 10372       // max_int: 2147483647
 10373       __ move(AT, 0x7fffffff);
 10374       __ mfc1(dst, F30);
 10376       __ bne(dst, AT, Done);
 10377       __ delayed()->mtc1(R0, F30);
 10379       __ cvt_d_w(F30, F30); 
 10380       __ c_ult_d(src, F30);
 10381       __ bc1f(Done);
 10382       __ delayed()->addiu(T9, R0, -1);
 10384       __ c_un_d(src, src);    //NaN?
 10385       __ subu32(dst, T9, AT);
 10386       __ movt(dst, R0);
 10388       __ bind(Done);
 10389   %}
 10390   ins_pipe( pipe_slow );
 10391 %}
 10393 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
 10394   match(Set dst (ConvD2I src));
 10396   ins_cost(250);
 10397   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
 10399   ins_encode %{
 10400       FloatRegister src = $src$$FloatRegister;
 10401       Register      dst = $dst$$Register;
 10402       Label L;
 10404       __ trunc_w_d(F30, src);
 10405       __ cfc1(AT, 31);
 10406       __ li(T9, 0x10000);
 10407       __ andr(AT, AT, T9);
 10408       __ beq(AT, R0, L);
 10409       __ delayed()->mfc1(dst, F30);
 10411       __ mov_d(F12, src);
 10412       __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
 10413       __ move(dst, V0);
 10414       __ bind(L);
 10416   %}
 10417   ins_pipe( pipe_slow );
 10418 %}
 10420 // Convert oop pointer into compressed form
 10421 instruct encodeHeapOop(mRegN dst, mRegP src) %{
 10422   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 10423   match(Set dst (EncodeP src));
 10424   format %{ "encode_heap_oop $dst,$src" %}
 10425   ins_encode %{
 10426     Register src = $src$$Register;
 10427     Register dst = $dst$$Register;
 10428     if (src != dst) {
 10429       __ move(dst, src);
 10431     __ encode_heap_oop(dst);
 10432   %}
 10433   ins_pipe( ialu_regL_regL );
 10434 %}
 10436 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
 10437   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
 10438   match(Set dst (EncodeP src));
 10439   format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
 10440   ins_encode %{
 10441     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
 10442   %}
 10443   ins_pipe( ialu_regL_regL );
 10444 %}
 10446 instruct decodeHeapOop(mRegP dst, mRegN src) %{
 10447   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
 10448             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
 10449   match(Set dst (DecodeN src));
 10450   format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
 10451   ins_encode %{
 10452     Register s = $src$$Register;
 10453     Register d = $dst$$Register;
 10454     if (s != d) {
 10455       __ move(d, s);
 10457     __ decode_heap_oop(d);
 10458   %}
 10459   ins_pipe( ialu_regL_regL );
 10460 %}
 10462 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
 10463   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
 10464             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
 10465   match(Set dst (DecodeN src));
 10466   format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
 10467   ins_encode %{
 10468     Register s = $src$$Register;
 10469     Register d = $dst$$Register;
 10470     if (s != d) {
 10471       __ decode_heap_oop_not_null(d, s);
 10472     } else {
 10473       __ decode_heap_oop_not_null(d);
 10475   %}
 10476   ins_pipe( ialu_regL_regL );
 10477 %}
 10479 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
 10480   match(Set dst (EncodePKlass src));
 10481   format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
 10482   ins_encode %{
 10483     __ encode_klass_not_null($dst$$Register, $src$$Register);
 10484   %}
 10485   ins_pipe( ialu_regL_regL );
 10486 %}
 10488 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
 10489   match(Set dst (DecodeNKlass src));
 10490   format %{ "decode_heap_klass_not_null $dst,$src" %}
 10491   ins_encode %{
 10492     Register s = $src$$Register;
 10493     Register d = $dst$$Register;
 10494     if (s != d) {
 10495       __ decode_klass_not_null(d, s);
 10496     } else {
 10497       __ decode_klass_not_null(d);
 10499   %}
 10500   ins_pipe( ialu_regL_regL );
 10501 %}
 10503 //FIXME
 10504 instruct tlsLoadP(mRegP dst) %{
 10505   match(Set dst (ThreadLocal));
 10507   ins_cost(0);
 10508   format %{ " get_thread in $dst #@tlsLoadP" %}
 10509   ins_encode %{
 10510     Register dst = $dst$$Register;
 10511 #ifdef OPT_THREAD
 10512     __ move(dst, TREG);
 10513 #else
 10514     __ get_thread(dst);
 10515 #endif
 10516   %}
 10518   ins_pipe( ialu_loadI );
 10519 %}
 10522 instruct checkCastPP( mRegP dst ) %{
 10523   match(Set dst (CheckCastPP dst));
 10525   format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
 10526   ins_encode( /*empty encoding*/ );
 10527   ins_pipe( empty );
 10528 %}
 10530 instruct castPP(mRegP dst)
 10531 %{
 10532   match(Set dst (CastPP dst));
 10534   size(0);
 10535   format %{ "# castPP of $dst" %}
 10536   ins_encode(/* empty encoding */);
 10537   ins_pipe(empty);
 10538 %}
 10540 instruct castII( mRegI dst ) %{
 10541   match(Set dst (CastII dst));
 10542   format %{ "#castII of $dst  empty encoding" %}
 10543   ins_encode( /*empty encoding*/ );
 10544   ins_cost(0);
 10545   ins_pipe( empty );
 10546 %}
 10548 // Return Instruction
 10549 // Remove the return address & jump to it.
 10550 instruct Ret() %{
 10551   match(Return);
 10552   format %{ "RET #@Ret" %}
 10554   ins_encode %{
 10555    __ jr(RA); 
 10556    __ nop();
 10557   %}
 10559   ins_pipe( pipe_jump );
 10560 %}
 10562 /*
 10563 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
 10564 instruct jumpXtnd(mRegL switch_val) %{
 10565   match(Jump switch_val);
 10567   ins_cost(350);
 10569   format %{  "load   T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
 10570              "jr     T9\n\t"
 10571              "nop" %}
 10572   ins_encode %{
 10573     Register table_base = $constanttablebase;
 10574     int      con_offset = $constantoffset;
 10575     Register switch_reg = $switch_val$$Register;
 10577     if (UseLoongsonISA) {
 10578        if (Assembler::is_simm(con_offset, 8)) {
 10579          __ gsldx(T9, table_base, switch_reg, con_offset);
 10580        } else if (Assembler::is_simm16(con_offset)) {
 10581          __ daddu(T9, table_base, switch_reg);
 10582          __ ld(T9, T9, con_offset);
 10583        } else {
 10584          __ move(T9, con_offset);
 10585          __ daddu(AT, table_base, switch_reg);
 10586          __ gsldx(T9, AT, T9, 0);
 10588     } else {
 10589        if (Assembler::is_simm16(con_offset)) {
 10590          __ daddu(T9, table_base, switch_reg);
 10591          __ ld(T9, T9, con_offset);
 10592        } else {
 10593          __ move(T9, con_offset);
 10594          __ daddu(AT, table_base, switch_reg);
 10595          __ daddu(AT, T9, AT);
 10596          __ ld(T9, AT, 0);
 10600     __ jr(T9);
 10601     __ nop();
 10603   %}
 10604   ins_pipe(pipe_jump);
 10605 %}
 10606 */
 10608 // Jump Direct - Label defines a relative address from JMP
 10609 instruct jmpDir(label labl) %{
 10610   match(Goto);
 10611   effect(USE labl);
 10613   ins_cost(300);
 10614   format %{ "JMP    $labl #@jmpDir" %}
 10616   ins_encode %{
 10617     Label &L = *($labl$$label);
 10618     if(&L)
 10619     	 __ b(L);
 10620     else
 10621          __ b(int(0));
 10622     __ nop();
 10623   %}
 10625     ins_pipe( pipe_jump );
 10626     ins_pc_relative(1);
 10627 %}
 10631 // Tail Jump; remove the return address; jump to target.
 10632 // TailCall above leaves the return address around.
 10633 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 10634 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 10635 // "restore" before this instruction (in Epilogue), we need to materialize it
 10636 // in %i0.
 10637 //FIXME
 10638 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
 10639   match( TailJump jump_target ex_oop );
 10640   ins_cost(200);
 10641   format %{ "Jmp     $jump_target  ; ex_oop = $ex_oop #@tailjmpInd" %}
 10642   ins_encode %{
 10643     Register target = $jump_target$$Register;
 10645     /* 2012/9/14 Jin: V0, V1 are indicated in:
 10646      *      [stubGenerator_mips.cpp] generate_forward_exception()
 10647      *      [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
 10648      */
 10649     Register oop  = $ex_oop$$Register;
 10650     Register exception_oop = V0;
 10651     Register exception_pc = V1;
 10653     __ move(exception_pc, RA);
 10654     __ move(exception_oop, oop);
 10656     __ jr(target);  
 10657     __ nop();
 10658   %}
 10659   ins_pipe( pipe_jump ); 
 10660 %}
 10662 // ============================================================================
 10663 // Procedure Call/Return Instructions
 10664 // Call Java Static Instruction
 10665 // Note: If this code changes, the corresponding ret_addr_offset() and
 10666 //       compute_padding() functions will have to be adjusted.
 10667 instruct CallStaticJavaDirect(method meth) %{
 10668   match(CallStaticJava);
 10669   effect(USE meth);
 10671   ins_cost(300);
 10672   format %{ "CALL,static #@CallStaticJavaDirect " %}
 10673   ins_encode( Java_Static_Call( meth ) );
 10674   ins_pipe( pipe_slow );
 10675   ins_pc_relative(1);
 10676 %}
 10678 // Call Java Dynamic Instruction
 10679 // Note: If this code changes, the corresponding ret_addr_offset() and
 10680 //       compute_padding() functions will have to be adjusted.
 10681 instruct CallDynamicJavaDirect(method meth) %{
 10682   match(CallDynamicJava);
 10683   effect(USE meth);
 10685   ins_cost(300);
 10686   format %{"MOV IC_Klass, (oop)-1\n\t"
 10687            "CallDynamic @ CallDynamicJavaDirect" %}
 10688   ins_encode( Java_Dynamic_Call( meth ) );
 10689   ins_pipe( pipe_slow );
 10690   ins_pc_relative(1);
 10691 %}
 10693 instruct CallLeafNoFPDirect(method meth) %{
 10694   match(CallLeafNoFP);
 10695   effect(USE meth);
 10697   ins_cost(300);
 10698   format %{ "CALL_LEAF_NOFP,runtime " %}
 10699   ins_encode(Java_To_Runtime(meth));
 10700   ins_pipe( pipe_slow );
 10701   ins_pc_relative(1);
 10702   ins_alignment(16);
 10703 %}
 10705 // Prefetch instructions.
 10707 instruct prefetchrNTA( umemory mem ) %{
 10708   match(PrefetchRead mem);
 10709   ins_cost(125);
 10711   format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
 10712   ins_encode %{
 10713     int  base = $mem$$base;
 10714     int  index = $mem$$index;
 10715     int  scale = $mem$$scale;
 10716     int  disp = $mem$$disp;
 10718     assert(index == 0, "no index");
 10719     __ daddiu(AT, as_Register(base), disp);
 10720     __ pref(0, AT, 0); //hint: 0:load
 10721   %}
 10722   ins_pipe(pipe_slow);
 10723 %}
 10725 instruct prefetchwNTA( umemory mem ) %{
 10726   match(PrefetchWrite mem);
 10727   ins_cost(125);
 10728   format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
 10729   ins_encode %{
 10730     int  base = $mem$$base;
 10731     int  index = $mem$$index;
 10732     int  scale = $mem$$scale;
 10733     int  disp = $mem$$disp;
 10735     assert(index == 0, "no index");
 10736     __ daddiu(AT, as_Register(base), disp);
 10737     __ pref(1, AT, 0); //hint: 1:store
 10738   %}
 10739   ins_pipe(pipe_slow);
 10740 %}
 10742 // Prefetch instructions for allocation.
 10744 instruct prefetchAllocNTA( memory mem ) %{
 10745   match(PrefetchAllocation mem);
 10746   ins_cost(125);
 10747   format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
 10748   ins_encode %{
 10749      int  base = $mem$$base;
 10750      int  index = $mem$$index;
 10751      int  scale = $mem$$scale;
 10752      int  disp = $mem$$disp;
 10754      Register dst = R0;
 10756      if( index != 0 ) {
 10757         assert(UseLoongsonISA, "Only supported for Loongson CPUs");
 10758         __ gslbx(dst, as_Register(base), as_Register(index), disp);
 10759      } else {
 10760         __ lb(dst, as_Register(base), disp);
 10762   %}
 10763   ins_pipe(pipe_slow);
 10764 %}
 10767 // Call runtime without safepoint
 10768 instruct CallLeafDirect(method meth) %{
 10769   match(CallLeaf);
 10770   effect(USE meth);
 10772   ins_cost(300);
 10773   format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
 10774   ins_encode(Java_To_Runtime(meth));
 10775   ins_pipe( pipe_slow );
 10776   ins_pc_relative(1);
 10777   ins_alignment(16);
 10778 %}
 10780 // Load Char (16bit unsigned)
 10781 instruct loadUS(mRegI dst, umemory mem) %{
 10782   match(Set dst (LoadUS mem));
 10784   ins_cost(125);
 10785   format %{ "loadUS  $dst,$mem @ loadC" %}
 10786   ins_encode(load_C_enc(dst, mem));
 10787   ins_pipe( ialu_loadI );
 10788 %}
 10790 instruct loadUS_convI2L(mRegL dst, umemory mem) %{
 10791   match(Set dst (ConvI2L (LoadUS mem)));
 10793   ins_cost(125);
 10794   format %{ "loadUS  $dst,$mem @ loadUS_convI2L" %}
 10795   ins_encode(load_C_enc(dst, mem));
 10796   ins_pipe( ialu_loadI );
 10797 %}
 10799 // Store Char (16bit unsigned)
 10800 instruct storeC(memory mem, mRegI src) %{
 10801   match(Set mem (StoreC mem src));
 10803   ins_cost(125);
 10804   format %{ "storeC  $src, $mem @ storeC" %}
 10805   ins_encode(store_C_reg_enc(mem, src));
 10806   ins_pipe( ialu_loadI );
 10807 %}
 10809 instruct storeC0(memory mem, immI0 zero) %{
 10810   match(Set mem (StoreC mem zero));
 10812   ins_cost(125);
 10813   format %{ "storeC  $zero, $mem @ storeC0" %}
 10814   ins_encode(store_C0_enc(mem));
 10815   ins_pipe( ialu_loadI );
 10816 %}
 10819 instruct loadConF0(regF dst, immF0 zero) %{
 10820   match(Set dst zero);
 10821   ins_cost(100);
 10823   format %{ "mov  $dst, zero @ loadConF0\n"%}
 10824   ins_encode %{
 10825     FloatRegister dst = $dst$$FloatRegister;
 10827     __ mtc1(R0, dst);
 10828   %}
 10829   ins_pipe( fpu_loadF );
 10830 %}
 10833 instruct loadConF(regF dst, immF src) %{
 10834   match(Set dst src);
 10835   ins_cost(125);
 10837   format %{ "lwc1  $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
 10838   ins_encode %{
 10839     int con_offset = $constantoffset($src);
 10841     if (Assembler::is_simm16(con_offset)) {
 10842        __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
 10843     } else {
 10844        __ set64(AT, con_offset);
 10845        if (UseLoongsonISA) {
 10846           __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 10847        } else {
 10848           __ daddu(AT, $constanttablebase, AT);
 10849           __ lwc1($dst$$FloatRegister, AT, 0);
 10852   %}
 10853   ins_pipe( fpu_loadF );
 10854 %}
 10857 instruct loadConD0(regD dst, immD0 zero) %{
 10858   match(Set dst zero);
 10859   ins_cost(100);
 10861   format %{ "mov  $dst, zero @ loadConD0"%}
 10862   ins_encode %{
 10863     FloatRegister dst = as_FloatRegister($dst$$reg);
 10865     __ dmtc1(R0, dst);
 10866   %}
 10867   ins_pipe( fpu_loadF );
 10868 %}
 10870 instruct loadConD(regD dst, immD src) %{
 10871   match(Set dst src);
 10872   ins_cost(125);
 10874   format %{ "ldc1  $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
 10875   ins_encode %{
 10876     int con_offset = $constantoffset($src);
 10878     if (Assembler::is_simm16(con_offset)) {
 10879        __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
 10880     } else {
 10881        __ set64(AT, con_offset);
 10882        if (UseLoongsonISA) {
 10883           __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 10884        } else {
 10885           __ daddu(AT, $constanttablebase, AT);
 10886           __ ldc1($dst$$FloatRegister, AT, 0);
 10889   %}
 10890   ins_pipe( fpu_loadF );
 10891 %}
 10893 // Store register Float value (it is faster than store from FPU register)
 10894 instruct storeF_reg( memory mem, regF src) %{
 10895   match(Set mem (StoreF mem src));
 10897   ins_cost(50);
 10898   format %{ "store   $mem, $src\t# store float @ storeF_reg" %}
 10899   ins_encode(store_F_reg_enc(mem, src));
 10900   ins_pipe( fpu_storeF );
 10901 %}
 10903 instruct storeF_imm0( memory mem, immF0 zero) %{
 10904   match(Set mem (StoreF mem zero));
 10906   ins_cost(40);
 10907   format %{ "store   $mem, zero\t# store float @ storeF_imm0" %}
 10908   ins_encode %{
 10909     int      base = $mem$$base;
 10910     int     index = $mem$$index;
 10911     int     scale = $mem$$scale;
 10912     int      disp = $mem$$disp;
 10914     if( index != 0 ) {
 10915        assert(UseLoongsonISA, "Only supported for Loongson CPUs");
 10916        __ gsswx(R0, as_Register(base), as_Register(index), disp);
 10917     } else {
 10918        __ sw(R0, as_Register(base), disp);
 10920   %}
 10921   ins_pipe( ialu_storeI );
 10922 %}
 10924 // Load Double
 10925 instruct loadD(regD dst, memory mem) %{
 10926   match(Set dst (LoadD mem));
 10928   ins_cost(150);
 10929   format %{ "loadD   $dst, $mem #@loadD" %}
 10930   ins_encode(load_D_enc(dst, mem));
 10931   ins_pipe( ialu_loadI );
 10932 %}
 10934 // Load Double - UNaligned
 10935 instruct loadD_unaligned(regD dst, memory mem ) %{
 10936   match(Set dst (LoadD_unaligned mem));
 10937   ins_cost(250);
 10938   // FIXME: Jin: Need more effective ldl/ldr
 10939   format %{ "loadD_unaligned   $dst, $mem #@loadD_unaligned" %}
 10940   ins_encode(load_D_enc(dst, mem));
 10941   ins_pipe( ialu_loadI );
 10942 %}
 10944 instruct storeD_reg( memory mem, regD src) %{
 10945   match(Set mem (StoreD mem src));
 10947   ins_cost(50);
 10948   format %{ "store   $mem, $src\t# store float @ storeD_reg" %}
 10949   ins_encode(store_D_reg_enc(mem, src));
 10950   ins_pipe( fpu_storeF );
 10951 %}
 10953 instruct loadSSI(mRegI dst, stackSlotI src)
 10954 %{
 10955   match(Set dst src);
 10957   ins_cost(125);
 10958   format %{ "lw    $dst, $src\t# int stk @ loadSSI" %}
 10959   ins_encode %{
 10960     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
 10961     __ lw($dst$$Register, SP, $src$$disp);
 10962   %}
 10963   ins_pipe(ialu_loadI);
 10964 %}
 10966 instruct storeSSI(stackSlotI dst, mRegI src)
 10967 %{
 10968   match(Set dst src);
 10970   ins_cost(100);
 10971   format %{ "sw    $dst, $src\t# int stk @ storeSSI" %}
 10972   ins_encode %{
 10973     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
 10974     __ sw($src$$Register, SP, $dst$$disp);
 10975   %}
 10976   ins_pipe(ialu_storeI);
 10977 %}
 10979 instruct loadSSL(mRegL dst, stackSlotL src)
 10980 %{
 10981   match(Set dst src);
 10983   ins_cost(125);
 10984   format %{ "ld    $dst, $src\t# long stk @ loadSSL" %}
 10985   ins_encode %{
 10986     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
 10987     __ ld($dst$$Register, SP, $src$$disp);
 10988   %}
 10989   ins_pipe(ialu_loadI);
 10990 %}
 10992 instruct storeSSL(stackSlotL dst, mRegL src)
 10993 %{
 10994   match(Set dst src);
 10996   ins_cost(100);
 10997   format %{ "sd    $dst, $src\t# long stk @ storeSSL" %}
 10998   ins_encode %{
 10999     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
 11000     __ sd($src$$Register, SP, $dst$$disp);
 11001   %}
 11002   ins_pipe(ialu_storeI);
 11003 %}
 11005 instruct loadSSP(mRegP dst, stackSlotP src)
 11006 %{
 11007   match(Set dst src);
 11009   ins_cost(125);
 11010   format %{ "ld    $dst, $src\t# ptr stk @ loadSSP" %}
 11011   ins_encode %{
 11012     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
 11013     __ ld($dst$$Register, SP, $src$$disp);
 11014   %}
 11015   ins_pipe(ialu_loadI);
 11016 %}
 11018 instruct storeSSP(stackSlotP dst, mRegP src)
 11019 %{
 11020   match(Set dst src);
 11022   ins_cost(100);
 11023   format %{ "sd    $dst, $src\t# ptr stk @ storeSSP" %}
 11024   ins_encode %{
 11025     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
 11026     __ sd($src$$Register, SP, $dst$$disp);
 11027   %}
 11028   ins_pipe(ialu_storeI);
 11029 %}
 11031 instruct loadSSF(regF dst, stackSlotF src)
 11032 %{
 11033   match(Set dst src);
 11035   ins_cost(125);
 11036   format %{ "lwc1   $dst, $src\t# float stk @ loadSSF" %}
 11037   ins_encode %{
 11038     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
 11039     __ lwc1($dst$$FloatRegister, SP, $src$$disp);
 11040   %}
 11041   ins_pipe(ialu_loadI);
 11042 %}
 11044 instruct storeSSF(stackSlotF dst, regF src)
 11045 %{
 11046   match(Set dst src);
 11048   ins_cost(100);
 11049   format %{ "swc1    $dst, $src\t# float stk @ storeSSF" %}
 11050   ins_encode %{
 11051     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
 11052     __ swc1($src$$FloatRegister, SP, $dst$$disp);
 11053   %}
 11054   ins_pipe(fpu_storeF);
 11055 %}
 11057 // Use the same format since predicate() can not be used here.
 11058 instruct loadSSD(regD dst, stackSlotD src)
 11059 %{
 11060   match(Set dst src);
 11062   ins_cost(125);
 11063   format %{ "ldc1   $dst, $src\t# double stk @ loadSSD" %}
 11064   ins_encode %{
 11065     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
 11066     __ ldc1($dst$$FloatRegister, SP, $src$$disp);
 11067   %}
 11068   ins_pipe(ialu_loadI);
 11069 %}
 11071 instruct storeSSD(stackSlotD dst, regD src)
 11072 %{
 11073   match(Set dst src);
 11075   ins_cost(100);
 11076   format %{ "sdc1    $dst, $src\t# double stk @ storeSSD" %}
 11077   ins_encode %{
 11078     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
 11079     __ sdc1($src$$FloatRegister, SP, $dst$$disp);
 11080   %}
 11081   ins_pipe(fpu_storeF);
 11082 %}
 11084 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
 11085   match( Set cr (FastLock object box) );
 11086   effect( TEMP tmp, TEMP scr, USE_KILL box );
 11087   ins_cost(300);
 11088   format %{ "FASTLOCK $cr $object, $box, $tmp #@ cmpFastLock" %}
 11089   ins_encode %{
 11090     __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
 11091   %}
 11093   ins_pipe( pipe_slow );
 11094   ins_pc_relative(1);
 11095 %}
 11097 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
 11098   match( Set cr (FastUnlock object box) );
 11099   effect( TEMP tmp, USE_KILL box );
 11100   ins_cost(300);
 11101   format %{ "FASTUNLOCK $object, $box, $tmp #@cmpFastUnlock" %}
 11102   ins_encode %{
 11103     __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
 11104   %}
 11106   ins_pipe( pipe_slow );
 11107   ins_pc_relative(1);
 11108 %}
 11110 // Store CMS card-mark Immediate
 11111 instruct storeImmCM(memory mem, mRegI src) %{
 11112   match(Set mem (StoreCM mem src));
 11114   ins_cost(500);
 11115   format %{ "sb   $src, $mem  (CMS card-mark) @ storeImmCM" %}
 11116   ins_encode(store_B_reg_sync_enc(mem, src));
 11117   ins_pipe( ialu_storeI );
 11118 %}
 11120 instruct storeI0CM(memory mem, immI0 zero) %{
 11121   match(Set mem (StoreCM mem zero));
 11123   ins_cost(450);
 11124   format %{ "sb   $zero, $mem  (CMS card-mark) @ storeI0CM" %}
 11125   ins_encode(store_B0_sync_enc(mem));
 11126   ins_pipe( ialu_storeI );
 11127 %}
 11129 // Die now
 11130 instruct ShouldNotReachHere( )
 11131 %{
 11132   match(Halt);
 11133   ins_cost(300);
 11135   // Use the following format syntax
 11136   format %{ "ILLTRAP   ;#@ShouldNotReachHere" %}
 11137   ins_encode %{
 11138     // Here we should emit illtrap !
 11140     __ stop("in ShoudNotReachHere");
 11142   %}
 11143   ins_pipe( pipe_jump );
 11144 %}
 11146 // Jump Direct Conditional - Label defines a relative address from Jcc+1
 11147 instruct  jmpLoopEnd(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
 11148   match(CountedLoopEnd cop (CmpI src1 src2));
 11149   effect(USE labl);
 11151   ins_cost(300);
 11152   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd" %}
 11153   ins_encode %{
 11154     Register op1 = $src1$$Register;
 11155     Register op2 = $src2$$Register;
 11156     Label     &L = *($labl$$label);
 11157     int     flag = $cop$$cmpcode;
 11159     switch(flag)
 11161       case 0x01: //equal
 11162 	if (&L)
 11163         	__ beq(op1, op2, L); 
 11164 	else 
 11165         	__ beq(op1, op2, (int)0); 
 11166         break;
 11167       case 0x02: //not_equal
 11168 	if (&L)
 11169         	__ bne(op1, op2, L); 
 11170 	else
 11171         	__ bne(op1, op2, (int)0); 
 11172         break;
 11173       case 0x03: //above
 11174         __ slt(AT, op2, op1);
 11175         if(&L)
 11176         	__ bne(AT, R0, L); 
 11177         else
 11178                 __ bne(AT, R0, (int)0);
 11179         break;
 11180       case 0x04: //above_equal
 11181         __ slt(AT, op1, op2);
 11182         if(&L)
 11183         	__ beq(AT, R0, L);
 11184         else
 11185                 __ beq(AT, R0, (int)0);
 11186         break;
 11187       case 0x05: //below
 11188         __ slt(AT, op1, op2);
 11189         if(&L)
 11190       		 __ bne(AT, R0, L); 
 11191         else
 11192         	 __ bne(AT, R0, (int)0);
 11193         break;
 11194       case 0x06: //below_equal
 11195         __ slt(AT, op2, op1);
 11196         if(&L)
 11197         	__ beq(AT, R0, L);
 11198         else
 11199         	__ beq(AT, R0, (int)0);
 11200        break;
 11201       default:
 11202           Unimplemented();
 11204     __ nop();
 11205   %}
 11206   ins_pipe( pipe_jump );
 11207   ins_pc_relative(1);
 11208 %}
 11211  instruct  jmpLoopEnd_reg_imm16_sub(cmpOp cop, mRegI src1, immI16_sub src2, label labl) %{
 11212   match(CountedLoopEnd cop (CmpI src1 src2));
 11213   effect(USE labl);
 11215   ins_cost(250);
 11216   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_imm16_sub" %}
 11217   ins_encode %{
 11218     Register op1 = $src1$$Register;
 11219     int      op2 = $src2$$constant;
 11220     Label     &L = *($labl$$label);
 11221     int     flag = $cop$$cmpcode;
 11223     __ addiu32(AT, op1, -1 * op2);
 11225     switch(flag)
 11227       case 0x01: //equal
 11228        if (&L)
 11229                __ beq(AT, R0, L); 
 11230        else 
 11231                __ beq(AT, R0, (int)0); 
 11232         break;
 11233       case 0x02: //not_equal
 11234        if (&L)
 11235                __ bne(AT, R0, L); 
 11236        else
 11237                __ bne(AT, R0, (int)0); 
 11238         break;
 11239       case 0x03: //above
 11240         if(&L)
 11241                __ bgtz(AT, L); 
 11242         else
 11243                 __ bgtz(AT, (int)0);
 11244         break;
 11245       case 0x04: //above_equal
 11246         if(&L)
 11247                __ bgez(AT, L);
 11248         else
 11249                 __ bgez(AT,(int)0);
 11250         break;
 11251       case 0x05: //below
 11252         if(&L)
 11253                 __ bltz(AT, L); 
 11254         else
 11255                 __ bltz(AT, (int)0);
 11256         break;
 11257       case 0x06: //below_equal
 11258         if(&L)
 11259                __ blez(AT, L);
 11260         else
 11261                __ blez(AT, (int)0);
 11262        break;
 11263       default:
 11264           Unimplemented();
 11266     __ nop();
 11267   %}
 11268   ins_pipe( pipe_jump );
 11269   ins_pc_relative(1);
 11270 %}
 11273 /*  
 11274 // Jump Direct Conditional - Label defines a relative address from Jcc+1
 11275 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
 11276   match(CountedLoopEnd cop cmp);
 11277   effect(USE labl);
 11279   ins_cost(300);
 11280   format %{ "J$cop,u  $labl\t# Loop end" %}
 11281   size(6);
 11282   opcode(0x0F, 0x80);
 11283   ins_encode( Jcc( cop, labl) );
 11284   ins_pipe( pipe_jump );
 11285   ins_pc_relative(1);
 11286 %}
 11288 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
 11289   match(CountedLoopEnd cop cmp);
 11290   effect(USE labl);
 11292   ins_cost(200);
 11293   format %{ "J$cop,u  $labl\t# Loop end" %}
 11294   opcode(0x0F, 0x80);
 11295   ins_encode( Jcc( cop, labl) );
 11296   ins_pipe( pipe_jump );
 11297   ins_pc_relative(1);
 11298 %}
 11299 */
 11301 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
 11302 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{
 11303   match(If cop cr);
 11304   effect(USE labl);
 11306   ins_cost(300);
 11307   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags" %}
 11309   ins_encode %{
 11310     Label    &L =  *($labl$$label);
 11311     switch($cop$$cmpcode)
 11313       case 0x01: //equal
 11314 	if (&L)
 11315         	__ bne(AT, R0, L); 
 11316 	else 
 11317         	__ bne(AT, R0, (int)0); 
 11318         break;
 11319       case 0x02: //not equal
 11320 	if (&L)
 11321         	__ beq(AT, R0, L); 
 11322 	else 
 11323         	__ beq(AT, R0, (int)0); 
 11324         break;
 11325       default:
 11326          Unimplemented(); 
 11328     __ nop();
 11329   %}
 11331   ins_pipe( pipe_jump );
 11332   ins_pc_relative(1);
 11333 %}
 11336 // ============================================================================
 11337 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 11338 // array for an instance of the superklass.  Set a hidden internal cache on a
 11339 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 11340 // NZ for a miss or zero for a hit.  The encoding ALSO sets flags.
 11341 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
 11342   match(Set result (PartialSubtypeCheck sub super));
 11343   effect(KILL tmp);
 11344   ins_cost(1100);  // slightly larger than the next version
 11345   format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
 11347   ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
 11348   ins_pipe( pipe_slow );
 11349 %}
 11352 // Conditional-store of an int value.
 11353 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
 11354 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
 11355   match(Set cr (StoreIConditional mem (Binary oldval newval)));
 11356 //  effect(KILL oldval);
 11357   format %{ "CMPXCHG  $newval, $mem, $oldval \t# @storeIConditional" %}
 11359   ins_encode %{
 11360     Register oldval = $oldval$$Register;
 11361     Register newval = $newval$$Register;
 11362     Address  addr(as_Register($mem$$base), $mem$$disp);
 11363     Label    again, failure;
 11365 //    int      base = $mem$$base;
 11366     int     index = $mem$$index;
 11367     int     scale = $mem$$scale;
 11368     int      disp = $mem$$disp;
 11370     guarantee(Assembler::is_simm16(disp), ""); 
 11372     if( index != 0 ) {
 11373        __ stop("in storeIConditional: index != 0");
 11374     } else {
 11375        __ bind(again);
 11376        if(!Use3A2000) __ sync();
 11377        __ ll(AT, addr);
 11378        __ bne(AT, oldval, failure);
 11379        __ delayed()->addu(AT, R0, R0);
 11381        __ addu(AT, newval, R0);
 11382        __ sc(AT, addr);
 11383        __ beq(AT, R0, again);
 11384        __ delayed()->addiu(AT, R0, 0xFF);
 11385        __ bind(failure);
 11386        __ sync();
 11388 %}
 11390   ins_pipe( long_memory_op );
 11391 %}
 11393 // Conditional-store of a long value.
 11394 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
 11395 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
 11396 %{
 11397   match(Set cr (StoreLConditional mem (Binary oldval newval)));
 11398   effect(KILL oldval);
 11400   format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
 11401   ins_encode%{
 11402 		Register oldval = $oldval$$Register;
 11403 		Register newval = $newval$$Register;
 11404 		Address addr((Register)$mem$$base, $mem$$disp);  
 11406 		int     index = $mem$$index;
 11407 		int     scale = $mem$$scale;
 11408 		int      disp = $mem$$disp;
 11410 		guarantee(Assembler::is_simm16(disp), ""); 
 11412 		if( index != 0 ) {
 11413 			__ stop("in storeIConditional: index != 0");
 11414 		} else {
 11415 			__ cmpxchg(newval, addr, oldval);
 11417   %}
 11418   ins_pipe( long_memory_op );
 11419 %}
 11422 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
 11423   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
 11424   effect(KILL oldval);
 11425 //  match(CompareAndSwapI mem_ptr (Binary oldval newval));
 11426   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
 11427             "MOV    $res, 1 @ compareAndSwapI\n\t"
 11428             "BNE    AT, R0 @ compareAndSwapI\n\t"
 11429             "MOV    $res, 0 @ compareAndSwapI\n"
 11430           "L:" %}
 11431   ins_encode %{
 11432     Register newval = $newval$$Register;
 11433     Register oldval = $oldval$$Register;
 11434     Register res    = $res$$Register;
 11435     Address  addr($mem_ptr$$Register, 0);    
 11436     Label L;
 11438     __ cmpxchg32(newval, addr, oldval);
 11439     __ move(res, AT);
 11440   %}
 11441   ins_pipe( long_memory_op );
 11442 %}
 11444 //FIXME:
 11445 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
 11446   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
 11447   effect(KILL oldval);
 11448   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
 11449             "MOV    $res, AT @ compareAndSwapP\n\t"
 11450           "L:" %}
 11451   ins_encode %{
 11452     Register newval = $newval$$Register;
 11453     Register oldval = $oldval$$Register;
 11454     Register res    = $res$$Register;
 11455     Address  addr($mem_ptr$$Register, 0);    
 11456     Label L;
 11458     __ cmpxchg(newval, addr, oldval);
 11459     __ move(res, AT);
 11460   %}
 11461   ins_pipe( long_memory_op );
 11462 %}
 11464 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
 11465   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
 11466   effect(KILL oldval);
 11467   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
 11468             "MOV    $res, AT @ compareAndSwapN\n\t"
 11469           "L:" %}
 11470   ins_encode %{
 11471     Register newval = $newval$$Register;
 11472     Register oldval = $oldval$$Register;
 11473     Register res    = $res$$Register;
 11474     Address  addr($mem_ptr$$Register, 0);    
 11475     Label L;
 11477     /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
 11478      *      Thus, we should extend oldval's sign for correct comparision.
 11479      */
 11480     __ sll(oldval, oldval, 0);
 11482     __ cmpxchg32(newval, addr, oldval);
 11483     __ move(res, AT);
 11484   %}
 11485   ins_pipe( long_memory_op );
 11486 %}
 11488 //----------Max and Min--------------------------------------------------------
 11489 // Min Instructions
 11490 ////
 11491 //   *** Min and Max using the conditional move are slower than the
 11492 //   *** branch version on a Pentium III.
 11493 // // Conditional move for min
 11494 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 11495 //  effect( USE_DEF op2, USE op1, USE cr );
 11496 //  format %{ "CMOVlt $op2,$op1\t! min" %}
 11497 //  opcode(0x4C,0x0F);
 11498 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 11499 //  ins_pipe( pipe_cmov_reg );
 11500 //%}
 11501 //
 11502 //// Min Register with Register (P6 version)
 11503 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
 11504 //  predicate(VM_Version::supports_cmov() );
 11505 //  match(Set op2 (MinI op1 op2));
 11506 //  ins_cost(200);
 11507 //  expand %{
 11508 //    eFlagsReg cr;
 11509 //    compI_eReg(cr,op1,op2);
 11510 //    cmovI_reg_lt(op2,op1,cr);
 11511 //  %}
 11512 //%}
 11514 // Min Register with Register (generic version)
 11515 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
 11516   match(Set dst (MinI dst src));
 11517   //effect(KILL flags);
 11518   ins_cost(80);
 11520   format %{ "MIN    $dst, $src @minI_Reg_Reg" %}
 11521   ins_encode %{
 11522     Register dst   = $dst$$Register;
 11523     Register src   = $src$$Register;
 11525     __ slt(AT, src, dst);
 11526     __ movn(dst, src, AT);
 11528   %}
 11530   ins_pipe( pipe_slow );
 11531 %}
 11533 // Max Register with Register
 11534 //   *** Min and Max using the conditional move are slower than the
 11535 //   *** branch version on a Pentium III.
 11536 // // Conditional move for max
 11537 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 11538 //  effect( USE_DEF op2, USE op1, USE cr );
 11539 //  format %{ "CMOVgt $op2,$op1\t! max" %}
 11540 //  opcode(0x4F,0x0F);
 11541 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 11542 //  ins_pipe( pipe_cmov_reg );
 11543 //%}
 11544 //
 11545 // // Max Register with Register (P6 version)
 11546 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
 11547 //  predicate(VM_Version::supports_cmov() );
 11548 //  match(Set op2 (MaxI op1 op2));
 11549 //  ins_cost(200);
 11550 //  expand %{
 11551 //    eFlagsReg cr;
 11552 //    compI_eReg(cr,op1,op2);
 11553 //    cmovI_reg_gt(op2,op1,cr);
 11554 //  %}
 11555 //%}
 11557 // Max Register with Register (generic version)
 11558 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
 11559   match(Set dst (MaxI dst src));
 11560   ins_cost(80);
 11562   format %{ "MAX    $dst, $src @maxI_Reg_Reg" %}
 11564   ins_encode %{
 11565     Register dst   = $dst$$Register;
 11566     Register src   = $src$$Register;
 11568     __ slt(AT, dst, src);
 11569     __ movn(dst, src, AT);
 11571   %}
 11573   ins_pipe( pipe_slow );
 11574 %}
 11576 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
 11577   match(Set dst (MaxI dst zero));
 11578   ins_cost(50);
 11580   format %{ "MAX    $dst, 0 @maxI_Reg_zero" %}
 11582   ins_encode %{
 11583     Register dst   = $dst$$Register;
 11585     __ slt(AT, dst, R0);
 11586     __ movn(dst, R0, AT);
 11588   %}
 11590   ins_pipe( pipe_slow );
 11591 %}
 11593 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
 11594 %{
 11595   match(Set dst (AndL src mask));
 11597   format %{ "movl    $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
 11598   ins_encode %{
 11599     Register dst = $dst$$Register;
 11600     Register src = $src$$Register;
 11602     __ dext(dst, src, 0, 32);
 11603   %}
 11604   ins_pipe(ialu_regI_regI);
 11605 %}
 11607 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
 11608 %{
 11609   match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
 11611   format %{ "combine_i2l    $dst, $src2(H), $src1(L) @ combine_i2l" %}
 11612   ins_encode %{
 11613     Register dst  = $dst$$Register;
 11614     Register src1 = $src1$$Register;
 11615     Register src2 = $src2$$Register;
 11617     if (src1 == dst) {
 11618        __ dinsu(dst, src2, 32, 32);
 11619     } else if (src2 == dst) {
 11620        __ dsll32(dst, dst, 0); 
 11621        __ dins(dst, src1, 0, 32);
 11622     } else {
 11623        __ dext(dst, src1, 0, 32);
 11624        __ dinsu(dst, src2, 32, 32);
 11626   %}
 11627   ins_pipe(ialu_regI_regI);
 11628 %}
 11630 // Zero-extend convert int to long
 11631 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
 11632 %{
 11633   match(Set dst (AndL (ConvI2L src) mask));
 11635   format %{ "movl    $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
 11636   ins_encode %{
 11637     Register dst = $dst$$Register;
 11638     Register src = $src$$Register;
 11640     __ dext(dst, src, 0, 32);
 11641   %}
 11642   ins_pipe(ialu_regI_regI);
 11643 %}
 11645 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
 11646 %{
 11647   match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
 11649   format %{ "movl    $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
 11650   ins_encode %{
 11651     Register dst = $dst$$Register;
 11652     Register src = $src$$Register;
 11654     __ dext(dst, src, 0, 32);
 11655   %}
 11656   ins_pipe(ialu_regI_regI);
 11657 %}
 11659 // Match loading integer and casting it to unsigned int in long register.
 11660 // LoadI + ConvI2L + AndL 0xffffffff.
 11661 instruct loadUI2L_rmask(mRegL dst, umemory mem, immL_32bits mask) %{
 11662   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 11664   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
 11665   ins_encode (load_N_enc(dst, mem));
 11666   ins_pipe(ialu_loadI);
 11667 %}
 11669 instruct loadUI2L_lmask(mRegL dst, umemory mem, immL_32bits mask) %{
 11670   match(Set dst (AndL mask (ConvI2L (LoadI mem))));
 11672   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
 11673   ins_encode (load_N_enc(dst, mem));
 11674   ins_pipe(ialu_loadI);
 11675 %}
 11678 // ============================================================================
 11679 // Safepoint Instruction
 11680 instruct safePoint_poll_reg(mRegP poll) %{
 11681   match(SafePoint poll);
 11682   predicate(false);
 11683   effect(USE poll);
 11685   ins_cost(125);
 11686   format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
 11688   ins_encode %{
 11689     Register poll_reg = $poll$$Register;
 11691     __ block_comment("Safepoint:");
 11692     __ relocate(relocInfo::poll_type);
 11693     __ lw(AT, poll_reg, 0);
 11694   %}
 11696   ins_pipe( ialu_storeI );
 11697 %}
 11699 instruct safePoint_poll() %{
 11700   match(SafePoint);
 11702   ins_cost(105);
 11703   format %{ "poll for GC @ safePoint_poll" %}
 11705   ins_encode %{
 11706     __ block_comment("Safepoint:");
 11707     __ set64(T9, (long)os::get_polling_page());
 11708     __ relocate(relocInfo::poll_type);
 11709     __ lw(AT, T9, 0);
 11710   %}
 11712   ins_pipe( ialu_storeI );
 11713 %}
 11715 //----------Arithmetic Conversion Instructions---------------------------------
 11717 instruct roundFloat_nop(regF dst)
 11718 %{
 11719   match(Set dst (RoundFloat dst));
 11721   ins_cost(0);
 11722   ins_encode();
 11723   ins_pipe(empty);
 11724 %}
 11726 instruct roundDouble_nop(regD dst)
 11727 %{
 11728   match(Set dst (RoundDouble dst));
 11730   ins_cost(0);
 11731   ins_encode();
 11732   ins_pipe(empty);
 11733 %}
 11735 //---------- Zeros Count Instructions ------------------------------------------
 11736 // CountLeadingZerosINode CountTrailingZerosINode 
 11737 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
 11738   predicate(UseCountLeadingZerosInstruction);
 11739   match(Set dst (CountLeadingZerosI src));
 11741   format %{ "clz  $dst, $src\t# count leading zeros (int)" %}
 11742   ins_encode %{
 11743     __ clz($dst$$Register, $src$$Register);
 11744   %}
 11745   ins_pipe( ialu_regL_regL );
 11746 %}
 11748 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
 11749   predicate(UseCountLeadingZerosInstruction);
 11750   match(Set dst (CountLeadingZerosL src));
 11752   format %{ "dclz  $dst, $src\t# count leading zeros (long)" %}
 11753   ins_encode %{
 11754     __ dclz($dst$$Register, $src$$Register);
 11755   %}
 11756   ins_pipe( ialu_regL_regL );
 11757 %}
 11759 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
 11760   predicate(UseCountTrailingZerosInstruction);
 11761   match(Set dst (CountTrailingZerosI src));
 11763   format %{ "ctz    $dst, $src\t# count trailing zeros (int)" %}
 11764   ins_encode %{
 11765     // ctz and dctz is gs instructions.
 11766     __ ctz($dst$$Register, $src$$Register);
 11767   %}
 11768   ins_pipe( ialu_regL_regL );
 11769 %}
 11771 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
 11772   predicate(UseCountTrailingZerosInstruction);
 11773   match(Set dst (CountTrailingZerosL src));
 11775   format %{ "dcto    $dst, $src\t# count trailing zeros (long)" %}
 11776   ins_encode %{
 11777     __ dctz($dst$$Register, $src$$Register);
 11778   %}
 11779   ins_pipe( ialu_regL_regL );
 11780 %}
 11782 // ====================VECTOR INSTRUCTIONS=====================================
 11784 // Load vectors (8 bytes long)
 11785 instruct loadV8(vecD dst, memory mem) %{
 11786   predicate(n->as_LoadVector()->memory_size() == 8);
 11787   match(Set dst (LoadVector mem));
 11788   ins_cost(125);
 11789   format %{ "load    $dst, $mem\t! load vector (8 bytes)" %}
 11790   ins_encode(load_D_enc(dst, mem));
 11791   ins_pipe( fpu_loadF );
 11792 %}
 11794 // Store vectors (8 bytes long)
 11795 instruct storeV8(memory mem, vecD src) %{
 11796   predicate(n->as_StoreVector()->memory_size() == 8);
 11797   match(Set mem (StoreVector mem src));
 11798   ins_cost(145);
 11799   format %{ "store    $mem, $src\t! store vector (8 bytes)" %}
 11800   ins_encode(store_D_reg_enc(mem, src));
 11801   ins_pipe( fpu_storeF );
 11802 %}
 11804 instruct Repl8B_DSP(vecD dst, mRegI src) %{
 11805   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 11806   match(Set dst (ReplicateB src));
 11807   ins_cost(100);
 11808   format %{ "replv_ob    AT, $src\n\t"
 11809             "dmtc1 AT, $dst\t! replicate8B" %}
 11810   ins_encode %{
 11811     __ replv_ob(AT, $src$$Register);
 11812     __ dmtc1(AT, $dst$$FloatRegister);
 11813   %}
 11814   ins_pipe( pipe_mtc1 );
 11815 %}
 11817 instruct Repl8B(vecD dst, mRegI src) %{
 11818   predicate(n->as_Vector()->length() == 8);
 11819   match(Set dst (ReplicateB src));
 11820   ins_cost(140);
 11821   format %{ "move       AT,  $src\n\t"
 11822             "dins  AT, AT,  8,  8\n\t"
 11823             "dins  AT, AT, 16, 16\n\t"
 11824             "dinsu AT, AT, 32, 32\n\t"
 11825             "dmtc1 AT, $dst\t! replicate8B" %}
 11826   ins_encode %{
 11827     __ move(AT, $src$$Register);
 11828     __ dins(AT, AT, 8, 8);
 11829     __ dins(AT, AT, 16, 16);
 11830     __ dinsu(AT, AT, 32, 32);
 11831     __ dmtc1(AT, $dst$$FloatRegister);
 11832   %}
 11833   ins_pipe( pipe_mtc1 );
 11834 %}
 11836 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
 11837   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 11838   match(Set dst (ReplicateB con));
 11839   ins_cost(110);
 11840   format %{ "repl_ob    AT, [$con]\n\t"
 11841             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 11842   ins_encode %{
 11843     int      val = $con$$constant;
 11844     __ repl_ob(AT, val);
 11845     __ dmtc1(AT, $dst$$FloatRegister);
 11846   %}
 11847   ins_pipe( pipe_mtc1 );
 11848 %}
 11850 instruct Repl8B_imm(vecD dst, immI con) %{
 11851   predicate(n->as_Vector()->length() == 8);
 11852   match(Set dst (ReplicateB con));
 11853   ins_cost(150);
 11854   format %{ "move      AT, [$con]\n\t"
 11855             "dins  AT, AT,  8,  8\n\t"
 11856             "dins  AT, AT, 16, 16\n\t"
 11857             "dinsu AT, AT, 32, 32\n\t"
 11858             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 11859   ins_encode %{
 11860     __ move(AT, $con$$constant);
 11861     __ dins(AT, AT, 8, 8);
 11862     __ dins(AT, AT, 16, 16);
 11863     __ dinsu(AT, AT, 32, 32);
 11864     __ dmtc1(AT, $dst$$FloatRegister);
 11865   %}
 11866   ins_pipe( pipe_mtc1 );
 11867 %}
 11869 instruct Repl8B_zero(vecD dst, immI0 zero) %{
 11870   predicate(n->as_Vector()->length() == 8);
 11871   match(Set dst (ReplicateB zero));
 11872   ins_cost(90);
 11873   format %{ "dmtc1    R0, $dst\t! replicate8B zero" %}
 11874   ins_encode %{
 11875     __ dmtc1(R0, $dst$$FloatRegister);
 11876   %}
 11877   ins_pipe( pipe_mtc1 );
 11878 %}
 11880 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
 11881   predicate(n->as_Vector()->length() == 8);
 11882   match(Set dst (ReplicateB M1));
 11883   ins_cost(80);
 11884   format %{ "dmtc1    -1, $dst\t! replicate8B -1" %}
 11885   ins_encode %{
 11886     __ nor(AT, R0, R0);
 11887     __ dmtc1(AT, $dst$$FloatRegister);
 11888   %}
 11889   ins_pipe( pipe_mtc1 );
 11890 %}
 11892 instruct Repl4S_DSP(vecD dst, mRegI src) %{
 11893   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 11894   match(Set dst (ReplicateS src));
 11895   ins_cost(100);
 11896   format %{ "replv_qh    AT, $src\n\t"
 11897             "dmtc1 AT, $dst\t! replicate4S" %}
 11898   ins_encode %{
 11899     __ replv_qh(AT, $src$$Register);
 11900     __ dmtc1(AT, $dst$$FloatRegister);
 11901   %}
 11902   ins_pipe( pipe_mtc1 );
 11903 %}
 11905 instruct Repl4S(vecD dst, mRegI src) %{
 11906   predicate(n->as_Vector()->length() == 4);
 11907   match(Set dst (ReplicateS src));
 11908   ins_cost(120);
 11909   format %{ "move    AT,     $src  \n\t"
 11910             "dins    AT, AT, 16, 16\n\t"
 11911             "dinsu   AT, AT, 32, 32\n\t"
 11912             "dmtc1 AT, $dst\t! replicate4S" %}
 11913   ins_encode %{
 11914     __ move(AT, $src$$Register);
 11915     __ dins(AT, AT, 16, 16);
 11916     __ dinsu(AT, AT, 32, 32);
 11917     __ dmtc1(AT, $dst$$FloatRegister);
 11918   %}
 11919   ins_pipe( pipe_mtc1 );
 11920 %}
 11922 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
 11923   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 11924   match(Set dst (ReplicateS con));
 11925   ins_cost(100);
 11926   format %{ "replv_qh    AT, [$con]\n\t"
 11927             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 11928   ins_encode %{
 11929     int      val = $con$$constant;
 11930     if ( Assembler::is_simm(val, 10)) {
 11931       //repl_qh supports 10 bits immediate
 11932       __ repl_qh(AT, val);
 11933     } else {
 11934       __ li32(AT, val);
 11935       __ replv_qh(AT, AT);
 11937     __ dmtc1(AT, $dst$$FloatRegister);
 11938   %}
 11939   ins_pipe( pipe_mtc1 );
 11940 %}
 11942 instruct Repl4S_imm(vecD dst, immI con) %{
 11943   predicate(n->as_Vector()->length() == 4);
 11944   match(Set dst (ReplicateS con));
 11945   ins_cost(110);
 11946   format %{ "move    AT,   [$con]\n\t"
 11947             "dins  AT, AT, 16, 16\n\t"
 11948             "dinsu AT, AT, 32, 32\n\t"
 11949             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 11950   ins_encode %{
 11951     __ move(AT, $con$$constant);
 11952     __ dins(AT, AT, 16, 16);
 11953     __ dinsu(AT, AT, 32, 32);
 11954     __ dmtc1(AT, $dst$$FloatRegister);
 11955   %}
 11956   ins_pipe( pipe_mtc1 );
 11957 %}
 11959 instruct Repl4S_zero(vecD dst, immI0 zero) %{
 11960   predicate(n->as_Vector()->length() == 4);
 11961   match(Set dst (ReplicateS zero));
 11962   format %{ "dmtc1    R0, $dst\t! replicate4S zero" %}
 11963   ins_encode %{
 11964     __ dmtc1(R0, $dst$$FloatRegister);
 11965   %}
 11966   ins_pipe( pipe_mtc1 );
 11967 %}
 11969 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
 11970   predicate(n->as_Vector()->length() == 4);
 11971   match(Set dst (ReplicateS M1));
 11972   format %{ "dmtc1    -1, $dst\t! replicate4S -1" %}
 11973   ins_encode %{
 11974     __ nor(AT, R0, R0);
 11975     __ dmtc1(AT, $dst$$FloatRegister);
 11976   %}
 11977   ins_pipe( pipe_mtc1 );
 11978 %}
 11980 // Replicate integer (4 byte) scalar to be vector
 11981 instruct Repl2I(vecD dst, mRegI src) %{
 11982   predicate(n->as_Vector()->length() == 2);
 11983   match(Set dst (ReplicateI src));
 11984   format %{ "dins    AT, $src, 0, 32\n\t"
 11985             "dinsu   AT, $src, 32, 32\n\t"
 11986             "dmtc1   AT, $dst\t! replicate2I" %}
 11987   ins_encode %{
 11988     __ dins(AT, $src$$Register, 0, 32);
 11989     __ dinsu(AT, $src$$Register, 32, 32);
 11990     __ dmtc1(AT, $dst$$FloatRegister);
 11991   %}
 11992   ins_pipe( pipe_mtc1 );
 11993 %}
 11995 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
 11996 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
 11997   predicate(n->as_Vector()->length() == 2);
 11998   match(Set dst (ReplicateI con));
 11999   effect(KILL tmp);
 12000   format %{ "li32    AT, [$con], 32\n\t"
 12001             "dinsu   AT,         AT\n\t"
 12002             "dmtc1   AT, $dst\t! replicate2I($con)" %}
 12003   ins_encode %{
 12004     int      val = $con$$constant;
 12005     __ li32(AT, val);
 12006     __ dinsu(AT, AT, 32, 32);
 12007     __ dmtc1(AT, $dst$$FloatRegister);
 12008   %}
 12009   ins_pipe( pipe_mtc1 );
 12010 %}
 12012 // Replicate integer (4 byte) scalar zero to be vector
 12013 instruct Repl2I_zero(vecD dst, immI0 zero) %{
 12014   predicate(n->as_Vector()->length() == 2);
 12015   match(Set dst (ReplicateI zero));
 12016   format %{ "dmtc1    R0, $dst\t! replicate2I zero" %}
 12017   ins_encode %{
 12018     __ dmtc1(R0, $dst$$FloatRegister);
 12019   %}
 12020   ins_pipe( pipe_mtc1 );
 12021 %}
 12023 // Replicate integer (4 byte) scalar -1 to be vector
 12024 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
 12025   predicate(n->as_Vector()->length() == 2);
 12026   match(Set dst (ReplicateI M1));
 12027   format %{ "dmtc1    -1, $dst\t! replicate2I -1, use AT" %}
 12028   ins_encode %{
 12029     __ nor(AT, R0, R0);
 12030     __ dmtc1(AT, $dst$$FloatRegister);
 12031   %}
 12032   ins_pipe( pipe_mtc1 );
 12033 %}
 12035 // Replicate float (4 byte) scalar to be vector
 12036 instruct Repl2F(vecD dst, regF src) %{
 12037   predicate(n->as_Vector()->length() == 2);
 12038   match(Set dst (ReplicateF src));
 12039   format %{ "cvt.ps  $dst, $src, $src\t! replicate2F" %}
 12040   ins_encode %{
 12041     __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
 12042   %}
 12043   ins_pipe( pipe_slow );
 12044 %}
 12046 // Replicate float (4 byte) scalar zero to be vector
 12047 instruct Repl2F_zero(vecD dst, immF0 zero) %{
 12048   predicate(n->as_Vector()->length() == 2);
 12049   match(Set dst (ReplicateF zero));
 12050   format %{ "dmtc1   R0, $dst\t! replicate2F zero" %}
 12051   ins_encode %{
 12052     __ dmtc1(R0, $dst$$FloatRegister);
 12053   %}
 12054   ins_pipe( pipe_mtc1 );
 12055 %}
 12058 // ====================VECTOR ARITHMETIC=======================================
 12060 // --------------------------------- ADD --------------------------------------
 12062 // Floats vector add
 12063 instruct vadd2F(vecD dst, vecD src) %{
 12064   predicate(n->as_Vector()->length() == 2);
 12065   match(Set dst (AddVF dst src));
 12066   format %{ "add.ps   $dst,$src\t! add packed2F" %}
 12067   ins_encode %{
 12068     __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 12069   %}
 12070   ins_pipe( pipe_slow );
 12071 %}
 12073 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
 12074   predicate(n->as_Vector()->length() == 2);
 12075   match(Set dst (AddVF src1 src2));
 12076   format %{ "add.ps   $dst,$src1,$src2\t! add packed2F" %}
 12077   ins_encode %{
 12078     __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 12079   %}
 12080   ins_pipe( fpu_regF_regF );
 12081 %}
 12083 // --------------------------------- SUB --------------------------------------
 12085 // Floats vector sub
 12086 instruct vsub2F(vecD dst, vecD src) %{
 12087   predicate(n->as_Vector()->length() == 2);
 12088   match(Set dst (SubVF dst src));
 12089   format %{ "sub.ps   $dst,$src\t! sub packed2F" %}
 12090   ins_encode %{
 12091     __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 12092   %}
 12093   ins_pipe( fpu_regF_regF );
 12094 %}
 12096 // --------------------------------- MUL --------------------------------------
 12098 // Floats vector mul
 12099 instruct vmul2F(vecD dst, vecD src) %{
 12100   predicate(n->as_Vector()->length() == 2);
 12101   match(Set dst (MulVF dst src));
 12102   format %{ "mul.ps   $dst, $src\t! mul packed2F" %}
 12103   ins_encode %{
 12104     __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 12105   %}
 12106   ins_pipe( fpu_regF_regF );
 12107 %}
 12109 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
 12110   predicate(n->as_Vector()->length() == 2);
 12111   match(Set dst (MulVF src1 src2));
 12112   format %{ "mul.ps   $dst, $src1, $src2\t! mul packed2F" %}
 12113   ins_encode %{
 12114     __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 12115   %}
 12116   ins_pipe( fpu_regF_regF );
 12117 %}
 12119 // --------------------------------- DIV --------------------------------------
 12120 // MIPS do not have div.ps
 12123 //----------PEEPHOLE RULES-----------------------------------------------------
 12124 // These must follow all instruction definitions as they use the names
 12125 // defined in the instructions definitions.
 12126 // 
 12127 // peepmatch ( root_instr_name [preceeding_instruction]* );
 12128 //
 12129 // peepconstraint %{
 12130 // (instruction_number.operand_name relational_op instruction_number.operand_name
 12131 //  [, ...] );
 12132 // // instruction numbers are zero-based using left to right order in peepmatch
 12133 //
 12134 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
 12135 // // provide an instruction_number.operand_name for each operand that appears
 12136 // // in the replacement instruction's match rule
 12137 //
 12138 // ---------VM FLAGS---------------------------------------------------------
 12139 // 
 12140 // All peephole optimizations can be turned off using -XX:-OptoPeephole
 12141 // 
 12142 // Each peephole rule is given an identifying number starting with zero and
 12143 // increasing by one in the order seen by the parser.  An individual peephole
 12144 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
 12145 // on the command-line.
 12146 // 
 12147 // ---------CURRENT LIMITATIONS----------------------------------------------
 12148 // 
 12149 // Only match adjacent instructions in same basic block
 12150 // Only equality constraints
 12151 // Only constraints between operands, not (0.dest_reg == EAX_enc)
 12152 // Only one replacement instruction
 12153 //
 12154 // ---------EXAMPLE----------------------------------------------------------
 12155 //
 12156 // // pertinent parts of existing instructions in architecture description
 12157 // instruct movI(eRegI dst, eRegI src) %{
 12158 //   match(Set dst (CopyI src));
 12159 // %}
 12160 // 
 12161 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
 12162 //   match(Set dst (AddI dst src));
 12163 //   effect(KILL cr);
 12164 // %}
 12165 // 
 12166 // // Change (inc mov) to lea
 12167 // peephole %{
 12168 //   // increment preceeded by register-register move
 12169 //   peepmatch ( incI_eReg movI );
 12170 //   // require that the destination register of the increment 
 12171 //   // match the destination register of the move
 12172 //   peepconstraint ( 0.dst == 1.dst );
 12173 //   // construct a replacement instruction that sets
 12174 //   // the destination to ( move's source register + one )
 12175 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 12176 // %}
 12177 // 
 12178 // Implementation no longer uses movX instructions since 
 12179 // machine-independent system no longer uses CopyX nodes.
 12180 // 
 12181 // peephole %{
 12182 //   peepmatch ( incI_eReg movI );
 12183 //   peepconstraint ( 0.dst == 1.dst );
 12184 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 12185 // %}
 12186 // 
 12187 // peephole %{
 12188 //   peepmatch ( decI_eReg movI );
 12189 //   peepconstraint ( 0.dst == 1.dst );
 12190 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 12191 // %}
 12192 // 
 12193 // peephole %{
 12194 //   peepmatch ( addI_eReg_imm movI );
 12195 //   peepconstraint ( 0.dst == 1.dst );
 12196 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 12197 // %}
 12198 // 
 12199 // peephole %{
 12200 //   peepmatch ( addP_eReg_imm movP );
 12201 //   peepconstraint ( 0.dst == 1.dst );
 12202 //   peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
 12203 // %}
 12205 // // Change load of spilled value to only a spill
 12206 // instruct storeI(memory mem, eRegI src) %{
 12207 //   match(Set mem (StoreI mem src));
 12208 // %}
 12209 // 
 12210 // instruct loadI(eRegI dst, memory mem) %{
 12211 //   match(Set dst (LoadI mem));
 12212 // %}
 12213 // 
 12214 //peephole %{
 12215 //  peepmatch ( loadI storeI );
 12216 //  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
 12217 //  peepreplace ( storeI( 1.mem 1.mem 1.src ) );
 12218 //%}
 12220 //----------SMARTSPILL RULES---------------------------------------------------
 12221 // These must follow all instruction definitions as they use the names
 12222 // defined in the instructions definitions.

mercurial