src/cpu/mips/vm/mips_64.ad

Thu, 13 Sep 2018 15:03:14 +0800

author
fujie
date
Thu, 13 Sep 2018 15:03:14 +0800
changeset 9244
914de2d5d730
parent 9234
a1cf6cdffc83
child 9260
ba3aac24b68d
permissions
-rw-r--r--

#7558 [C2] cmovL_cmpP_reg_reg was added im mips_64.ad

Effect:
java -XX:-UseCompressedOops SpecApplication _213_javac # passed

     1 //
     2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     3 // Copyright (c) 2015, 2018, 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 // F31 are not used as temporary registers in D2I
   384 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);
   385 reg_class dbl_reg( F0, F0_H,
   386                    F1, F1_H,
   387                    F2, F2_H,
   388                    F3, F3_H,
   389                    F4, F4_H,
   390                    F5, F5_H,
   391                    F6, F6_H,
   392                    F7, F7_H,
   393                    F8, F8_H,
   394                    F9, F9_H,
   395                    F10, F10_H,
   396                    F11, F11_H,
   397                    F12, F12_H,
   398                    F13, F13_H,
   399                    F14, F14_H,
   400                    F15, F15_H,
   401                    F16, F16_H,
   402                    F17, F17_H,
   403                    F18, F18_H,
   404                    F19, F19_H,
   405                    F20, F20_H,
   406                    F21, F21_H,
   407                    F22, F22_H,
   408                    F23, F23_H,
   409                    F24, F24_H,
   410                    F25, F25_H,
   411                    F26, F26_H,
   412                    F27, F27_H,
   413                    F28, F28_H,
   414                    F29, F29_H,
   415                    F31, F31_H);
   417 reg_class flt_arg0( F12 );
   418 reg_class dbl_arg0( F12, F12_H );
   419 reg_class dbl_arg1( F14, F14_H );
   421 %}
   423 //----------DEFINITION BLOCK---------------------------------------------------
   424 // Define name --> value mappings to inform the ADLC of an integer valued name
   425 // Current support includes integer values in the range [0, 0x7FFFFFFF]
   426 // Format:
   427 //        int_def  <name>         ( <int_value>, <expression>);
   428 // Generated Code in ad_<arch>.hpp
   429 //        #define  <name>   (<expression>)
   430 //        // value == <int_value>
   431 // Generated code in ad_<arch>.cpp adlc_verification()
   432 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
   433 //
   434 definitions %{
   435   int_def DEFAULT_COST      (    100,     100);
   436   int_def HUGE_COST         (1000000, 1000000);
   438   // Memory refs are twice as expensive as run-of-the-mill.
   439   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
   441   // Branches are even more expensive.
   442   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
   443   // we use jr instruction to construct call, so more expensive
   444   int_def CALL_COST         (    500, DEFAULT_COST * 5);
   445 /*
   446         int_def EQUAL             (   1, 1  );
   447         int_def NOT_EQUAL         (   2, 2  );
   448         int_def GREATER           (   3, 3  );
   449         int_def GREATER_EQUAL     (   4, 4  );
   450         int_def LESS              (   5, 5  );
   451         int_def LESS_EQUAL        (   6, 6  );
   452 */
   453 %}
   457 //----------SOURCE BLOCK-------------------------------------------------------
   458 // This is a block of C++ code which provides values, functions, and
   459 // definitions necessary in the rest of the architecture description
   461 source_hpp %{
   462 // Header information of the source block.
   463 // Method declarations/definitions which are used outside
   464 // the ad-scope can conveniently be defined here.
   465 //
   466 // To keep related declarations/definitions/uses close together,
   467 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
   469 class CallStubImpl {
   471   //--------------------------------------------------------------
   472   //---<  Used for optimization in Compile::shorten_branches  >---
   473   //--------------------------------------------------------------
   475  public:
   476   // Size of call trampoline stub.
   477   static uint size_call_trampoline() {
   478     return 0; // no call trampolines on this platform
   479   }
   481   // number of relocations needed by a call trampoline stub
   482   static uint reloc_call_trampoline() {
   483     return 0; // no call trampolines on this platform
   484   }
   485 };
   487 class HandlerImpl {
   489  public:
   491   static int emit_exception_handler(CodeBuffer &cbuf);
   492   static int emit_deopt_handler(CodeBuffer& cbuf);
   494   static uint size_exception_handler() {
   495     // NativeCall instruction size is the same as NativeJump.
   496     // exception handler starts out as jump and can be patched to
   497     // a call be deoptimization.  (4932387)
   498     // Note that this value is also credited (in output.cpp) to
   499     // the size of the code section.
   500     int size = NativeCall::instruction_size;
   501     return round_to(size, 16);
   502   }
   504 #ifdef _LP64
   505   static uint size_deopt_handler() {
   506     int size = NativeCall::instruction_size;
   507     return round_to(size, 16);
   508   }
   509 #else
   510   static uint size_deopt_handler() {
   511     // NativeCall instruction size is the same as NativeJump.
   512     // exception handler starts out as jump and can be patched to
   513     // a call be deoptimization.  (4932387)
   514     // Note that this value is also credited (in output.cpp) to
   515     // the size of the code section.
   516     return 5 + NativeJump::instruction_size; // pushl(); jmp;
   517   }
   518 #endif
   519 };
   521 %} // end source_hpp
   523 source %{
   525 #define   NO_INDEX    0
   526 #define   RELOC_IMM64    Assembler::imm_operand
   527 #define   RELOC_DISP32   Assembler::disp32_operand
   530 #define __ _masm.
   533 // Emit exception handler code.
   534 // Stuff framesize into a register and call a VM stub routine.
   535 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
   536   // Note that the code buffer's insts_mark is always relative to insts.
   537   // That's why we must use the macroassembler to generate a handler.
   538   MacroAssembler _masm(&cbuf);
   539   address base = __ start_a_stub(size_exception_handler());
   540   if (base == NULL) {
   541     ciEnv::current()->record_failure("CodeCache is full");
   542     return 0;  // CodeBuffer::expand failed
   543   }
   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 = __ start_a_stub(size_deopt_handler());
   564   if (base == NULL) {
   565     ciEnv::current()->record_failure("CodeCache is full");
   566     return 0;  // CodeBuffer::expand failed
   567   }
   569   int offset = __ offset();
   571   __ block_comment("; emit_deopt_handler");
   573   cbuf.set_insts_mark();
   574   __ relocate(relocInfo::runtime_call_type);
   575   __ patchable_call(SharedRuntime::deopt_blob()->unpack());
   576   __ align(16);
   577   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
   578   __ end_a_stub();
   579   return offset;
   580 }
   583 const bool Matcher::match_rule_supported(int opcode) {
   584   if (!has_match_rule(opcode))
   585     return false;
   587   switch (opcode) {
   588     //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
   589     case Op_CountLeadingZerosI:
   590     case Op_CountLeadingZerosL:
   591       if (!UseCountLeadingZerosInstructionMIPS64)
   592         return false;
   593       break;
   594     case Op_CountTrailingZerosI:
   595     case Op_CountTrailingZerosL:
   596       if (!UseCountTrailingZerosInstructionMIPS64)
   597         return false;
   598       break;
   599   }
   601   return true;  // Per default match rules are supported.
   602 }
   604 //FIXME
   605 // emit call stub, compiled java to interpreter
   606 void emit_java_to_interp(CodeBuffer &cbuf ) {
   607   // Stub is fixed up when the corresponding call is converted from calling
   608   // compiled code to calling interpreted code.
   609   // mov rbx,0
   610   // jmp -1
   612   address mark = cbuf.insts_mark();  // get mark within main instrs section
   614   // Note that the code buffer's insts_mark is always relative to insts.
   615   // That's why we must use the macroassembler to generate a stub.
   616   MacroAssembler _masm(&cbuf);
   618   address base = __ start_a_stub(Compile::MAX_stubs_size);
   619   if (base == NULL) { // CodeBuffer::expand failed
   620     ciEnv::current()->record_failure("CodeCache is full");
   621   }
   623   // static stub relocation stores the instruction address of the call
   625   __ relocate(static_stub_Relocation::spec(mark), 0);
   627   // static stub relocation also tags the methodOop in the code-stream.
   628   __ patchable_set48(S3, (long)0);
   629   // This is recognized as unresolved by relocs/nativeInst/ic code
   631   __ relocate(relocInfo::runtime_call_type);
   633   cbuf.set_insts_mark();
   634   address call_pc = (address)-1;
   635   __ patchable_jump(call_pc);
   636   __ align(16);
   637   __ end_a_stub();
   638   // Update current stubs pointer and restore code_end.
   639 }
   641 // size of call stub, compiled java to interpretor
   642 uint size_java_to_interp() {
   643   int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
   644   return round_to(size, 16);
   645 }
   647 // relocation entries for call stub, compiled java to interpreter
   648 uint reloc_java_to_interp() {
   649   return 16;  //  in emit_java_to_interp +  in Java_Static_Call
   650 }
   652 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
   653   int offs = offset - br_size + 4;
   654   // To be conservative on MIPS
   655   // branch node should be end with:
   656   //   branch inst
   657   //   delay slot
   658   const int safety_zone = 3 * BytesPerInstWord;
   659   return Assembler::is_simm16((offs<0 ? offs-safety_zone : offs+safety_zone) >> 2);
   660 }
   663 // No additional cost for CMOVL.
   664 const int Matcher::long_cmove_cost() { return 0; }
   666 // No CMOVF/CMOVD with SSE2
   667 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
   669 // Does the CPU require late expand (see block.cpp for description of late expand)?
   670 const bool Matcher::require_postalloc_expand = false;
   672 // Should the Matcher clone shifts on addressing modes, expecting them
   673 // to be subsumed into complex addressing expressions or compute them
   674 // into registers?  True for Intel but false for most RISCs
   675 const bool Matcher::clone_shift_expressions = false;
   677 // Do we need to mask the count passed to shift instructions or does
   678 // the cpu only look at the lower 5/6 bits anyway?
   679 const bool Matcher::need_masked_shift_count = false;
   681 bool Matcher::narrow_oop_use_complex_address() {
   682   NOT_LP64(ShouldNotCallThis());
   683   assert(UseCompressedOops, "only for compressed oops code");
   684   return false;
   685 }
   687 bool Matcher::narrow_klass_use_complex_address() {
   688   NOT_LP64(ShouldNotCallThis());
   689   assert(UseCompressedClassPointers, "only for compressed klass code");
   690   return false;
   691 }
   693 // This is UltraSparc specific, true just means we have fast l2f conversion
   694 const bool Matcher::convL2FSupported(void) {
   695   return true;
   696 }
   698 // Max vector size in bytes. 0 if not supported.
   699 const int Matcher::vector_width_in_bytes(BasicType bt) {
   700   if (MaxVectorSize == 0)
   701     return 0;
   702   assert(MaxVectorSize == 8, "");
   703   return 8;
   704 }
   706 // Vector ideal reg
   707 const int Matcher::vector_ideal_reg(int size) {
   708   assert(MaxVectorSize == 8, "");
   709   switch(size) {
   710     case  8: return Op_VecD;
   711   }
   712   ShouldNotReachHere();
   713   return 0;
   714 }
   716 // Only lowest bits of xmm reg are used for vector shift count.
   717 const int Matcher::vector_shift_count_ideal_reg(int size) {
   718   fatal("vector shift is not supported");
   719   return Node::NotAMachineReg;
   720 }
   722 // Limits on vector size (number of elements) loaded into vector.
   723 const int Matcher::max_vector_size(const BasicType bt) {
   724   assert(is_java_primitive(bt), "only primitive type vectors");
   725   return vector_width_in_bytes(bt)/type2aelembytes(bt);
   726 }
   728 const int Matcher::min_vector_size(const BasicType bt) {
   729   return max_vector_size(bt); // Same as max.
   730 }
   732 // MIPS supports misaligned vectors store/load? FIXME
   733 const bool Matcher::misaligned_vectors_ok() {
   734   return false;
   735   //return !AlignVector; // can be changed by flag
   736 }
   738 // Register for DIVI projection of divmodI
   739 RegMask Matcher::divI_proj_mask() {
   740   ShouldNotReachHere();
   741   return RegMask();
   742 }
   744 // Register for MODI projection of divmodI
   745 RegMask Matcher::modI_proj_mask() {
   746   ShouldNotReachHere();
   747   return RegMask();
   748 }
   750 // Register for DIVL projection of divmodL
   751 RegMask Matcher::divL_proj_mask() {
   752   ShouldNotReachHere();
   753   return RegMask();
   754 }
   756 int Matcher::regnum_to_fpu_offset(int regnum) {
   757   return regnum - 32; // The FP registers are in the second chunk
   758 }
   761 const bool Matcher::isSimpleConstant64(jlong value) {
   762   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
   763   return true;
   764 }
   767 // Return whether or not this register is ever used as an argument.  This
   768 // function is used on startup to build the trampoline stubs in generateOptoStub.
   769 // Registers not mentioned will be killed by the VM call in the trampoline, and
   770 // arguments in those registers not be available to the callee.
   771 bool Matcher::can_be_java_arg( int reg ) {
   772   /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
   773   if (    reg == T0_num || reg == T0_H_num
   774        || reg == A0_num || reg == A0_H_num
   775        || reg == A1_num || reg == A1_H_num
   776        || reg == A2_num || reg == A2_H_num
   777        || reg == A3_num || reg == A3_H_num
   778        || reg == A4_num || reg == A4_H_num
   779        || reg == A5_num || reg == A5_H_num
   780        || reg == A6_num || reg == A6_H_num
   781        || reg == A7_num || reg == A7_H_num )
   782     return true;
   784   if (    reg == F12_num || reg == F12_H_num
   785        || reg == F13_num || reg == F13_H_num
   786        || reg == F14_num || reg == F14_H_num
   787        || reg == F15_num || reg == F15_H_num
   788        || reg == F16_num || reg == F16_H_num
   789        || reg == F17_num || reg == F17_H_num
   790        || reg == F18_num || reg == F18_H_num
   791        || reg == F19_num || reg == F19_H_num )
   792     return true;
   794   return false;
   795 }
   797 bool Matcher::is_spillable_arg( int reg ) {
   798   return can_be_java_arg(reg);
   799 }
   801 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
   802   return false;
   803 }
   805 // Register for MODL projection of divmodL
   806 RegMask Matcher::modL_proj_mask() {
   807   ShouldNotReachHere();
   808   return RegMask();
   809 }
   811 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
   812   return FP_REG_mask();
   813 }
   815 // MIPS doesn't support AES intrinsics
   816 const bool Matcher::pass_original_key_for_aes() {
   817   return false;
   818 }
   820 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
   821   //lui
   822   //ori
   823   //dsll
   824   //ori
   826   //jalr
   827   //nop
   829   return round_to(current_offset, alignment_required()) - current_offset;
   830 }
   832 int CallLeafDirectNode::compute_padding(int current_offset) const {
   833   //lui
   834   //ori
   835   //dsll
   836   //ori
   838   //jalr
   839   //nop
   841   return round_to(current_offset, alignment_required()) - current_offset;
   842 }
   844 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
   845   //lui
   846   //ori
   847   //dsll
   848   //ori
   850   //jalr
   851   //nop
   853   return round_to(current_offset, alignment_required()) - current_offset;
   854 }
   856 // If CPU can load and store mis-aligned doubles directly then no fixup is
   857 // needed.  Else we split the double into 2 integer pieces and move it
   858 // piece-by-piece.  Only happens when passing doubles into C code as the
   859 // Java calling convention forces doubles to be aligned.
   860 const bool Matcher::misaligned_doubles_ok = false;
   861 // Do floats take an entire double register or just half?
   862 //const bool Matcher::float_in_double = true;
   863 bool Matcher::float_in_double() { return false; }
   864 // Threshold size for cleararray.
   865 const int Matcher::init_array_short_size = 8 * BytesPerLong;
   866 // Do ints take an entire long register or just half?
   867 const bool Matcher::int_in_long = true;
   868 // Is it better to copy float constants, or load them directly from memory?
   869 // Intel can load a float constant from a direct address, requiring no
   870 // extra registers.  Most RISCs will have to materialize an address into a
   871 // register first, so they would do better to copy the constant from stack.
   872 const bool Matcher::rematerialize_float_constants = false;
   873 // Advertise here if the CPU requires explicit rounding operations
   874 // to implement the UseStrictFP mode.
   875 const bool Matcher::strict_fp_requires_explicit_rounding = false;
   876 // The ecx parameter to rep stos for the ClearArray node is in dwords.
   877 const bool Matcher::init_array_count_is_in_bytes = false;
   880 // Indicate if the safepoint node needs the polling page as an input.
   881 // Since MIPS doesn't have absolute addressing, it needs.
   882 bool SafePointNode::needs_polling_address_input() {
   883   return false;
   884 }
   886 // !!!!! Special hack to get all type of calls to specify the byte offset
   887 //       from the start of the call to the point where the return address
   888 //       will point.
   889 int MachCallStaticJavaNode::ret_addr_offset() {
   890   //lui
   891   //ori
   892   //nop
   893   //nop
   894   //jalr
   895   //nop
   896   return 24;
   897 }
   899 int MachCallDynamicJavaNode::ret_addr_offset() {
   900   //lui IC_Klass,
   901   //ori IC_Klass,
   902   //dsll IC_Klass
   903   //ori IC_Klass
   905   //lui T9
   906   //ori T9
   907   //nop
   908   //nop
   909   //jalr T9
   910   //nop
   911   return 4 * 4 + 4 * 6;
   912 }
   914 //=============================================================================
   916 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
   917 enum RC { rc_bad, rc_int, rc_float, rc_stack };
   918 static enum RC rc_class( OptoReg::Name reg ) {
   919   if( !OptoReg::is_valid(reg)  ) return rc_bad;
   920   if (OptoReg::is_stack(reg)) return rc_stack;
   921   VMReg r = OptoReg::as_VMReg(reg);
   922   if (r->is_Register()) return rc_int;
   923   assert(r->is_FloatRegister(), "must be");
   924   return rc_float;
   925 }
   927 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
   928   // Get registers to move
   929   OptoReg::Name src_second = ra_->get_reg_second(in(1));
   930   OptoReg::Name src_first = ra_->get_reg_first(in(1));
   931   OptoReg::Name dst_second = ra_->get_reg_second(this );
   932   OptoReg::Name dst_first = ra_->get_reg_first(this );
   934   enum RC src_second_rc = rc_class(src_second);
   935   enum RC src_first_rc = rc_class(src_first);
   936   enum RC dst_second_rc = rc_class(dst_second);
   937   enum RC dst_first_rc = rc_class(dst_first);
   939   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
   941   // Generate spill code!
   942   int size = 0;
   944   if( src_first == dst_first && src_second == dst_second )
   945     return 0;            // Self copy, no move
   947   if (src_first_rc == rc_stack) {
   948     // mem ->
   949     if (dst_first_rc == rc_stack) {
   950       // mem -> mem
   951       assert(src_second != dst_first, "overlap");
   952       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   953           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   954         // 64-bit
   955         int src_offset = ra_->reg2offset(src_first);
   956         int dst_offset = ra_->reg2offset(dst_first);
   957         if (cbuf) {
   958           MacroAssembler _masm(cbuf);
   959           __ ld(AT, Address(SP, src_offset));
   960           __ sd(AT, Address(SP, dst_offset));
   961 #ifndef PRODUCT
   962         } else {
   963           if(!do_size){
   964             if (size != 0) st->print("\n\t");
   965               st->print("ld    AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
   966                         "sd    AT, [SP + #%d]",
   967                         src_offset, dst_offset);
   968           }
   969 #endif
   970         }
   971         size += 8;
   972       } else {
   973         // 32-bit
   974         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
   975         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
   976         // No pushl/popl, so:
   977         int src_offset = ra_->reg2offset(src_first);
   978         int dst_offset = ra_->reg2offset(dst_first);
   979         if (cbuf) {
   980           MacroAssembler _masm(cbuf);
   981           __ lw(AT, Address(SP, src_offset));
   982           __ sw(AT, Address(SP, dst_offset));
   983 #ifndef PRODUCT
   984         } else {
   985           if(!do_size){
   986             if (size != 0) st->print("\n\t");
   987               st->print("lw    AT, [SP + #%d] spill 2\n\t"
   988                         "sw    AT, [SP + #%d]\n\t",
   989                         src_offset, dst_offset);
   990           }
   991 #endif
   992         }
   993         size += 8;
   994       }
   995       return size;
   996     } else if (dst_first_rc == rc_int) {
   997       // mem -> gpr
   998       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   999           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1000         // 64-bit
  1001         int offset = ra_->reg2offset(src_first);
  1002         if (cbuf) {
  1003           MacroAssembler _masm(cbuf);
  1004           __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1005 #ifndef PRODUCT
  1006         } else {
  1007           if(!do_size){
  1008             if (size != 0) st->print("\n\t");
  1009               st->print("ld    %s, [SP + #%d]\t# spill 3",
  1010                         Matcher::regName[dst_first],
  1011                         offset);
  1013 #endif
  1015         size += 4;
  1016       } else {
  1017         // 32-bit
  1018         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1019         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1020         int offset = ra_->reg2offset(src_first);
  1021         if (cbuf) {
  1022           MacroAssembler _masm(cbuf);
  1023           if (this->ideal_reg() == Op_RegI)
  1024             __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1025           else
  1026             __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1027 #ifndef PRODUCT
  1028           } else {
  1029             if(!do_size){
  1030               if (size != 0) st->print("\n\t");
  1031               if (this->ideal_reg() == Op_RegI)
  1032                 st->print("lw    %s, [SP + #%d]\t# spill 4",
  1033                           Matcher::regName[dst_first],
  1034                           offset);
  1035               else
  1036                 st->print("lwu    %s, [SP + #%d]\t# spill 5",
  1037                           Matcher::regName[dst_first],
  1038                           offset);
  1040 #endif
  1042           size += 4;
  1044       return size;
  1045     } else if (dst_first_rc == rc_float) {
  1046       // mem-> xmm
  1047       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1048           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1049         // 64-bit
  1050         int offset = ra_->reg2offset(src_first);
  1051         if (cbuf) {
  1052           MacroAssembler _masm(cbuf);
  1053           __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1054 #ifndef PRODUCT
  1055         } else {
  1056           if (!do_size) {
  1057             if (size != 0) st->print("\n\t");
  1058             st->print("ldc1  %s, [SP + #%d]\t# spill 6",
  1059                       Matcher::regName[dst_first],
  1060                       offset);
  1062 #endif
  1064         size += 4;
  1065       } else {
  1066         // 32-bit
  1067         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1068         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1069         int offset = ra_->reg2offset(src_first);
  1070         if (cbuf) {
  1071           MacroAssembler _masm(cbuf);
  1072           __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1073 #ifndef PRODUCT
  1074         } else {
  1075           if(!do_size){
  1076             if (size != 0) st->print("\n\t");
  1077             st->print("lwc1   %s, [SP + #%d]\t# spill 7",
  1078                       Matcher::regName[dst_first],
  1079                       offset);
  1081 #endif
  1083         size += 4;
  1085       return size;
  1087   } else if (src_first_rc == rc_int) {
  1088     // gpr ->
  1089     if (dst_first_rc == rc_stack) {
  1090       // gpr -> mem
  1091       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1092           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1093         // 64-bit
  1094         int offset = ra_->reg2offset(dst_first);
  1095         if (cbuf) {
  1096           MacroAssembler _masm(cbuf);
  1097           __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1098 #ifndef PRODUCT
  1099         } else {
  1100           if(!do_size){
  1101             if (size != 0) st->print("\n\t");
  1102             st->print("sd    %s, [SP + #%d] # spill 8",
  1103                       Matcher::regName[src_first],
  1104                       offset);
  1106 #endif
  1108         size += 4;
  1109       } else {
  1110         // 32-bit
  1111         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1112         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1113         int offset = ra_->reg2offset(dst_first);
  1114         if (cbuf) {
  1115           MacroAssembler _masm(cbuf);
  1116           __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1117 #ifndef PRODUCT
  1118         } else {
  1119           if (!do_size) {
  1120             if (size != 0) st->print("\n\t");
  1121             st->print("sw    %s, [SP + #%d]\t# spill 9",
  1122                       Matcher::regName[src_first], offset);
  1124 #endif
  1126         size += 4;
  1128       return size;
  1129     } else if (dst_first_rc == rc_int) {
  1130       // gpr -> gpr
  1131       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1132           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1133         // 64-bit
  1134         if (cbuf) {
  1135           MacroAssembler _masm(cbuf);
  1136           __ move(as_Register(Matcher::_regEncode[dst_first]),
  1137                   as_Register(Matcher::_regEncode[src_first]));
  1138 #ifndef PRODUCT
  1139         } else {
  1140           if(!do_size){
  1141             if (size != 0) st->print("\n\t");
  1142             st->print("move(64bit)    %s <-- %s\t# spill 10",
  1143                       Matcher::regName[dst_first],
  1144                       Matcher::regName[src_first]);
  1146 #endif
  1148         size += 4;
  1149         return size;
  1150       } else {
  1151         // 32-bit
  1152         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1153         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1154         if (cbuf) {
  1155           MacroAssembler _masm(cbuf);
  1156           if (this->ideal_reg() == Op_RegI)
  1157               __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
  1158           else
  1159               __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
  1160 #ifndef PRODUCT
  1161         } else {
  1162           if (!do_size) {
  1163             if (size != 0) st->print("\n\t");
  1164             st->print("move(32-bit)    %s <-- %s\t# spill 11",
  1165                       Matcher::regName[dst_first],
  1166                       Matcher::regName[src_first]);
  1168 #endif
  1170         size += 4;
  1171         return size;
  1173     } else if (dst_first_rc == rc_float) {
  1174       // gpr -> xmm
  1175       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1176           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1177         // 64-bit
  1178         if (cbuf) {
  1179           MacroAssembler _masm(cbuf);
  1180           __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
  1181 #ifndef PRODUCT
  1182         } else {
  1183           if(!do_size){
  1184             if (size != 0) st->print("\n\t");
  1185             st->print("dmtc1   %s, %s\t# spill 12",
  1186                       Matcher::regName[dst_first],
  1187                       Matcher::regName[src_first]);
  1189 #endif
  1191         size += 4;
  1192       } else {
  1193         // 32-bit
  1194         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1195         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1196         if (cbuf) {
  1197           MacroAssembler _masm(cbuf);
  1198           __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
  1199 #ifndef PRODUCT
  1200         } else {
  1201           if(!do_size){
  1202             if (size != 0) st->print("\n\t");
  1203             st->print("mtc1   %s, %s\t# spill 13",
  1204                       Matcher::regName[dst_first],
  1205                       Matcher::regName[src_first]);
  1207 #endif
  1209         size += 4;
  1211       return size;
  1213   } else if (src_first_rc == rc_float) {
  1214     // xmm ->
  1215     if (dst_first_rc == rc_stack) {
  1216       // xmm -> mem
  1217       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1218           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1219         // 64-bit
  1220         int offset = ra_->reg2offset(dst_first);
  1221         if (cbuf) {
  1222           MacroAssembler _masm(cbuf);
  1223           __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
  1224 #ifndef PRODUCT
  1225         } else {
  1226           if(!do_size){
  1227             if (size != 0) st->print("\n\t");
  1228             st->print("sdc1   %s, [SP + #%d]\t# spill 14",
  1229                       Matcher::regName[src_first],
  1230                       offset);
  1232 #endif
  1234         size += 4;
  1235       } else {
  1236         // 32-bit
  1237         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1238         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1239         int offset = ra_->reg2offset(dst_first);
  1240         if (cbuf) {
  1241           MacroAssembler _masm(cbuf);
  1242           __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
  1243 #ifndef PRODUCT
  1244         } else {
  1245           if(!do_size){
  1246             if (size != 0) st->print("\n\t");
  1247             st->print("swc1   %s, [SP + #%d]\t# spill 15",
  1248                       Matcher::regName[src_first],
  1249                       offset);
  1251 #endif
  1253         size += 4;
  1255       return size;
  1256     } else if (dst_first_rc == rc_int) {
  1257       // xmm -> gpr
  1258       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1259           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1260         // 64-bit
  1261         if (cbuf) {
  1262           MacroAssembler _masm(cbuf);
  1263           __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1264 #ifndef PRODUCT
  1265         } else {
  1266           if(!do_size){
  1267             if (size != 0) st->print("\n\t");
  1268             st->print("dmfc1   %s, %s\t# spill 16",
  1269                       Matcher::regName[dst_first],
  1270                       Matcher::regName[src_first]);
  1272 #endif
  1274         size += 4;
  1275       } else {
  1276         // 32-bit
  1277         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1278         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1279         if (cbuf) {
  1280           MacroAssembler _masm(cbuf);
  1281           __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1282 #ifndef PRODUCT
  1283         } else {
  1284       if(!do_size){
  1285             if (size != 0) st->print("\n\t");
  1286             st->print("mfc1   %s, %s\t# spill 17",
  1287                       Matcher::regName[dst_first],
  1288                       Matcher::regName[src_first]);
  1290 #endif
  1292         size += 4;
  1294       return size;
  1295     } else if (dst_first_rc == rc_float) {
  1296       // xmm -> xmm
  1297       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1298           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1299         // 64-bit
  1300         if (cbuf) {
  1301           MacroAssembler _masm(cbuf);
  1302           __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1303 #ifndef PRODUCT
  1304         } else {
  1305           if(!do_size){
  1306             if (size != 0) st->print("\n\t");
  1307             st->print("mov_d  %s <-- %s\t# spill 18",
  1308                       Matcher::regName[dst_first],
  1309                       Matcher::regName[src_first]);
  1311 #endif
  1313         size += 4;
  1314       } else {
  1315         // 32-bit
  1316         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1317         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1318         if (cbuf) {
  1319           MacroAssembler _masm(cbuf);
  1320           __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1321 #ifndef PRODUCT
  1322         } else {
  1323           if(!do_size){
  1324             if (size != 0) st->print("\n\t");
  1325             st->print("mov_s  %s <-- %s\t# spill 19",
  1326                       Matcher::regName[dst_first],
  1327                       Matcher::regName[src_first]);
  1329 #endif
  1331         size += 4;
  1333       return size;
  1337   assert(0," foo ");
  1338   Unimplemented();
  1339   return size;
  1343 #ifndef PRODUCT
  1344 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1345   implementation( NULL, ra_, false, st );
  1347 #endif
  1349 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1350   implementation( &cbuf, ra_, false, NULL );
  1353 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  1354   return implementation( NULL, ra_, true, NULL );
  1357 //=============================================================================
  1360 #ifndef PRODUCT
  1361 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1362   st->print("INT3");
  1364 #endif
  1366 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
  1367   MacroAssembler _masm(&cbuf);
  1368   __ int3();
  1371 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
  1372   return MachNode::size(ra_);
  1376 //=============================================================================
  1377 #ifndef PRODUCT
  1378 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1379   Compile *C = ra_->C;
  1380   int framesize = C->frame_size_in_bytes();
  1382   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1384   st->print_cr("daddiu   SP, SP, %d # Rlease stack @ MachEpilogNode", framesize);
  1385   st->print("\t");
  1386   if (UseLoongsonISA) {
  1387     st->print_cr("gslq  RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
  1388   } else {
  1389     st->print_cr("ld    RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
  1390     st->print("\t");
  1391     st->print_cr("ld    FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
  1394   if( do_polling() && C->is_method_compilation() ) {
  1395     st->print("\t");
  1396     st->print_cr("Poll Safepoint # MachEpilogNode");
  1399 #endif
  1401 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1402   Compile *C = ra_->C;
  1403   MacroAssembler _masm(&cbuf);
  1404   int framesize = C->frame_size_in_bytes();
  1406   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1408   __ daddiu(SP, SP, framesize);
  1410   if (UseLoongsonISA) {
  1411     __ gslq(RA, FP, SP, -wordSize*2);
  1412   } else {
  1413     __ ld(RA, SP, -wordSize );
  1414     __ ld(FP, SP, -wordSize*2 );
  1417   if( do_polling() && C->is_method_compilation() ) {
  1418     __ set64(AT, (long)os::get_polling_page());
  1419     __ relocate(relocInfo::poll_return_type);
  1420     __ lw(AT, AT, 0);
  1424 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  1425   return MachNode::size(ra_); // too many variables; just compute it the hard way  fujie debug
  1428 int MachEpilogNode::reloc() const {
  1429   return 0; // a large enough number
  1432 const Pipeline * MachEpilogNode::pipeline() const {
  1433   return MachNode::pipeline_class();
  1436 int MachEpilogNode::safepoint_offset() const { return 0; }
  1438 //=============================================================================
  1440 #ifndef PRODUCT
  1441 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1442   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1443   int reg = ra_->get_reg_first(this);
  1444   st->print("ADDI %s, SP, %d   @BoxLockNode",Matcher::regName[reg],offset);
  1446 #endif
  1449 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  1450   return 4;
  1453 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1454   MacroAssembler _masm(&cbuf);
  1455   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1456   int reg = ra_->get_encode(this);
  1458   __ addi(as_Register(reg), SP, offset);
  1462 //static int sizeof_FFree_Float_Stack_All = -1;
  1464 int MachCallRuntimeNode::ret_addr_offset() {
  1465   //lui
  1466   //ori
  1467   //dsll
  1468   //ori
  1469   //jalr
  1470   //nop
  1471   assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
  1472   return NativeCall::instruction_size;
  1476 //=============================================================================
  1477 #ifndef PRODUCT
  1478 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1479   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  1481 #endif
  1483 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  1484   MacroAssembler _masm(&cbuf);
  1485   int i = 0;
  1486   for(i = 0; i < _count; i++)
  1487      __ nop();
  1490 uint MachNopNode::size(PhaseRegAlloc *) const {
  1491   return 4 * _count;
  1493 const Pipeline* MachNopNode::pipeline() const {
  1494   return MachNode::pipeline_class();
  1497 //=============================================================================
  1499 //=============================================================================
  1500 #ifndef PRODUCT
  1501 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1502   st->print_cr("load_klass(T9, T0)");
  1503   st->print_cr("\tbeq(T9, iCache, L)");
  1504   st->print_cr("\tnop");
  1505   st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
  1506   st->print_cr("\tnop");
  1507   st->print_cr("\tnop");
  1508   st->print_cr("    L:");
  1510 #endif
  1513 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1514   MacroAssembler _masm(&cbuf);
  1515 #ifdef ASSERT
  1516   //uint code_size = cbuf.code_size();
  1517 #endif
  1518   int  ic_reg = Matcher::inline_cache_reg_encode();
  1519   Label L;
  1520   Register receiver = T0;
  1521   Register   iCache = as_Register(ic_reg);
  1522   __ load_klass(T9, receiver);
  1523   __ beq(T9, iCache, L);
  1524   __ delayed()->nop();
  1526   __ relocate(relocInfo::runtime_call_type);
  1527   __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
  1529   /* WARNING these NOPs are critical so that verified entry point is properly
  1530    *      8 bytes aligned for patching by NativeJump::patch_verified_entry() */
  1531   __ align(CodeEntryAlignment);
  1532   __ bind(L);
  1535 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  1536   return MachNode::size(ra_);
  1541 //=============================================================================
  1543 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
  1545 int Compile::ConstantTable::calculate_table_base_offset() const {
  1546   return 0;  // absolute addressing, no offset
  1549 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  1550 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  1551   ShouldNotReachHere();
  1554 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  1555   Compile* C = ra_->C;
  1556   Compile::ConstantTable& constant_table = C->constant_table();
  1557   MacroAssembler _masm(&cbuf);
  1559   Register Rtoc = as_Register(ra_->get_encode(this));
  1560   CodeSection* consts_section = __ code()->consts();
  1561   int consts_size = consts_section->align_at_start(consts_section->size());
  1562   assert(constant_table.size() == consts_size, "must be equal");
  1564   if (consts_section->size()) {
  1565     // Materialize the constant table base.
  1566     address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  1567     // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  1568     __ relocate(relocInfo::internal_word_type);
  1569     __ patchable_set48(Rtoc, (long)baseaddr);
  1573 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
  1574   // patchable_set48 (4 insts)
  1575   return 4 * 4;
  1578 #ifndef PRODUCT
  1579 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  1580   Register r = as_Register(ra_->get_encode(this));
  1581   st->print("patchable_set48    %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
  1583 #endif
  1586 //=============================================================================
  1587 #ifndef PRODUCT
  1588 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1589   Compile* C = ra_->C;
  1591   int framesize = C->frame_size_in_bytes();
  1592   int bangsize = C->bang_size_in_bytes();
  1593   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1595   // Calls to C2R adapters often do not accept exceptional returns.
  1596   // We require that their callers must bang for them.  But be careful, because
  1597   // some VM calls (such as call site linkage) can use several kilobytes of
  1598   // stack.  But the stack safety zone should account for that.
  1599   // See bugs 4446381, 4468289, 4497237.
  1600   if (C->need_stack_bang(bangsize)) {
  1601     st->print_cr("# stack bang"); st->print("\t");
  1603   if (UseLoongsonISA) {
  1604     st->print("gssq     RA, FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1605   } else {
  1606     st->print("sd       RA, %d(SP)  @ MachPrologNode\n\t", -wordSize);
  1607     st->print("sd       FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1609   st->print("daddiu   FP, SP, -%d \n\t", wordSize*2);
  1610   st->print("daddiu   SP, SP, -%d \t",framesize);
  1612 #endif
  1615 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1616   Compile* C = ra_->C;
  1617   MacroAssembler _masm(&cbuf);
  1619   int framesize = C->frame_size_in_bytes();
  1620   int bangsize = C->bang_size_in_bytes();
  1622   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1624   if (C->need_stack_bang(bangsize)) {
  1625     __ generate_stack_overflow_check(bangsize);
  1628   if (UseLoongsonISA) {
  1629     __ gssq(RA, FP, SP, -wordSize*2);
  1630   } else {
  1631     __ sd(RA, SP, -wordSize);
  1632     __ sd(FP, SP, -wordSize*2);
  1634   __ daddiu(FP, SP, -wordSize*2);
  1635   __ daddiu(SP, SP, -framesize);
  1636   __ nop(); // Make enough room for patch_verified_entry()
  1637   __ nop();
  1639   C->set_frame_complete(cbuf.insts_size());
  1640   if (C->has_mach_constant_base_node()) {
  1641     // NOTE: We set the table base offset here because users might be
  1642     // emitted before MachConstantBaseNode.
  1643     Compile::ConstantTable& constant_table = C->constant_table();
  1644     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  1650 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  1651   return MachNode::size(ra_); // too many variables; just compute it the hard way
  1654 int MachPrologNode::reloc() const {
  1655   return 0; // a large enough number
  1658 %}
  1660 //----------ENCODING BLOCK-----------------------------------------------------
  1661 // This block specifies the encoding classes used by the compiler to output
  1662 // byte streams.  Encoding classes generate functions which are called by
  1663 // Machine Instruction Nodes in order to generate the bit encoding of the
  1664 // instruction.  Operands specify their base encoding interface with the
  1665 // interface keyword.  There are currently supported four interfaces,
  1666 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
  1667 // operand to generate a function which returns its register number when
  1668 // queried.   CONST_INTER causes an operand to generate a function which
  1669 // returns the value of the constant when queried.  MEMORY_INTER causes an
  1670 // operand to generate four functions which return the Base Register, the
  1671 // Index Register, the Scale Value, and the Offset Value of the operand when
  1672 // queried.  COND_INTER causes an operand to generate six functions which
  1673 // return the encoding code (ie - encoding bits for the instruction)
  1674 // associated with each basic boolean condition for a conditional instruction.
  1675 // Instructions specify two basic values for encoding.  They use the
  1676 // ins_encode keyword to specify their encoding class (which must be one of
  1677 // the class names specified in the encoding block), and they use the
  1678 // opcode keyword to specify, in order, their primary, secondary, and
  1679 // tertiary opcode.  Only the opcode sections which a particular instruction
  1680 // needs for encoding need to be specified.
  1681 encode %{
  1683   //Load byte signed
  1684   enc_class load_B_enc (mRegI dst, memory mem) %{
  1685     MacroAssembler _masm(&cbuf);
  1686     int  dst = $dst$$reg;
  1687     int  base = $mem$$base;
  1688     int  index = $mem$$index;
  1689     int  scale = $mem$$scale;
  1690     int  disp = $mem$$disp;
  1692     if( index != 0 ) {
  1693       if( Assembler::is_simm16(disp) ) {
  1694         if( UseLoongsonISA ) {
  1695           if (scale == 0) {
  1696             __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1697           } else {
  1698             __ dsll(AT, as_Register(index), scale);
  1699             __ gslbx(as_Register(dst), as_Register(base), AT, disp);
  1701         } else {
  1702           if (scale == 0) {
  1703             __ addu(AT, as_Register(base), as_Register(index));
  1704           } else {
  1705             __ dsll(AT, as_Register(index), scale);
  1706             __ addu(AT, as_Register(base), AT);
  1708           __ lb(as_Register(dst), AT, disp);
  1710       } else {
  1711         if (scale == 0) {
  1712           __ addu(AT, as_Register(base), as_Register(index));
  1713         } else {
  1714           __ dsll(AT, as_Register(index), scale);
  1715           __ addu(AT, as_Register(base), AT);
  1717         __ move(T9, disp);
  1718         if( UseLoongsonISA ) {
  1719           __ gslbx(as_Register(dst), AT, T9, 0);
  1720         } else {
  1721           __ addu(AT, AT, T9);
  1722           __ lb(as_Register(dst), AT, 0);
  1725     } else {
  1726       if( Assembler::is_simm16(disp) ) {
  1727         __ lb(as_Register(dst), as_Register(base), disp);
  1728       } else {
  1729         __ move(T9, disp);
  1730         if( UseLoongsonISA ) {
  1731           __ gslbx(as_Register(dst), as_Register(base), T9, 0);
  1732         } else {
  1733           __ addu(AT, as_Register(base), T9);
  1734           __ lb(as_Register(dst), AT, 0);
  1738   %}
  1740   //Load byte unsigned
  1741   enc_class load_UB_enc (mRegI dst, memory mem) %{
  1742     MacroAssembler _masm(&cbuf);
  1743     int  dst = $dst$$reg;
  1744     int  base = $mem$$base;
  1745     int  index = $mem$$index;
  1746     int  scale = $mem$$scale;
  1747     int  disp = $mem$$disp;
  1749     if( index != 0 ) {
  1750       if (scale == 0) {
  1751         __ daddu(AT, as_Register(base), as_Register(index));
  1752       } else {
  1753         __ dsll(AT, as_Register(index), scale);
  1754         __ daddu(AT, as_Register(base), AT);
  1756       if( Assembler::is_simm16(disp) ) {
  1757         __ lbu(as_Register(dst), AT, disp);
  1758       } else {
  1759         __ move(T9, disp);
  1760         __ daddu(AT, AT, T9);
  1761         __ lbu(as_Register(dst), AT, 0);
  1763     } else {
  1764       if( Assembler::is_simm16(disp) ) {
  1765         __ lbu(as_Register(dst), as_Register(base), disp);
  1766       } else {
  1767         __ move(T9, disp);
  1768         __ daddu(AT, as_Register(base), T9);
  1769         __ lbu(as_Register(dst), AT, 0);
  1772   %}
  1774   enc_class store_B_reg_enc (memory mem, mRegI src) %{
  1775     MacroAssembler _masm(&cbuf);
  1776     int  src = $src$$reg;
  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       if (scale == 0) {
  1784         if( Assembler::is_simm(disp, 8) ) {
  1785           if (UseLoongsonISA) {
  1786             __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
  1787           } else {
  1788             __ addu(AT, as_Register(base), as_Register(index));
  1789             __ sb(as_Register(src), AT, disp);
  1791         } else if( Assembler::is_simm16(disp) ) {
  1792           __ addu(AT, as_Register(base), as_Register(index));
  1793           __ sb(as_Register(src), AT, disp);
  1794         } else {
  1795           __ addu(AT, as_Register(base), as_Register(index));
  1796           __ move(T9, disp);
  1797           if (UseLoongsonISA) {
  1798             __ gssbx(as_Register(src), AT, T9, 0);
  1799           } else {
  1800             __ addu(AT, AT, T9);
  1801             __ sb(as_Register(src), AT, 0);
  1804       } else {
  1805         __ dsll(AT, as_Register(index), scale);
  1806         if( Assembler::is_simm(disp, 8) ) {
  1807           if (UseLoongsonISA) {
  1808             __ gssbx(as_Register(src), AT, as_Register(base), disp);
  1809           } else {
  1810             __ addu(AT, as_Register(base), AT);
  1811             __ sb(as_Register(src), AT, disp);
  1813         } else if( Assembler::is_simm16(disp) ) {
  1814           __ addu(AT, as_Register(base), AT);
  1815           __ sb(as_Register(src), AT, disp);
  1816         } else {
  1817           __ addu(AT, as_Register(base), AT);
  1818           __ move(T9, disp);
  1819           if (UseLoongsonISA) {
  1820             __ gssbx(as_Register(src), AT, T9, 0);
  1821           } else {
  1822             __ addu(AT, AT, T9);
  1823             __ sb(as_Register(src), AT, 0);
  1827     } else {
  1828       if( Assembler::is_simm16(disp) ) {
  1829         __ sb(as_Register(src), as_Register(base), disp);
  1830       } else {
  1831         __ move(T9, disp);
  1832         if (UseLoongsonISA) {
  1833           __ gssbx(as_Register(src), as_Register(base), T9, 0);
  1834         } else {
  1835           __ addu(AT, as_Register(base), T9);
  1836           __ sb(as_Register(src), AT, 0);
  1840   %}
  1842   enc_class store_B_immI_enc (memory mem, immI8 src) %{
  1843     MacroAssembler _masm(&cbuf);
  1844     int  base = $mem$$base;
  1845     int  index = $mem$$index;
  1846     int  scale = $mem$$scale;
  1847     int  disp = $mem$$disp;
  1848     int value = $src$$constant;
  1850     if( index != 0 ) {
  1851       if (!UseLoongsonISA) {
  1852         if (scale == 0) {
  1853           __ daddu(AT, as_Register(base), as_Register(index));
  1854         } else {
  1855           __ dsll(AT, as_Register(index), scale);
  1856           __ daddu(AT, as_Register(base), AT);
  1858         if( Assembler::is_simm16(disp) ) {
  1859           if (value == 0) {
  1860             __ sb(R0, AT, disp);
  1861           } else {
  1862             __ move(T9, value);
  1863             __ sb(T9, AT, disp);
  1865         } else {
  1866           if (value == 0) {
  1867             __ move(T9, disp);
  1868             __ daddu(AT, AT, T9);
  1869             __ sb(R0, AT, 0);
  1870           } else {
  1871             __ move(T9, disp);
  1872             __ daddu(AT, AT, T9);
  1873             __ move(T9, value);
  1874             __ sb(T9, AT, 0);
  1877       } else {
  1879         if (scale == 0) {
  1880           if( Assembler::is_simm(disp, 8) ) {
  1881             if (value == 0) {
  1882               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1883             } else {
  1884               __ move(T9, value);
  1885               __ gssbx(T9, as_Register(base), as_Register(index), disp);
  1887           } else if( Assembler::is_simm16(disp) ) {
  1888             __ daddu(AT, as_Register(base), as_Register(index));
  1889             if (value == 0) {
  1890               __ sb(R0, AT, disp);
  1891             } else {
  1892               __ move(T9, value);
  1893               __ sb(T9, AT, disp);
  1895           } else {
  1896             if (value == 0) {
  1897               __ daddu(AT, as_Register(base), as_Register(index));
  1898               __ move(T9, disp);
  1899               __ gssbx(R0, AT, T9, 0);
  1900             } else {
  1901               __ move(AT, disp);
  1902               __ move(T9, value);
  1903               __ daddu(AT, as_Register(base), AT);
  1904               __ gssbx(T9, AT, as_Register(index), 0);
  1908         } else {
  1910           if( Assembler::is_simm(disp, 8) ) {
  1911             __ dsll(AT, as_Register(index), scale);
  1912             if (value == 0) {
  1913               __ gssbx(R0, as_Register(base), AT, disp);
  1914             } else {
  1915               __ move(T9, value);
  1916               __ gssbx(T9, as_Register(base), AT, disp);
  1918           } else if( Assembler::is_simm16(disp) ) {
  1919             __ dsll(AT, as_Register(index), scale);
  1920             __ daddu(AT, as_Register(base), AT);
  1921             if (value == 0) {
  1922               __ sb(R0, AT, disp);
  1923             } else {
  1924               __ move(T9, value);
  1925               __ sb(T9, AT, disp);
  1927           } else {
  1928             __ dsll(AT, as_Register(index), scale);
  1929             if (value == 0) {
  1930               __ daddu(AT, as_Register(base), AT);
  1931               __ move(T9, disp);
  1932               __ gssbx(R0, AT, T9, 0);
  1933             } else {
  1934               __ move(T9, disp);
  1935               __ daddu(AT, AT, T9);
  1936               __ move(T9, value);
  1937               __ gssbx(T9, as_Register(base), AT, 0);
  1942     } else {
  1943       if( Assembler::is_simm16(disp) ) {
  1944         if (value == 0) {
  1945           __ sb(R0, as_Register(base), disp);
  1946         } else {
  1947           __ move(AT, value);
  1948           __ sb(AT, as_Register(base), disp);
  1950       } else {
  1951         if (value == 0) {
  1952           __ move(T9, disp);
  1953           if (UseLoongsonISA) {
  1954             __ gssbx(R0, as_Register(base), T9, 0);
  1955           } else {
  1956             __ daddu(AT, as_Register(base), T9);
  1957             __ sb(R0, AT, 0);
  1959         } else {
  1960           __ move(T9, disp);
  1961           if (UseLoongsonISA) {
  1962             __ move(AT, value);
  1963             __ gssbx(AT, as_Register(base), T9, 0);
  1964           } else {
  1965             __ daddu(AT, as_Register(base), T9);
  1966             __ move(T9, value);
  1967             __ sb(T9, AT, 0);
  1972   %}
  1975   enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
  1976     MacroAssembler _masm(&cbuf);
  1977     int  base = $mem$$base;
  1978     int  index = $mem$$index;
  1979     int  scale = $mem$$scale;
  1980     int  disp = $mem$$disp;
  1981     int value = $src$$constant;
  1983     if( index != 0 ) {
  1984       if ( UseLoongsonISA ) {
  1985         if ( Assembler::is_simm(disp,8) ) {
  1986           if ( scale == 0 ) {
  1987             if ( value == 0 ) {
  1988               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1989             } else {
  1990               __ move(AT, value);
  1991               __ gssbx(AT, as_Register(base), as_Register(index), disp);
  1993           } else {
  1994             __ dsll(AT, as_Register(index), scale);
  1995             if ( value == 0 ) {
  1996               __ gssbx(R0, as_Register(base), AT, disp);
  1997             } else {
  1998               __ move(T9, value);
  1999               __ gssbx(T9, as_Register(base), AT, disp);
  2002         } else if ( Assembler::is_simm16(disp) ) {
  2003           if ( scale == 0 ) {
  2004             __ daddu(AT, as_Register(base), as_Register(index));
  2005             if ( value == 0 ){
  2006               __ sb(R0, AT, disp);
  2007             } else {
  2008               __ move(T9, value);
  2009               __ sb(T9, AT, disp);
  2011           } else {
  2012             __ dsll(AT, as_Register(index), scale);
  2013             __ daddu(AT, as_Register(base), AT);
  2014             if ( value == 0 ) {
  2015               __ sb(R0, AT, disp);
  2016             } else {
  2017               __ move(T9, value);
  2018               __ sb(T9, AT, disp);
  2021         } else {
  2022           if ( scale == 0 ) {
  2023             __ move(AT, disp);
  2024             __ daddu(AT, as_Register(index), AT);
  2025             if ( value == 0 ) {
  2026               __ gssbx(R0, as_Register(base), AT, 0);
  2027             } else {
  2028               __ move(T9, value);
  2029               __ gssbx(T9, as_Register(base), AT, 0);
  2031           } else {
  2032             __ dsll(AT, as_Register(index), scale);
  2033             __ move(T9, disp);
  2034             __ daddu(AT, AT, T9);
  2035             if ( value == 0 ) {
  2036               __ gssbx(R0, as_Register(base), AT, 0);
  2037             } else {
  2038               __ move(T9, value);
  2039               __ gssbx(T9, as_Register(base), AT, 0);
  2043       } else { //not use loongson isa
  2044         if (scale == 0) {
  2045           __ daddu(AT, as_Register(base), as_Register(index));
  2046         } else {
  2047           __ dsll(AT, as_Register(index), scale);
  2048           __ daddu(AT, as_Register(base), AT);
  2050         if( Assembler::is_simm16(disp) ) {
  2051           if (value == 0) {
  2052             __ sb(R0, AT, disp);
  2053           } else {
  2054             __ move(T9, value);
  2055             __ sb(T9, AT, disp);
  2057         } else {
  2058           if (value == 0) {
  2059             __ move(T9, disp);
  2060             __ daddu(AT, AT, T9);
  2061             __ sb(R0, AT, 0);
  2062           } else {
  2063             __ move(T9, disp);
  2064             __ daddu(AT, AT, T9);
  2065             __ move(T9, value);
  2066             __ sb(T9, AT, 0);
  2070     } else {
  2071       if ( UseLoongsonISA ){
  2072         if ( Assembler::is_simm16(disp) ){
  2073           if ( value == 0 ) {
  2074             __ sb(R0, as_Register(base), disp);
  2075           } else {
  2076             __ move(AT, value);
  2077             __ sb(AT, as_Register(base), disp);
  2079         } else {
  2080           __ move(AT, disp);
  2081           if ( value == 0 ) {
  2082             __ gssbx(R0, as_Register(base), AT, 0);
  2083           } else {
  2084             __ move(T9, value);
  2085             __ gssbx(T9, as_Register(base), AT, 0);
  2088       } else {
  2089         if( Assembler::is_simm16(disp) ) {
  2090           if (value == 0) {
  2091             __ sb(R0, as_Register(base), disp);
  2092           } else {
  2093             __ move(AT, value);
  2094             __ sb(AT, as_Register(base), disp);
  2096         } else {
  2097           if (value == 0) {
  2098             __ move(T9, disp);
  2099             __ daddu(AT, as_Register(base), T9);
  2100             __ sb(R0, AT, 0);
  2101           } else {
  2102             __ move(T9, disp);
  2103             __ daddu(AT, as_Register(base), T9);
  2104             __ move(T9, value);
  2105             __ sb(T9, AT, 0);
  2111     __ sync();
  2112   %}
  2114   // Load Short (16bit signed)
  2115   enc_class load_S_enc (mRegI dst, memory mem) %{
  2116     MacroAssembler _masm(&cbuf);
  2117     int  dst = $dst$$reg;
  2118     int  base = $mem$$base;
  2119     int  index = $mem$$index;
  2120     int  scale = $mem$$scale;
  2121     int  disp = $mem$$disp;
  2123     if( index != 0 ) {
  2124       if ( UseLoongsonISA ) {
  2125         if ( Assembler::is_simm(disp, 8) ) {
  2126           if (scale == 0) {
  2127             __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2128           } else {
  2129             __ dsll(AT, as_Register(index), scale);
  2130             __ gslhx(as_Register(dst), as_Register(base), AT, disp);
  2132         } else if ( Assembler::is_simm16(disp) ) {
  2133           if (scale == 0) {
  2134             __ daddu(AT, as_Register(base), as_Register(index));
  2135             __ lh(as_Register(dst), AT, disp);
  2136           } else {
  2137             __ dsll(AT, as_Register(index), scale);
  2138             __ daddu(AT, as_Register(base), AT);
  2139             __ lh(as_Register(dst), AT, disp);
  2141         } else {
  2142           if (scale == 0) {
  2143             __ move(AT, disp);
  2144             __ daddu(AT, as_Register(index), AT);
  2145             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2146           } else {
  2147             __ dsll(AT, as_Register(index), scale);
  2148             __ move(T9, disp);
  2149             __ daddu(AT, AT, T9);
  2150             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2153       } else { // not use loongson isa
  2154         if (scale == 0) {
  2155           __ daddu(AT, as_Register(base), as_Register(index));
  2156         } else {
  2157           __ dsll(AT, as_Register(index), scale);
  2158           __ daddu(AT, as_Register(base), AT);
  2160         if( Assembler::is_simm16(disp) ) {
  2161           __ lh(as_Register(dst), AT, disp);
  2162         } else {
  2163           __ move(T9, disp);
  2164           __ daddu(AT, AT, T9);
  2165           __ lh(as_Register(dst), AT, 0);
  2168     } else { // index is 0
  2169       if ( UseLoongsonISA ) {
  2170         if ( Assembler::is_simm16(disp) ) {
  2171           __ lh(as_Register(dst), as_Register(base), disp);
  2172         } else {
  2173           __ move(T9, disp);
  2174           __ gslhx(as_Register(dst), as_Register(base), T9, 0);
  2176       } else { //not use loongson isa
  2177         if( Assembler::is_simm16(disp) ) {
  2178           __ lh(as_Register(dst), as_Register(base), disp);
  2179         } else {
  2180           __ move(T9, disp);
  2181           __ daddu(AT, as_Register(base), T9);
  2182           __ lh(as_Register(dst), AT, 0);
  2186   %}
  2188   // Load Char (16bit unsigned)
  2189   enc_class load_C_enc (mRegI dst, memory mem) %{
  2190     MacroAssembler _masm(&cbuf);
  2191     int  dst = $dst$$reg;
  2192     int  base = $mem$$base;
  2193     int  index = $mem$$index;
  2194     int  scale = $mem$$scale;
  2195     int  disp = $mem$$disp;
  2197     if( index != 0 ) {
  2198       if (scale == 0) {
  2199         __ daddu(AT, as_Register(base), as_Register(index));
  2200       } else {
  2201         __ dsll(AT, as_Register(index), scale);
  2202         __ daddu(AT, as_Register(base), AT);
  2204       if( Assembler::is_simm16(disp) ) {
  2205         __ lhu(as_Register(dst), AT, disp);
  2206       } else {
  2207         __ move(T9, disp);
  2208         __ addu(AT, AT, T9);
  2209         __ lhu(as_Register(dst), AT, 0);
  2211     } else {
  2212       if( Assembler::is_simm16(disp) ) {
  2213         __ lhu(as_Register(dst), as_Register(base), disp);
  2214       } else {
  2215         __ move(T9, disp);
  2216         __ daddu(AT, as_Register(base), T9);
  2217         __ lhu(as_Register(dst), AT, 0);
  2220   %}
  2222   // Store Char (16bit unsigned)
  2223   enc_class store_C_reg_enc (memory mem, mRegI src) %{
  2224     MacroAssembler _masm(&cbuf);
  2225     int  src = $src$$reg;
  2226     int  base = $mem$$base;
  2227     int  index = $mem$$index;
  2228     int  scale = $mem$$scale;
  2229     int  disp = $mem$$disp;
  2231     if( index != 0 ) {
  2232       if( Assembler::is_simm16(disp) ) {
  2233         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2234           if (scale == 0) {
  2235             __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
  2236           } else {
  2237             __ dsll(AT, as_Register(index), scale);
  2238             __ gsshx(as_Register(src), as_Register(base), AT, disp);
  2240         } else {
  2241           if (scale == 0) {
  2242             __ addu(AT, as_Register(base), as_Register(index));
  2243           } else {
  2244             __ dsll(AT, as_Register(index), scale);
  2245             __ addu(AT, as_Register(base), AT);
  2247           __ sh(as_Register(src), AT, disp);
  2249       } else {
  2250         if (scale == 0) {
  2251           __ addu(AT, as_Register(base), as_Register(index));
  2252         } else {
  2253           __ dsll(AT, as_Register(index), scale);
  2254           __ addu(AT, as_Register(base), AT);
  2256         __ move(T9, disp);
  2257         if( UseLoongsonISA ) {
  2258           __ gsshx(as_Register(src), AT, T9, 0);
  2259         } else {
  2260           __ addu(AT, AT, T9);
  2261           __ sh(as_Register(src), AT, 0);
  2264     } else {
  2265       if( Assembler::is_simm16(disp) ) {
  2266         __ sh(as_Register(src), as_Register(base), disp);
  2267       } else {
  2268         __ move(T9, disp);
  2269         if( UseLoongsonISA ) {
  2270           __ gsshx(as_Register(src), as_Register(base), T9, 0);
  2271         } else {
  2272           __ addu(AT, as_Register(base), T9);
  2273           __ sh(as_Register(src), AT, 0);
  2277   %}
  2279   enc_class store_C0_enc (memory mem) %{
  2280     MacroAssembler _masm(&cbuf);
  2281     int  base = $mem$$base;
  2282     int  index = $mem$$index;
  2283     int  scale = $mem$$scale;
  2284     int  disp = $mem$$disp;
  2286     if( index != 0 ) {
  2287       if( Assembler::is_simm16(disp) ) {
  2288         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2289           if (scale == 0) {
  2290             __ gsshx(R0, as_Register(base), as_Register(index), disp);
  2291           } else {
  2292             __ dsll(AT, as_Register(index), scale);
  2293             __ gsshx(R0, as_Register(base), AT, disp);
  2295         } else {
  2296           if (scale == 0) {
  2297             __ addu(AT, as_Register(base), as_Register(index));
  2298           } else {
  2299             __ dsll(AT, as_Register(index), scale);
  2300             __ addu(AT, as_Register(base), AT);
  2302           __ sh(R0, AT, disp);
  2304       } else {
  2305         if (scale == 0) {
  2306           __ addu(AT, as_Register(base), as_Register(index));
  2307         } else {
  2308           __ dsll(AT, as_Register(index), scale);
  2309           __ addu(AT, as_Register(base), AT);
  2311         __ move(T9, disp);
  2312         if( UseLoongsonISA ) {
  2313           __ gsshx(R0, AT, T9, 0);
  2314         } else {
  2315           __ addu(AT, AT, T9);
  2316           __ sh(R0, AT, 0);
  2319     } else {
  2320       if( Assembler::is_simm16(disp) ) {
  2321         __ sh(R0, as_Register(base), disp);
  2322       } else {
  2323         __ move(T9, disp);
  2324         if( UseLoongsonISA ) {
  2325           __ gsshx(R0, as_Register(base), T9, 0);
  2326         } else {
  2327           __ addu(AT, as_Register(base), T9);
  2328           __ sh(R0, AT, 0);
  2332   %}
  2334   enc_class load_I_enc (mRegI dst, memory mem) %{
  2335     MacroAssembler _masm(&cbuf);
  2336     int  dst = $dst$$reg;
  2337     int  base = $mem$$base;
  2338     int  index = $mem$$index;
  2339     int  scale = $mem$$scale;
  2340     int  disp = $mem$$disp;
  2342     if( index != 0 ) {
  2343       if( Assembler::is_simm16(disp) ) {
  2344         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2345           if (scale == 0) {
  2346             __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2347           } else {
  2348             __ dsll(AT, as_Register(index), scale);
  2349             __ gslwx(as_Register(dst), as_Register(base), AT, disp);
  2351         } else {
  2352           if (scale == 0) {
  2353             __ addu(AT, as_Register(base), as_Register(index));
  2354           } else {
  2355             __ dsll(AT, as_Register(index), scale);
  2356             __ addu(AT, as_Register(base), AT);
  2358           __ lw(as_Register(dst), AT, disp);
  2360       } else {
  2361         if (scale == 0) {
  2362           __ addu(AT, as_Register(base), as_Register(index));
  2363         } else {
  2364           __ dsll(AT, as_Register(index), scale);
  2365           __ addu(AT, as_Register(base), AT);
  2367         __ move(T9, disp);
  2368         if( UseLoongsonISA ) {
  2369           __ gslwx(as_Register(dst), AT, T9, 0);
  2370         } else {
  2371           __ addu(AT, AT, T9);
  2372           __ lw(as_Register(dst), AT, 0);
  2375     } else {
  2376       if( Assembler::is_simm16(disp) ) {
  2377         __ lw(as_Register(dst), as_Register(base), disp);
  2378       } else {
  2379         __ move(T9, disp);
  2380         if( UseLoongsonISA ) {
  2381           __ gslwx(as_Register(dst), as_Register(base), T9, 0);
  2382         } else {
  2383           __ addu(AT, as_Register(base), T9);
  2384           __ lw(as_Register(dst), AT, 0);
  2388   %}
  2390   enc_class store_I_reg_enc (memory mem, mRegI src) %{
  2391     MacroAssembler _masm(&cbuf);
  2392     int  src = $src$$reg;
  2393     int  base = $mem$$base;
  2394     int  index = $mem$$index;
  2395     int  scale = $mem$$scale;
  2396     int  disp = $mem$$disp;
  2398     if( index != 0 ) {
  2399       if( Assembler::is_simm16(disp) ) {
  2400         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2401           if (scale == 0) {
  2402             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2403           } else {
  2404             __ dsll(AT, as_Register(index), scale);
  2405             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2407         } else {
  2408           if (scale == 0) {
  2409             __ addu(AT, as_Register(base), as_Register(index));
  2410           } else {
  2411             __ dsll(AT, as_Register(index), scale);
  2412             __ addu(AT, as_Register(base), AT);
  2414           __ sw(as_Register(src), AT, disp);
  2416       } else {
  2417         if (scale == 0) {
  2418           __ addu(AT, as_Register(base), as_Register(index));
  2419         } else {
  2420           __ dsll(AT, as_Register(index), scale);
  2421           __ addu(AT, as_Register(base), AT);
  2423         __ move(T9, disp);
  2424         if( UseLoongsonISA ) {
  2425           __ gsswx(as_Register(src), AT, T9, 0);
  2426         } else {
  2427           __ addu(AT, AT, T9);
  2428           __ sw(as_Register(src), AT, 0);
  2431     } else {
  2432       if( Assembler::is_simm16(disp) ) {
  2433         __ sw(as_Register(src), as_Register(base), disp);
  2434       } else {
  2435         __ move(T9, disp);
  2436         if( UseLoongsonISA ) {
  2437           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2438         } else {
  2439           __ addu(AT, as_Register(base), T9);
  2440           __ sw(as_Register(src), AT, 0);
  2444   %}
  2446   enc_class store_I_immI_enc (memory mem, immI src) %{
  2447     MacroAssembler _masm(&cbuf);
  2448     int  base = $mem$$base;
  2449     int  index = $mem$$index;
  2450     int  scale = $mem$$scale;
  2451     int  disp = $mem$$disp;
  2452     int value = $src$$constant;
  2454     if( index != 0 ) {
  2455       if ( UseLoongsonISA ) {
  2456         if ( Assembler::is_simm(disp, 8) ) {
  2457           if ( scale == 0 ) {
  2458             if ( value == 0 ) {
  2459               __ gsswx(R0, as_Register(base), as_Register(index), disp);
  2460             } else {
  2461               __ move(T9, value);
  2462               __ gsswx(T9, as_Register(base), as_Register(index), disp);
  2464           } else {
  2465             __ dsll(AT, as_Register(index), scale);
  2466             if ( value == 0 ) {
  2467               __ gsswx(R0, as_Register(base), AT, disp);
  2468             } else {
  2469               __ move(T9, value);
  2470               __ gsswx(T9, as_Register(base), AT, disp);
  2473         } else if ( Assembler::is_simm16(disp) ) {
  2474           if ( scale == 0 ) {
  2475             __ daddu(AT, as_Register(base), as_Register(index));
  2476             if ( value == 0 ) {
  2477               __ sw(R0, AT, disp);
  2478             } else {
  2479               __ move(T9, value);
  2480               __ sw(T9, AT, disp);
  2482           } else {
  2483             __ dsll(AT, as_Register(index), scale);
  2484             __ daddu(AT, as_Register(base), AT);
  2485             if ( value == 0 ) {
  2486               __ sw(R0, AT, disp);
  2487             } else {
  2488               __ move(T9, value);
  2489               __ sw(T9, AT, disp);
  2492         } else {
  2493           if ( scale == 0 ) {
  2494             __ move(T9, disp);
  2495             __ daddu(AT, as_Register(index), T9);
  2496             if ( value ==0 ) {
  2497               __ gsswx(R0, as_Register(base), AT, 0);
  2498             } else {
  2499               __ move(T9, value);
  2500               __ gsswx(T9, as_Register(base), AT, 0);
  2502           } else {
  2503             __ dsll(AT, as_Register(index), scale);
  2504             __ move(T9, disp);
  2505             __ daddu(AT, AT, T9);
  2506             if ( value == 0 ) {
  2507               __ gsswx(R0, as_Register(base), AT, 0);
  2508             } else {
  2509               __ move(T9, value);
  2510               __ gsswx(T9, as_Register(base), AT, 0);
  2514       } else { //not use loongson isa
  2515         if (scale == 0) {
  2516           __ daddu(AT, as_Register(base), as_Register(index));
  2517         } else {
  2518           __ dsll(AT, as_Register(index), scale);
  2519           __ daddu(AT, as_Register(base), AT);
  2521         if( Assembler::is_simm16(disp) ) {
  2522           if (value == 0) {
  2523             __ sw(R0, AT, disp);
  2524           } else {
  2525             __ move(T9, value);
  2526             __ sw(T9, AT, disp);
  2528         } else {
  2529           if (value == 0) {
  2530             __ move(T9, disp);
  2531             __ daddu(AT, AT, T9);
  2532             __ sw(R0, AT, 0);
  2533           } else {
  2534             __ move(T9, disp);
  2535             __ daddu(AT, AT, T9);
  2536             __ move(T9, value);
  2537             __ sw(T9, AT, 0);
  2541     } else {
  2542       if ( UseLoongsonISA ) {
  2543         if ( Assembler::is_simm16(disp) ) {
  2544           if ( value == 0 ) {
  2545             __ sw(R0, as_Register(base), disp);
  2546           } else {
  2547             __ move(AT, value);
  2548             __ sw(AT, as_Register(base), disp);
  2550         } else {
  2551           __ move(T9, disp);
  2552           if ( value == 0 ) {
  2553             __ gsswx(R0, as_Register(base), T9, 0);
  2554           } else {
  2555             __ move(AT, value);
  2556             __ gsswx(AT, as_Register(base), T9, 0);
  2559       } else {
  2560         if( Assembler::is_simm16(disp) ) {
  2561           if (value == 0) {
  2562             __ sw(R0, as_Register(base), disp);
  2563           } else {
  2564             __ move(AT, value);
  2565             __ sw(AT, as_Register(base), disp);
  2567         } else {
  2568           if (value == 0) {
  2569             __ move(T9, disp);
  2570             __ daddu(AT, as_Register(base), T9);
  2571             __ sw(R0, AT, 0);
  2572           } else {
  2573             __ move(T9, disp);
  2574             __ daddu(AT, as_Register(base), T9);
  2575             __ move(T9, value);
  2576             __ sw(T9, AT, 0);
  2581   %}
  2583   enc_class load_N_enc (mRegN dst, memory mem) %{
  2584     MacroAssembler _masm(&cbuf);
  2585     int  dst = $dst$$reg;
  2586     int  base = $mem$$base;
  2587     int  index = $mem$$index;
  2588     int  scale = $mem$$scale;
  2589     int  disp = $mem$$disp;
  2590     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2591     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2593     if( index != 0 ) {
  2594       if (scale == 0) {
  2595         __ daddu(AT, as_Register(base), as_Register(index));
  2596       } else {
  2597         __ dsll(AT, as_Register(index), scale);
  2598         __ daddu(AT, as_Register(base), AT);
  2600       if( Assembler::is_simm16(disp) ) {
  2601         __ lwu(as_Register(dst), AT, disp);
  2602       } else {
  2603         __ set64(T9, disp);
  2604         __ daddu(AT, AT, T9);
  2605         __ lwu(as_Register(dst), AT, 0);
  2607     } else {
  2608       if( Assembler::is_simm16(disp) ) {
  2609         __ lwu(as_Register(dst), as_Register(base), disp);
  2610       } else {
  2611         __ set64(T9, disp);
  2612         __ daddu(AT, as_Register(base), T9);
  2613         __ lwu(as_Register(dst), AT, 0);
  2616   %}
  2619   enc_class load_P_enc (mRegP dst, memory mem) %{
  2620     MacroAssembler _masm(&cbuf);
  2621     int  dst = $dst$$reg;
  2622     int  base = $mem$$base;
  2623     int  index = $mem$$index;
  2624     int  scale = $mem$$scale;
  2625     int  disp = $mem$$disp;
  2626     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2627     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2629     if( index != 0 ) {
  2630       if ( UseLoongsonISA ) {
  2631         if ( Assembler::is_simm(disp, 8) ) {
  2632           if ( scale != 0 ) {
  2633             __ dsll(AT, as_Register(index), scale);
  2634             __ gsldx(as_Register(dst), as_Register(base), AT, disp);
  2635           } else {
  2636             __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2638         } else if ( Assembler::is_simm16(disp) ){
  2639           if ( scale != 0 ) {
  2640             __ dsll(AT, as_Register(index), scale);
  2641             __ daddu(AT, AT, as_Register(base));
  2642           } else {
  2643             __ daddu(AT, as_Register(index), as_Register(base));
  2645           __ ld(as_Register(dst), AT, disp);
  2646         } else {
  2647           if ( scale != 0 ) {
  2648             __ dsll(AT, as_Register(index), scale);
  2649             __ move(T9, disp);
  2650             __ daddu(AT, AT, T9);
  2651           } else {
  2652             __ move(T9, disp);
  2653             __ daddu(AT, as_Register(index), T9);
  2655           __ gsldx(as_Register(dst), as_Register(base), AT, 0);
  2657       } else { //not use loongson isa
  2658         if (scale == 0) {
  2659           __ daddu(AT, as_Register(base), as_Register(index));
  2660         } else {
  2661           __ dsll(AT, as_Register(index), scale);
  2662           __ daddu(AT, as_Register(base), AT);
  2664         if( Assembler::is_simm16(disp) ) {
  2665           __ ld(as_Register(dst), AT, disp);
  2666         } else {
  2667           __ set64(T9, disp);
  2668           __ daddu(AT, AT, T9);
  2669           __ ld(as_Register(dst), AT, 0);
  2672     } else {
  2673       if ( UseLoongsonISA ) {
  2674         if ( Assembler::is_simm16(disp) ){
  2675           __ ld(as_Register(dst), as_Register(base), disp);
  2676         } else {
  2677           __ set64(T9, disp);
  2678           __ gsldx(as_Register(dst), as_Register(base), T9, 0);
  2680       } else { //not use loongson isa
  2681         if( Assembler::is_simm16(disp) ) {
  2682           __ ld(as_Register(dst), as_Register(base), disp);
  2683         } else {
  2684           __ set64(T9, disp);
  2685           __ daddu(AT, as_Register(base), T9);
  2686           __ ld(as_Register(dst), AT, 0);
  2690   %}
  2692   enc_class store_P_reg_enc (memory mem, mRegP src) %{
  2693     MacroAssembler _masm(&cbuf);
  2694     int  src = $src$$reg;
  2695     int  base = $mem$$base;
  2696     int  index = $mem$$index;
  2697     int  scale = $mem$$scale;
  2698     int  disp = $mem$$disp;
  2700     if( index != 0 ) {
  2701       if ( UseLoongsonISA ){
  2702         if ( Assembler::is_simm(disp, 8) ) {
  2703           if ( scale == 0 ) {
  2704             __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
  2705           } else {
  2706             __ dsll(AT, as_Register(index), scale);
  2707             __ gssdx(as_Register(src), as_Register(base), AT, disp);
  2709         } else if ( Assembler::is_simm16(disp) ) {
  2710           if ( scale == 0 ) {
  2711             __ daddu(AT, as_Register(base), as_Register(index));
  2712           } else {
  2713             __ dsll(AT, as_Register(index), scale);
  2714             __ daddu(AT, as_Register(base), AT);
  2716           __ sd(as_Register(src), AT, disp);
  2717         } else {
  2718           if ( scale == 0 ) {
  2719             __ move(T9, disp);
  2720             __ daddu(AT, as_Register(index), T9);
  2721           } else {
  2722             __ dsll(AT, as_Register(index), scale);
  2723             __ move(T9, disp);
  2724             __ daddu(AT, AT, T9);
  2726           __ gssdx(as_Register(src), as_Register(base), AT, 0);
  2728       } else { //not use loongson isa
  2729         if (scale == 0) {
  2730           __ daddu(AT, as_Register(base), as_Register(index));
  2731         } else {
  2732           __ dsll(AT, as_Register(index), scale);
  2733           __ daddu(AT, as_Register(base), AT);
  2735         if( Assembler::is_simm16(disp) ) {
  2736           __ sd(as_Register(src), AT, disp);
  2737         } else {
  2738           __ move(T9, disp);
  2739           __ daddu(AT, AT, T9);
  2740           __ sd(as_Register(src), AT, 0);
  2743     } else {
  2744       if ( UseLoongsonISA ) {
  2745         if ( Assembler::is_simm16(disp) ) {
  2746           __ sd(as_Register(src), as_Register(base), disp);
  2747         } else {
  2748           __ move(T9, disp);
  2749           __ gssdx(as_Register(src), as_Register(base), T9, 0);
  2751       } else {
  2752         if( Assembler::is_simm16(disp) ) {
  2753           __ sd(as_Register(src), as_Register(base), disp);
  2754         } else {
  2755           __ move(T9, disp);
  2756           __ daddu(AT, as_Register(base), T9);
  2757           __ sd(as_Register(src), AT, 0);
  2761   %}
  2763   enc_class store_N_reg_enc (memory mem, mRegN src) %{
  2764     MacroAssembler _masm(&cbuf);
  2765     int  src = $src$$reg;
  2766     int  base = $mem$$base;
  2767     int  index = $mem$$index;
  2768     int  scale = $mem$$scale;
  2769     int  disp = $mem$$disp;
  2771     if( index != 0 ) {
  2772       if ( UseLoongsonISA ){
  2773         if ( Assembler::is_simm(disp, 8) ) {
  2774           if ( scale == 0 ) {
  2775             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2776           } else {
  2777             __ dsll(AT, as_Register(index), scale);
  2778             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2780         } else if ( Assembler::is_simm16(disp) ) {
  2781           if ( scale == 0 ) {
  2782             __ daddu(AT, as_Register(base), as_Register(index));
  2783           } else {
  2784             __ dsll(AT, as_Register(index), scale);
  2785             __ daddu(AT, as_Register(base), AT);
  2787           __ sw(as_Register(src), AT, disp);
  2788         } else {
  2789           if ( scale == 0 ) {
  2790             __ move(T9, disp);
  2791             __ daddu(AT, as_Register(index), T9);
  2792           } else {
  2793             __ dsll(AT, as_Register(index), scale);
  2794             __ move(T9, disp);
  2795             __ daddu(AT, AT, T9);
  2797           __ gsswx(as_Register(src), as_Register(base), AT, 0);
  2799       } else { //not use loongson isa
  2800         if (scale == 0) {
  2801           __ daddu(AT, as_Register(base), as_Register(index));
  2802         } else {
  2803           __ dsll(AT, as_Register(index), scale);
  2804           __ daddu(AT, as_Register(base), AT);
  2806         if( Assembler::is_simm16(disp) ) {
  2807           __ sw(as_Register(src), AT, disp);
  2808         } else {
  2809           __ move(T9, disp);
  2810           __ daddu(AT, AT, T9);
  2811           __ sw(as_Register(src), AT, 0);
  2814     } else {
  2815       if ( UseLoongsonISA ) {
  2816         if ( Assembler::is_simm16(disp) ) {
  2817           __ sw(as_Register(src), as_Register(base), disp);
  2818         } else {
  2819           __ move(T9, disp);
  2820           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2822       } else {
  2823         if( Assembler::is_simm16(disp) ) {
  2824           __ sw(as_Register(src), as_Register(base), disp);
  2825         } else {
  2826           __ move(T9, disp);
  2827           __ daddu(AT, as_Register(base), T9);
  2828           __ sw(as_Register(src), AT, 0);
  2832   %}
  2834   enc_class store_P_immP0_enc (memory mem) %{
  2835     MacroAssembler _masm(&cbuf);
  2836     int  base = $mem$$base;
  2837     int  index = $mem$$index;
  2838     int  scale = $mem$$scale;
  2839     int  disp = $mem$$disp;
  2841     if( index != 0 ) {
  2842       if (scale == 0) {
  2843         if( Assembler::is_simm16(disp) ) {
  2844           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2845             __ gssdx(R0, as_Register(base), as_Register(index), disp);
  2846           } else {
  2847             __ daddu(AT, as_Register(base), as_Register(index));
  2848             __ sd(R0, AT, disp);
  2850         } else {
  2851           __ daddu(AT, as_Register(base), as_Register(index));
  2852           __ move(T9, disp);
  2853           if(UseLoongsonISA) {
  2854             __ gssdx(R0, AT, T9, 0);
  2855           } else {
  2856             __ daddu(AT, AT, T9);
  2857             __ sd(R0, AT, 0);
  2860       } else {
  2861         __ dsll(AT, as_Register(index), scale);
  2862         if( Assembler::is_simm16(disp) ) {
  2863           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2864             __ gssdx(R0, as_Register(base), AT, disp);
  2865           } else {
  2866             __ daddu(AT, as_Register(base), AT);
  2867             __ sd(R0, AT, disp);
  2869         } else {
  2870           __ daddu(AT, as_Register(base), AT);
  2871           __ move(T9, disp);
  2872           if (UseLoongsonISA) {
  2873             __ gssdx(R0, AT, T9, 0);
  2874           } else {
  2875             __ daddu(AT, AT, T9);
  2876             __ sd(R0, AT, 0);
  2880     } else {
  2881       if( Assembler::is_simm16(disp) ) {
  2882         __ sd(R0, as_Register(base), disp);
  2883       } else {
  2884         __ move(T9, disp);
  2885         if (UseLoongsonISA) {
  2886           __ gssdx(R0, as_Register(base), T9, 0);
  2887         } else {
  2888           __ daddu(AT, as_Register(base), T9);
  2889           __ sd(R0, AT, 0);
  2893   %}
  2895   enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
  2896     MacroAssembler _masm(&cbuf);
  2897     int  base = $mem$$base;
  2898     int  index = $mem$$index;
  2899     int  scale = $mem$$scale;
  2900     int  disp = $mem$$disp;
  2902     if(index!=0){
  2903       if (scale == 0) {
  2904         __ daddu(AT, as_Register(base), as_Register(index));
  2905       } else {
  2906         __ dsll(AT, as_Register(index), scale);
  2907         __ daddu(AT, as_Register(base), AT);
  2910       if( Assembler::is_simm16(disp) ) {
  2911         __ sw(R0, AT, disp);
  2912       } else {
  2913         __ move(T9, disp);
  2914         __ daddu(AT, AT, T9);
  2915         __ sw(R0, AT, 0);
  2917     } else {
  2918       if( Assembler::is_simm16(disp) ) {
  2919         __ sw(R0, as_Register(base), disp);
  2920       } else {
  2921         __ move(T9, disp);
  2922         __ daddu(AT, as_Register(base), T9);
  2923         __ sw(R0, AT, 0);
  2926   %}
  2928   enc_class load_L_enc (mRegL dst, memory mem) %{
  2929     MacroAssembler _masm(&cbuf);
  2930     int  base = $mem$$base;
  2931     int  index = $mem$$index;
  2932     int  scale = $mem$$scale;
  2933     int  disp = $mem$$disp;
  2934     Register  dst_reg = as_Register($dst$$reg);
  2936     if( index != 0 ) {
  2937       if (scale == 0) {
  2938         __ daddu(AT, as_Register(base), as_Register(index));
  2939       } else {
  2940         __ dsll(AT, as_Register(index), scale);
  2941         __ daddu(AT, as_Register(base), AT);
  2943       if( Assembler::is_simm16(disp) ) {
  2944         __ ld(dst_reg, AT, disp);
  2945       } else {
  2946         __ move(T9, disp);
  2947         __ daddu(AT, AT, T9);
  2948         __ ld(dst_reg, AT, 0);
  2950     } else {
  2951       if( Assembler::is_simm16(disp) ) {
  2952         __ ld(dst_reg, as_Register(base), disp);
  2953       } else {
  2954         __ move(T9, disp);
  2955         __ daddu(AT, as_Register(base), T9);
  2956         __ ld(dst_reg, AT, 0);
  2959   %}
  2961   enc_class store_L_reg_enc (memory mem, mRegL src) %{
  2962     MacroAssembler _masm(&cbuf);
  2963     int  base = $mem$$base;
  2964     int  index = $mem$$index;
  2965     int  scale = $mem$$scale;
  2966     int  disp = $mem$$disp;
  2967     Register  src_reg = as_Register($src$$reg);
  2969     if( index != 0 ) {
  2970       if (scale == 0) {
  2971         __ daddu(AT, as_Register(base), as_Register(index));
  2972       } else {
  2973         __ dsll(AT, as_Register(index), scale);
  2974         __ daddu(AT, as_Register(base), AT);
  2976       if( Assembler::is_simm16(disp) ) {
  2977         __ sd(src_reg, AT, disp);
  2978       } else {
  2979         __ move(T9, disp);
  2980         __ daddu(AT, AT, T9);
  2981         __ sd(src_reg, AT, 0);
  2983     } else {
  2984       if( Assembler::is_simm16(disp) ) {
  2985         __ sd(src_reg, as_Register(base), disp);
  2986       } else {
  2987         __ move(T9, disp);
  2988         __ daddu(AT, as_Register(base), T9);
  2989         __ sd(src_reg, AT, 0);
  2992   %}
  2994   enc_class store_L_immL0_enc (memory mem, immL0 src) %{
  2995     MacroAssembler _masm(&cbuf);
  2996     int  base = $mem$$base;
  2997     int  index = $mem$$index;
  2998     int  scale = $mem$$scale;
  2999     int  disp = $mem$$disp;
  3001     if( index != 0 ) {
  3002       if (scale == 0) {
  3003         __ daddu(AT, as_Register(base), as_Register(index));
  3004       } else {
  3005         __ dsll(AT, as_Register(index), scale);
  3006         __ daddu(AT, as_Register(base), AT);
  3008       if( Assembler::is_simm16(disp) ) {
  3009         __ sd(R0, AT, disp);
  3010       } else {
  3011         __ move(T9, disp);
  3012         __ addu(AT, AT, T9);
  3013         __ sd(R0, AT, 0);
  3015     } else {
  3016       if( Assembler::is_simm16(disp) ) {
  3017         __ sd(R0, as_Register(base), disp);
  3018       } else {
  3019         __ move(T9, disp);
  3020         __ addu(AT, as_Register(base), T9);
  3021         __ sd(R0, AT, 0);
  3024   %}
  3026   enc_class store_L_immL_enc (memory mem, immL src) %{
  3027     MacroAssembler _masm(&cbuf);
  3028     int  base = $mem$$base;
  3029     int  index = $mem$$index;
  3030     int  scale = $mem$$scale;
  3031     int  disp = $mem$$disp;
  3032     long  imm = $src$$constant;
  3034     if( index != 0 ) {
  3035       if (scale == 0) {
  3036         __ daddu(AT, as_Register(base), as_Register(index));
  3037       } else {
  3038         __ dsll(AT, as_Register(index), scale);
  3039         __ daddu(AT, as_Register(base), AT);
  3041       if( Assembler::is_simm16(disp) ) {
  3042         __ set64(T9, imm);
  3043         __ sd(T9, AT, disp);
  3044       } else {
  3045         __ move(T9, disp);
  3046         __ addu(AT, AT, T9);
  3047         __ set64(T9, imm);
  3048         __ sd(T9, AT, 0);
  3050     } else {
  3051       if( Assembler::is_simm16(disp) ) {
  3052         __ move(AT, as_Register(base));
  3053         __ set64(T9, imm);
  3054         __ sd(T9, AT, disp);
  3055       } else {
  3056         __ move(T9, disp);
  3057         __ addu(AT, as_Register(base), T9);
  3058         __ set64(T9, imm);
  3059         __ sd(T9, AT, 0);
  3062   %}
  3064   enc_class load_F_enc (regF dst, memory mem) %{
  3065     MacroAssembler _masm(&cbuf);
  3066     int  base = $mem$$base;
  3067     int  index = $mem$$index;
  3068     int  scale = $mem$$scale;
  3069     int  disp = $mem$$disp;
  3070     FloatRegister dst = $dst$$FloatRegister;
  3072     if( index != 0 ) {
  3073       if( Assembler::is_simm16(disp) ) {
  3074         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3075           if (scale == 0) {
  3076             __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
  3077           } else {
  3078             __ dsll(AT, as_Register(index), scale);
  3079             __ gslwxc1(dst, as_Register(base), AT, disp);
  3081         } else {
  3082           if (scale == 0) {
  3083             __ daddu(AT, as_Register(base), as_Register(index));
  3084           } else {
  3085             __ dsll(AT, as_Register(index), scale);
  3086             __ daddu(AT, as_Register(base), AT);
  3088           __ lwc1(dst, AT, disp);
  3090       } else {
  3091         if (scale == 0) {
  3092           __ daddu(AT, as_Register(base), as_Register(index));
  3093         } else {
  3094           __ dsll(AT, as_Register(index), scale);
  3095           __ daddu(AT, as_Register(base), AT);
  3097         __ move(T9, disp);
  3098         if( UseLoongsonISA ) {
  3099           __ gslwxc1(dst, AT, T9, 0);
  3100         } else {
  3101           __ daddu(AT, AT, T9);
  3102           __ lwc1(dst, AT, 0);
  3105     } else {
  3106       if( Assembler::is_simm16(disp) ) {
  3107         __ lwc1(dst, as_Register(base), disp);
  3108       } else {
  3109         __ move(T9, disp);
  3110         if( UseLoongsonISA ) {
  3111           __ gslwxc1(dst, as_Register(base), T9, 0);
  3112         } else {
  3113           __ daddu(AT, as_Register(base), T9);
  3114           __ lwc1(dst, AT, 0);
  3118   %}
  3120   enc_class store_F_reg_enc (memory mem, regF src) %{
  3121     MacroAssembler _masm(&cbuf);
  3122     int  base = $mem$$base;
  3123     int  index = $mem$$index;
  3124     int  scale = $mem$$scale;
  3125     int  disp = $mem$$disp;
  3126     FloatRegister src = $src$$FloatRegister;
  3128     if( index != 0 ) {
  3129       if( Assembler::is_simm16(disp) ) {
  3130         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3131           if (scale == 0) {
  3132             __ gsswxc1(src, as_Register(base), as_Register(index), disp);
  3133           } else {
  3134             __ dsll(AT, as_Register(index), scale);
  3135             __ gsswxc1(src, as_Register(base), AT, disp);
  3137         } else {
  3138           if (scale == 0) {
  3139             __ daddu(AT, as_Register(base), as_Register(index));
  3140           } else {
  3141             __ dsll(AT, as_Register(index), scale);
  3142             __ daddu(AT, as_Register(base), AT);
  3144           __ swc1(src, AT, disp);
  3146       } else {
  3147         if (scale == 0) {
  3148           __ daddu(AT, as_Register(base), as_Register(index));
  3149         } else {
  3150           __ dsll(AT, as_Register(index), scale);
  3151           __ daddu(AT, as_Register(base), AT);
  3153         __ move(T9, disp);
  3154         if( UseLoongsonISA ) {
  3155           __ gsswxc1(src, AT, T9, 0);
  3156         } else {
  3157           __ daddu(AT, AT, T9);
  3158           __ swc1(src, AT, 0);
  3161     } else {
  3162       if( Assembler::is_simm16(disp) ) {
  3163         __ swc1(src, as_Register(base), disp);
  3164       } else {
  3165         __ move(T9, disp);
  3166         if( UseLoongsonISA ) {
  3167           __ gsswxc1(src, as_Register(base), T9, 0);
  3168         } else {
  3169           __ daddu(AT, as_Register(base), T9);
  3170           __ swc1(src, AT, 0);
  3174   %}
  3176   enc_class load_D_enc (regD dst, memory mem) %{
  3177     MacroAssembler _masm(&cbuf);
  3178     int  base = $mem$$base;
  3179     int  index = $mem$$index;
  3180     int  scale = $mem$$scale;
  3181     int  disp = $mem$$disp;
  3182     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
  3184     if( index != 0 ) {
  3185       if( Assembler::is_simm16(disp) ) {
  3186         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3187           if (scale == 0) {
  3188             __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
  3189           } else {
  3190             __ dsll(AT, as_Register(index), scale);
  3191             __ gsldxc1(dst_reg, as_Register(base), AT, disp);
  3193         } else {
  3194           if (scale == 0) {
  3195             __ daddu(AT, as_Register(base), as_Register(index));
  3196           } else {
  3197             __ dsll(AT, as_Register(index), scale);
  3198             __ daddu(AT, as_Register(base), AT);
  3200           __ ldc1(dst_reg, AT, disp);
  3202       } else {
  3203         if (scale == 0) {
  3204           __ daddu(AT, as_Register(base), as_Register(index));
  3205         } else {
  3206           __ dsll(AT, as_Register(index), scale);
  3207           __ daddu(AT, as_Register(base), AT);
  3209         __ move(T9, disp);
  3210         if( UseLoongsonISA ) {
  3211           __ gsldxc1(dst_reg, AT, T9, 0);
  3212         } else {
  3213           __ addu(AT, AT, T9);
  3214           __ ldc1(dst_reg, AT, 0);
  3217     } else {
  3218       if( Assembler::is_simm16(disp) ) {
  3219         __ ldc1(dst_reg, as_Register(base), disp);
  3220       } else {
  3221         __ move(T9, disp);
  3222         if( UseLoongsonISA ) {
  3223           __ gsldxc1(dst_reg, as_Register(base), T9, 0);
  3224         } else {
  3225           __ addu(AT, as_Register(base), T9);
  3226           __ ldc1(dst_reg, AT, 0);
  3230   %}
  3232   enc_class store_D_reg_enc (memory mem, regD src) %{
  3233     MacroAssembler _masm(&cbuf);
  3234     int  base = $mem$$base;
  3235     int  index = $mem$$index;
  3236     int  scale = $mem$$scale;
  3237     int  disp = $mem$$disp;
  3238     FloatRegister src_reg = as_FloatRegister($src$$reg);
  3240     if( index != 0 ) {
  3241       if( Assembler::is_simm16(disp) ) {
  3242         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3243           if (scale == 0) {
  3244             __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
  3245           } else {
  3246             __ dsll(AT, as_Register(index), scale);
  3247             __ gssdxc1(src_reg, as_Register(base), AT, disp);
  3249         } else {
  3250           if (scale == 0) {
  3251             __ daddu(AT, as_Register(base), as_Register(index));
  3252           } else {
  3253             __ dsll(AT, as_Register(index), scale);
  3254             __ daddu(AT, as_Register(base), AT);
  3256           __ sdc1(src_reg, AT, disp);
  3258       } else {
  3259         if (scale == 0) {
  3260           __ daddu(AT, as_Register(base), as_Register(index));
  3261         } else {
  3262           __ dsll(AT, as_Register(index), scale);
  3263           __ daddu(AT, as_Register(base), AT);
  3265         __ move(T9, disp);
  3266         if( UseLoongsonISA ) {
  3267           __ gssdxc1(src_reg, AT, T9, 0);
  3268         } else {
  3269           __ addu(AT, AT, T9);
  3270           __ sdc1(src_reg, AT, 0);
  3273     } else {
  3274       if( Assembler::is_simm16(disp) ) {
  3275         __ sdc1(src_reg, as_Register(base), disp);
  3276       } else {
  3277         __ move(T9, disp);
  3278         if( UseLoongsonISA ) {
  3279           __ gssdxc1(src_reg, as_Register(base), T9, 0);
  3280         } else {
  3281           __ addu(AT, as_Register(base), T9);
  3282           __ sdc1(src_reg, AT, 0);
  3286   %}
  3288   enc_class Java_To_Runtime (method meth) %{    // CALL Java_To_Runtime, Java_To_Runtime_Leaf
  3289     MacroAssembler _masm(&cbuf);
  3290     // This is the instruction starting address for relocation info.
  3291     __ block_comment("Java_To_Runtime");
  3292     cbuf.set_insts_mark();
  3293     __ relocate(relocInfo::runtime_call_type);
  3295     __ patchable_call((address)$meth$$method);
  3296   %}
  3298   enc_class Java_Static_Call (method meth) %{    // JAVA STATIC CALL
  3299     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
  3300     // who we intended to call.
  3301     MacroAssembler _masm(&cbuf);
  3302     cbuf.set_insts_mark();
  3304     if ( !_method ) {
  3305       __ relocate(relocInfo::runtime_call_type);
  3306     } else if(_optimized_virtual) {
  3307       __ relocate(relocInfo::opt_virtual_call_type);
  3308     } else {
  3309       __ relocate(relocInfo::static_call_type);
  3312     __ patchable_call((address)($meth$$method));
  3313     if( _method ) {  // Emit stub for static call
  3314       emit_java_to_interp(cbuf);
  3316   %}
  3319   /*
  3320    * [Ref: LIR_Assembler::ic_call() ]
  3321    */
  3322   enc_class Java_Dynamic_Call (method meth) %{    // JAVA DYNAMIC CALL
  3323     MacroAssembler _masm(&cbuf);
  3324     __ block_comment("Java_Dynamic_Call");
  3325     __ ic_call((address)$meth$$method);
  3326   %}
  3329   enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
  3330     Register flags = $cr$$Register;
  3331     Label  L;
  3333     MacroAssembler _masm(&cbuf);
  3335     __ addu(flags, R0, R0);
  3336     __ beq(AT, R0, L);
  3337     __ delayed()->nop();
  3338     __ move(flags, 0xFFFFFFFF);
  3339     __ bind(L);
  3340   %}
  3342   enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
  3343     Register result = $result$$Register;
  3344     Register sub    = $sub$$Register;
  3345     Register super  = $super$$Register;
  3346     Register length = $tmp$$Register;
  3347     Register tmp    = T9;
  3348     Label miss;
  3350     // result may be the same as sub
  3351     //    47c   B40: #    B21 B41 <- B20  Freq: 0.155379
  3352     //    47c     partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
  3353     //    4bc     mov   S2, NULL #@loadConP
  3354     //    4c0     beq   S1, S2, B21 #@branchConP  P=0.999999 C=-1.000000
  3355     //
  3356     MacroAssembler _masm(&cbuf);
  3357     Label done;
  3358     __ check_klass_subtype_slow_path(sub, super, length, tmp,
  3359         NULL, &miss,
  3360         /*set_cond_codes:*/ true);
  3361     // Refer to X86_64's RDI
  3362     __ move(result, 0);
  3363     __ b(done);
  3364     __ delayed()->nop();
  3366     __ bind(miss);
  3367     __ move(result, 1);
  3368     __ bind(done);
  3369   %}
  3371 %}
  3374 //---------MIPS FRAME--------------------------------------------------------------
  3375 // Definition of frame structure and management information.
  3376 //
  3377 //  S T A C K   L A Y O U T    Allocators stack-slot number
  3378 //                             |   (to get allocators register number
  3379 //  G  Owned by    |        |  v    add SharedInfo::stack0)
  3380 //  r   CALLER     |        |
  3381 //  o     |        +--------+      pad to even-align allocators stack-slot
  3382 //  w     V        |  pad0  |        numbers; owned by CALLER
  3383 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
  3384 //  h     ^        |   in   |  5
  3385 //        |        |  args  |  4   Holes in incoming args owned by SELF
  3386 //  |     |    old |        |  3
  3387 //  |     |     SP-+--------+----> Matcher::_old_SP, even aligned
  3388 //  v     |        |  ret   |  3   return address
  3389 //     Owned by    +--------+
  3390 //      Self       |  pad2  |  2   pad to align old SP
  3391 //        |        +--------+  1
  3392 //        |        | locks  |  0
  3393 //        |        +--------+----> SharedInfo::stack0, even aligned
  3394 //        |        |  pad1  | 11   pad to align new SP
  3395 //        |        +--------+
  3396 //        |        |        | 10
  3397 //        |        | spills |  9   spills
  3398 //        V        |        |  8   (pad0 slot for callee)
  3399 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
  3400 //        ^        |  out   |  7
  3401 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
  3402 //   Owned by  new |        |
  3403 //    Callee    SP-+--------+----> Matcher::_new_SP, even aligned
  3404 //                  |        |
  3405 //
  3406 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
  3407 //         known from SELF's arguments and the Java calling convention.
  3408 //         Region 6-7 is determined per call site.
  3409 // Note 2: If the calling convention leaves holes in the incoming argument
  3410 //         area, those holes are owned by SELF.  Holes in the outgoing area
  3411 //         are owned by the CALLEE.  Holes should not be nessecary in the
  3412 //         incoming area, as the Java calling convention is completely under
  3413 //         the control of the AD file.  Doubles can be sorted and packed to
  3414 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
  3415 //         varargs C calling conventions.
  3416 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
  3417 //         even aligned with pad0 as needed.
  3418 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
  3419 //         region 6-11 is even aligned; it may be padded out more so that
  3420 //         the region from SP to FP meets the minimum stack alignment.
  3421 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
  3422 //         alignment.  Region 11, pad1, may be dynamically extended so that
  3423 //         SP meets the minimum alignment.
  3426 frame %{
  3428   stack_direction(TOWARDS_LOW);
  3430   // These two registers define part of the calling convention
  3431   // between compiled code and the interpreter.
  3432   // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
  3433   // for more information.
  3435   inline_cache_reg(T1);                // Inline Cache Register
  3436   interpreter_method_oop_reg(S3);      // Method Oop Register when calling interpreter
  3438   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
  3439   cisc_spilling_operand_name(indOffset32);
  3441   // Number of stack slots consumed by locking an object
  3442   // generate Compile::sync_stack_slots
  3443 #ifdef _LP64
  3444   sync_stack_slots(2);
  3445 #else
  3446   sync_stack_slots(1);
  3447 #endif
  3449   frame_pointer(SP);
  3451   // Interpreter stores its frame pointer in a register which is
  3452   // stored to the stack by I2CAdaptors.
  3453   // I2CAdaptors convert from interpreted java to compiled java.
  3455   interpreter_frame_pointer(FP);
  3457   // generate Matcher::stack_alignment
  3458   stack_alignment(StackAlignmentInBytes);  //wordSize = sizeof(char*);
  3460   // Number of stack slots between incoming argument block and the start of
  3461   // a new frame.  The PROLOG must add this many slots to the stack.  The
  3462   // EPILOG must remove this many slots.  Intel needs one slot for
  3463   // return address.
  3464   // generate Matcher::in_preserve_stack_slots
  3465   //in_preserve_stack_slots(VerifyStackAtCalls + 2);  //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
  3466   in_preserve_stack_slots(4);  //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
  3468   // Number of outgoing stack slots killed above the out_preserve_stack_slots
  3469   // for calls to C.  Supports the var-args backing area for register parms.
  3470   varargs_C_out_slots_killed(0);
  3472   // The after-PROLOG location of the return address.  Location of
  3473   // return address specifies a type (REG or STACK) and a number
  3474   // representing the register number (i.e. - use a register name) or
  3475   // stack slot.
  3476   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
  3477   // Otherwise, it is above the locks and verification slot and alignment word
  3478   //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
  3479   return_addr(REG RA);
  3481   // Body of function which returns an integer array locating
  3482   // arguments either in registers or in stack slots.  Passed an array
  3483   // of ideal registers called "sig" and a "length" count.  Stack-slot
  3484   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  3485   // arguments for a CALLEE.  Incoming stack arguments are
  3486   // automatically biased by the preserve_stack_slots field above.
  3489   // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
  3490   // StartNode::calling_convention call this.
  3491   calling_convention %{
  3492     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
  3493   %}
  3498   // Body of function which returns an integer array locating
  3499   // arguments either in registers or in stack slots.  Passed an array
  3500   // of ideal registers called "sig" and a "length" count.  Stack-slot
  3501   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  3502   // arguments for a CALLEE.  Incoming stack arguments are
  3503   // automatically biased by the preserve_stack_slots field above.
  3506   // SEE CallRuntimeNode::calling_convention for more information.
  3507   c_calling_convention %{
  3508    (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
  3509   %}
  3512   // Location of C & interpreter return values
  3513   // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
  3514   // SEE Matcher::match.
  3515   c_return_value %{
  3516     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  3517                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  3518     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,    V0_num };
  3519     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,  V0_H_num };
  3520     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  3521   %}
  3523   // Location of return values
  3524   // register(s) contain(s) return value for Op_StartC2I and Op_Start.
  3525   // SEE Matcher::match.
  3527   return_value %{
  3528     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  3529                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  3530     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,     V0_num };
  3531     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,   V0_H_num};
  3532     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  3533   %}
  3535 %}
  3537 //----------ATTRIBUTES---------------------------------------------------------
  3538 //----------Operand Attributes-------------------------------------------------
  3539 op_attrib op_cost(0);        // Required cost attribute
  3541 //----------Instruction Attributes---------------------------------------------
  3542 ins_attrib ins_cost(100);       // Required cost attribute
  3543 ins_attrib ins_size(32);         // Required size attribute (in bits)
  3544 ins_attrib ins_pc_relative(0);  // Required PC Relative flag
  3545 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
  3546                                 // non-matching short branch variant of some
  3547                                                             // long branch?
  3548 ins_attrib ins_alignment(4);    // Required alignment attribute (must be a power of 2)
  3549                                 // specifies the alignment that some part of the instruction (not
  3550                                 // necessarily the start) requires.  If > 1, a compute_padding()
  3551                                 // function must be provided for the instruction
  3553 //----------OPERANDS-----------------------------------------------------------
  3554 // Operand definitions must precede instruction definitions for correct parsing
  3555 // in the ADLC because operands constitute user defined types which are used in
  3556 // instruction definitions.
  3558 // Vectors
  3559 operand vecD() %{
  3560   constraint(ALLOC_IN_RC(dbl_reg));
  3561   match(VecD);
  3563   format %{ %}
  3564   interface(REG_INTER);
  3565 %}
  3567 // Flags register, used as output of compare instructions
  3568 operand FlagsReg() %{
  3569   constraint(ALLOC_IN_RC(mips_flags));
  3570   match(RegFlags);
  3572   format %{ "AT" %}
  3573   interface(REG_INTER);
  3574 %}
  3576 //----------Simple Operands----------------------------------------------------
  3577 //TODO: Should we need to define some more special immediate number ?
  3578 // Immediate Operands
  3579 // Integer Immediate
  3580 operand immI() %{
  3581   match(ConI);
  3582   //TODO: should not match immI8 here LEE
  3583   match(immI8);
  3585   op_cost(20);
  3586   format %{ %}
  3587   interface(CONST_INTER);
  3588 %}
  3590 // Long Immediate 8-bit
  3591 operand immL8()
  3592 %{
  3593   predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
  3594   match(ConL);
  3596   op_cost(5);
  3597   format %{ %}
  3598   interface(CONST_INTER);
  3599 %}
  3601 // Constant for test vs zero
  3602 operand immI0() %{
  3603   predicate(n->get_int() == 0);
  3604   match(ConI);
  3606   op_cost(0);
  3607   format %{ %}
  3608   interface(CONST_INTER);
  3609 %}
  3611 // Constant for increment
  3612 operand immI1() %{
  3613   predicate(n->get_int() == 1);
  3614   match(ConI);
  3616   op_cost(0);
  3617   format %{ %}
  3618   interface(CONST_INTER);
  3619 %}
  3621 // Constant for decrement
  3622 operand immI_M1() %{
  3623   predicate(n->get_int() == -1);
  3624   match(ConI);
  3626   op_cost(0);
  3627   format %{ %}
  3628   interface(CONST_INTER);
  3629 %}
  3631 operand immI_MaxI() %{
  3632   predicate(n->get_int() == 2147483647);
  3633   match(ConI);
  3635   op_cost(0);
  3636   format %{ %}
  3637   interface(CONST_INTER);
  3638 %}
  3640 // Valid scale values for addressing modes
  3641 operand immI2() %{
  3642   predicate(0 <= n->get_int() && (n->get_int() <= 3));
  3643   match(ConI);
  3645   format %{ %}
  3646   interface(CONST_INTER);
  3647 %}
  3649 operand immI8() %{
  3650   predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
  3651   match(ConI);
  3653   op_cost(5);
  3654   format %{ %}
  3655   interface(CONST_INTER);
  3656 %}
  3658 operand immI16() %{
  3659   predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
  3660   match(ConI);
  3662   op_cost(10);
  3663   format %{ %}
  3664   interface(CONST_INTER);
  3665 %}
  3667 // Constant for long shifts
  3668 operand immI_32() %{
  3669   predicate( n->get_int() == 32 );
  3670   match(ConI);
  3672   op_cost(0);
  3673   format %{ %}
  3674   interface(CONST_INTER);
  3675 %}
  3677 operand immI_63() %{
  3678   predicate( n->get_int() == 63 );
  3679   match(ConI);
  3681   op_cost(0);
  3682   format %{ %}
  3683   interface(CONST_INTER);
  3684 %}
  3686 operand immI_0_31() %{
  3687   predicate( n->get_int() >= 0 && n->get_int() <= 31 );
  3688   match(ConI);
  3690   op_cost(0);
  3691   format %{ %}
  3692   interface(CONST_INTER);
  3693 %}
  3695 // Operand for non-negtive integer mask
  3696 operand immI_nonneg_mask() %{
  3697   predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
  3698   match(ConI);
  3700   op_cost(0);
  3701   format %{ %}
  3702   interface(CONST_INTER);
  3703 %}
  3705 operand immI_32_63() %{
  3706   predicate( n->get_int() >= 32 && n->get_int() <= 63 );
  3707   match(ConI);
  3708   op_cost(0);
  3710   format %{ %}
  3711   interface(CONST_INTER);
  3712 %}
  3714 operand immI16_sub() %{
  3715   predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
  3716   match(ConI);
  3718   op_cost(10);
  3719   format %{ %}
  3720   interface(CONST_INTER);
  3721 %}
  3723 operand immI_0_32767() %{
  3724   predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
  3725   match(ConI);
  3726   op_cost(0);
  3728   format %{ %}
  3729   interface(CONST_INTER);
  3730 %}
  3732 operand immI_0_65535() %{
  3733   predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
  3734   match(ConI);
  3735   op_cost(0);
  3737   format %{ %}
  3738   interface(CONST_INTER);
  3739 %}
  3741 operand immI_1() %{
  3742   predicate( n->get_int() == 1 );
  3743   match(ConI);
  3745   op_cost(0);
  3746   format %{ %}
  3747   interface(CONST_INTER);
  3748 %}
  3750 operand immI_2() %{
  3751   predicate( n->get_int() == 2 );
  3752   match(ConI);
  3754   op_cost(0);
  3755   format %{ %}
  3756   interface(CONST_INTER);
  3757 %}
  3759 operand immI_3() %{
  3760   predicate( n->get_int() == 3 );
  3761   match(ConI);
  3763   op_cost(0);
  3764   format %{ %}
  3765   interface(CONST_INTER);
  3766 %}
  3768 operand immI_7() %{
  3769   predicate( n->get_int() == 7 );
  3770   match(ConI);
  3772   format %{ %}
  3773   interface(CONST_INTER);
  3774 %}
  3776 // Immediates for special shifts (sign extend)
  3778 // Constants for increment
  3779 operand immI_16() %{
  3780   predicate( n->get_int() == 16 );
  3781   match(ConI);
  3783   format %{ %}
  3784   interface(CONST_INTER);
  3785 %}
  3787 operand immI_24() %{
  3788   predicate( n->get_int() == 24 );
  3789   match(ConI);
  3791   format %{ %}
  3792   interface(CONST_INTER);
  3793 %}
  3795 // Constant for byte-wide masking
  3796 operand immI_255() %{
  3797   predicate( n->get_int() == 255 );
  3798   match(ConI);
  3800   op_cost(0);
  3801   format %{ %}
  3802   interface(CONST_INTER);
  3803 %}
  3805 operand immI_65535() %{
  3806   predicate( n->get_int() == 65535 );
  3807   match(ConI);
  3809   op_cost(5);
  3810   format %{ %}
  3811   interface(CONST_INTER);
  3812 %}
  3814 operand immI_65536() %{
  3815   predicate( n->get_int() == 65536 );
  3816   match(ConI);
  3818   op_cost(5);
  3819   format %{ %}
  3820   interface(CONST_INTER);
  3821 %}
  3823 operand immI_M65536() %{
  3824   predicate( n->get_int() == -65536 );
  3825   match(ConI);
  3827   op_cost(5);
  3828   format %{ %}
  3829   interface(CONST_INTER);
  3830 %}
  3832 // Pointer Immediate
  3833 operand immP() %{
  3834   match(ConP);
  3836   op_cost(10);
  3837   format %{ %}
  3838   interface(CONST_INTER);
  3839 %}
  3841 // NULL Pointer Immediate
  3842 operand immP0() %{
  3843   predicate( n->get_ptr() == 0 );
  3844   match(ConP);
  3845   op_cost(0);
  3847   format %{ %}
  3848   interface(CONST_INTER);
  3849 %}
  3851 // Pointer Immediate: 64-bit
  3852 operand immP_set() %{
  3853   match(ConP);
  3855   op_cost(5);
  3856   // formats are generated automatically for constants and base registers
  3857   format %{ %}
  3858   interface(CONST_INTER);
  3859 %}
  3861 // Pointer Immediate: 64-bit
  3862 operand immP_load() %{
  3863   predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
  3864   match(ConP);
  3866   op_cost(5);
  3867   // formats are generated automatically for constants and base registers
  3868   format %{ %}
  3869   interface(CONST_INTER);
  3870 %}
  3872 // Pointer Immediate: 64-bit
  3873 operand immP_no_oop_cheap() %{
  3874   predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
  3875   match(ConP);
  3877   op_cost(5);
  3878   // formats are generated automatically for constants and base registers
  3879   format %{ %}
  3880   interface(CONST_INTER);
  3881 %}
  3883 // Pointer for polling page
  3884 operand immP_poll() %{
  3885   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
  3886   match(ConP);
  3887   op_cost(5);
  3889   format %{ %}
  3890   interface(CONST_INTER);
  3891 %}
  3893 // Pointer Immediate
  3894 operand immN() %{
  3895   match(ConN);
  3897   op_cost(10);
  3898   format %{ %}
  3899   interface(CONST_INTER);
  3900 %}
  3902 operand immNKlass() %{
  3903   match(ConNKlass);
  3905   op_cost(10);
  3906   format %{ %}
  3907   interface(CONST_INTER);
  3908 %}
  3910 // NULL Pointer Immediate
  3911 operand immN0() %{
  3912   predicate(n->get_narrowcon() == 0);
  3913   match(ConN);
  3915   op_cost(5);
  3916   format %{ %}
  3917   interface(CONST_INTER);
  3918 %}
  3920 // Long Immediate
  3921 operand immL() %{
  3922   match(ConL);
  3924   op_cost(20);
  3925   format %{ %}
  3926   interface(CONST_INTER);
  3927 %}
  3929 // Long Immediate zero
  3930 operand immL0() %{
  3931   predicate( n->get_long() == 0L );
  3932   match(ConL);
  3933   op_cost(0);
  3935   format %{ %}
  3936   interface(CONST_INTER);
  3937 %}
  3939 operand immL7() %{
  3940   predicate( n->get_long() == 7L );
  3941   match(ConL);
  3942   op_cost(0);
  3944   format %{ %}
  3945   interface(CONST_INTER);
  3946 %}
  3948 operand immL_M1() %{
  3949   predicate( n->get_long() == -1L );
  3950   match(ConL);
  3951   op_cost(0);
  3953   format %{ %}
  3954   interface(CONST_INTER);
  3955 %}
  3957 // bit 0..2 zero
  3958 operand immL_M8() %{
  3959   predicate( n->get_long() == -8L );
  3960   match(ConL);
  3961   op_cost(0);
  3963   format %{ %}
  3964   interface(CONST_INTER);
  3965 %}
  3967 // bit 2 zero
  3968 operand immL_M5() %{
  3969   predicate( n->get_long() == -5L );
  3970   match(ConL);
  3971   op_cost(0);
  3973   format %{ %}
  3974   interface(CONST_INTER);
  3975 %}
  3977 // bit 1..2 zero
  3978 operand immL_M7() %{
  3979   predicate( n->get_long() == -7L );
  3980   match(ConL);
  3981   op_cost(0);
  3983   format %{ %}
  3984   interface(CONST_INTER);
  3985 %}
  3987 // bit 0..1 zero
  3988 operand immL_M4() %{
  3989   predicate( n->get_long() == -4L );
  3990   match(ConL);
  3991   op_cost(0);
  3993   format %{ %}
  3994   interface(CONST_INTER);
  3995 %}
  3997 // bit 3..6 zero
  3998 operand immL_M121() %{
  3999   predicate( n->get_long() == -121L );
  4000   match(ConL);
  4001   op_cost(0);
  4003   format %{ %}
  4004   interface(CONST_INTER);
  4005 %}
  4007 // Long immediate from 0 to 127.
  4008 // Used for a shorter form of long mul by 10.
  4009 operand immL_127() %{
  4010   predicate((0 <= n->get_long()) && (n->get_long() <= 127));
  4011   match(ConL);
  4012   op_cost(0);
  4014   format %{ %}
  4015   interface(CONST_INTER);
  4016 %}
  4018 // Operand for non-negtive long mask
  4019 operand immL_nonneg_mask() %{
  4020   predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
  4021   match(ConL);
  4023   op_cost(0);
  4024   format %{ %}
  4025   interface(CONST_INTER);
  4026 %}
  4028 operand immL_0_65535() %{
  4029   predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
  4030   match(ConL);
  4031   op_cost(0);
  4033   format %{ %}
  4034   interface(CONST_INTER);
  4035 %}
  4037 // Long Immediate: cheap (materialize in <= 3 instructions)
  4038 operand immL_cheap() %{
  4039   predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
  4040   match(ConL);
  4041   op_cost(0);
  4043   format %{ %}
  4044   interface(CONST_INTER);
  4045 %}
  4047 // Long Immediate: expensive (materialize in > 3 instructions)
  4048 operand immL_expensive() %{
  4049   predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
  4050   match(ConL);
  4051   op_cost(0);
  4053   format %{ %}
  4054   interface(CONST_INTER);
  4055 %}
  4057 operand immL16() %{
  4058   predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
  4059   match(ConL);
  4061   op_cost(10);
  4062   format %{ %}
  4063   interface(CONST_INTER);
  4064 %}
  4066 operand immL16_sub() %{
  4067   predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
  4068   match(ConL);
  4070   op_cost(10);
  4071   format %{ %}
  4072   interface(CONST_INTER);
  4073 %}
  4075 // Long Immediate: low 32-bit mask
  4076 operand immL_32bits() %{
  4077   predicate(n->get_long() == 0xFFFFFFFFL);
  4078   match(ConL);
  4079   op_cost(20);
  4081   format %{ %}
  4082   interface(CONST_INTER);
  4083 %}
  4085 // Long Immediate 32-bit signed
  4086 operand immL32()
  4087 %{
  4088   predicate(n->get_long() == (int) (n->get_long()));
  4089   match(ConL);
  4091   op_cost(15);
  4092   format %{ %}
  4093   interface(CONST_INTER);
  4094 %}
  4097 //single-precision floating-point zero
  4098 operand immF0() %{
  4099   predicate(jint_cast(n->getf()) == 0);
  4100   match(ConF);
  4102   op_cost(5);
  4103   format %{ %}
  4104   interface(CONST_INTER);
  4105 %}
  4107 //single-precision floating-point immediate
  4108 operand immF() %{
  4109   match(ConF);
  4111   op_cost(20);
  4112   format %{ %}
  4113   interface(CONST_INTER);
  4114 %}
  4116 //double-precision floating-point zero
  4117 operand immD0() %{
  4118   predicate(jlong_cast(n->getd()) == 0);
  4119   match(ConD);
  4121   op_cost(5);
  4122   format %{ %}
  4123   interface(CONST_INTER);
  4124 %}
  4126 //double-precision floating-point immediate
  4127 operand immD() %{
  4128   match(ConD);
  4130   op_cost(20);
  4131   format %{ %}
  4132   interface(CONST_INTER);
  4133 %}
  4135 // Register Operands
  4136 // Integer Register
  4137 operand mRegI() %{
  4138   constraint(ALLOC_IN_RC(int_reg));
  4139   match(RegI);
  4141   format %{ %}
  4142   interface(REG_INTER);
  4143 %}
  4145 operand no_Ax_mRegI() %{
  4146   constraint(ALLOC_IN_RC(no_Ax_int_reg));
  4147   match(RegI);
  4148   match(mRegI);
  4150   format %{  %}
  4151   interface(REG_INTER);
  4152 %}
  4154 operand mS0RegI() %{
  4155   constraint(ALLOC_IN_RC(s0_reg));
  4156   match(RegI);
  4157   match(mRegI);
  4159   format %{ "S0" %}
  4160   interface(REG_INTER);
  4161 %}
  4163 operand mS1RegI() %{
  4164   constraint(ALLOC_IN_RC(s1_reg));
  4165   match(RegI);
  4166   match(mRegI);
  4168   format %{ "S1" %}
  4169   interface(REG_INTER);
  4170 %}
  4172 operand mS2RegI() %{
  4173   constraint(ALLOC_IN_RC(s2_reg));
  4174   match(RegI);
  4175   match(mRegI);
  4177   format %{ "S2" %}
  4178   interface(REG_INTER);
  4179 %}
  4181 operand mS3RegI() %{
  4182   constraint(ALLOC_IN_RC(s3_reg));
  4183   match(RegI);
  4184   match(mRegI);
  4186   format %{ "S3" %}
  4187   interface(REG_INTER);
  4188 %}
  4190 operand mS4RegI() %{
  4191   constraint(ALLOC_IN_RC(s4_reg));
  4192   match(RegI);
  4193   match(mRegI);
  4195   format %{ "S4" %}
  4196   interface(REG_INTER);
  4197 %}
  4199 operand mS5RegI() %{
  4200   constraint(ALLOC_IN_RC(s5_reg));
  4201   match(RegI);
  4202   match(mRegI);
  4204   format %{ "S5" %}
  4205   interface(REG_INTER);
  4206 %}
  4208 operand mS6RegI() %{
  4209   constraint(ALLOC_IN_RC(s6_reg));
  4210   match(RegI);
  4211   match(mRegI);
  4213   format %{ "S6" %}
  4214   interface(REG_INTER);
  4215 %}
  4217 operand mS7RegI() %{
  4218   constraint(ALLOC_IN_RC(s7_reg));
  4219   match(RegI);
  4220   match(mRegI);
  4222   format %{ "S7" %}
  4223   interface(REG_INTER);
  4224 %}
  4227 operand mT0RegI() %{
  4228   constraint(ALLOC_IN_RC(t0_reg));
  4229   match(RegI);
  4230   match(mRegI);
  4232   format %{ "T0" %}
  4233   interface(REG_INTER);
  4234 %}
  4236 operand mT1RegI() %{
  4237   constraint(ALLOC_IN_RC(t1_reg));
  4238   match(RegI);
  4239   match(mRegI);
  4241   format %{ "T1" %}
  4242   interface(REG_INTER);
  4243 %}
  4245 operand mT2RegI() %{
  4246   constraint(ALLOC_IN_RC(t2_reg));
  4247   match(RegI);
  4248   match(mRegI);
  4250   format %{ "T2" %}
  4251   interface(REG_INTER);
  4252 %}
  4254 operand mT3RegI() %{
  4255   constraint(ALLOC_IN_RC(t3_reg));
  4256   match(RegI);
  4257   match(mRegI);
  4259   format %{ "T3" %}
  4260   interface(REG_INTER);
  4261 %}
  4263 operand mT8RegI() %{
  4264   constraint(ALLOC_IN_RC(t8_reg));
  4265   match(RegI);
  4266   match(mRegI);
  4268   format %{ "T8" %}
  4269   interface(REG_INTER);
  4270 %}
  4272 operand mT9RegI() %{
  4273   constraint(ALLOC_IN_RC(t9_reg));
  4274   match(RegI);
  4275   match(mRegI);
  4277   format %{ "T9" %}
  4278   interface(REG_INTER);
  4279 %}
  4281 operand mA0RegI() %{
  4282   constraint(ALLOC_IN_RC(a0_reg));
  4283   match(RegI);
  4284   match(mRegI);
  4286   format %{ "A0" %}
  4287   interface(REG_INTER);
  4288 %}
  4290 operand mA1RegI() %{
  4291   constraint(ALLOC_IN_RC(a1_reg));
  4292   match(RegI);
  4293   match(mRegI);
  4295   format %{ "A1" %}
  4296   interface(REG_INTER);
  4297 %}
  4299 operand mA2RegI() %{
  4300   constraint(ALLOC_IN_RC(a2_reg));
  4301   match(RegI);
  4302   match(mRegI);
  4304   format %{ "A2" %}
  4305   interface(REG_INTER);
  4306 %}
  4308 operand mA3RegI() %{
  4309   constraint(ALLOC_IN_RC(a3_reg));
  4310   match(RegI);
  4311   match(mRegI);
  4313   format %{ "A3" %}
  4314   interface(REG_INTER);
  4315 %}
  4317 operand mA4RegI() %{
  4318   constraint(ALLOC_IN_RC(a4_reg));
  4319   match(RegI);
  4320   match(mRegI);
  4322   format %{ "A4" %}
  4323   interface(REG_INTER);
  4324 %}
  4326 operand mA5RegI() %{
  4327   constraint(ALLOC_IN_RC(a5_reg));
  4328   match(RegI);
  4329   match(mRegI);
  4331   format %{ "A5" %}
  4332   interface(REG_INTER);
  4333 %}
  4335 operand mA6RegI() %{
  4336   constraint(ALLOC_IN_RC(a6_reg));
  4337   match(RegI);
  4338   match(mRegI);
  4340   format %{ "A6" %}
  4341   interface(REG_INTER);
  4342 %}
  4344 operand mA7RegI() %{
  4345   constraint(ALLOC_IN_RC(a7_reg));
  4346   match(RegI);
  4347   match(mRegI);
  4349   format %{ "A7" %}
  4350   interface(REG_INTER);
  4351 %}
  4353 operand mV0RegI() %{
  4354   constraint(ALLOC_IN_RC(v0_reg));
  4355   match(RegI);
  4356   match(mRegI);
  4358   format %{ "V0" %}
  4359   interface(REG_INTER);
  4360 %}
  4362 operand mV1RegI() %{
  4363   constraint(ALLOC_IN_RC(v1_reg));
  4364   match(RegI);
  4365   match(mRegI);
  4367   format %{ "V1" %}
  4368   interface(REG_INTER);
  4369 %}
  4371 operand mRegN() %{
  4372   constraint(ALLOC_IN_RC(int_reg));
  4373   match(RegN);
  4375   format %{ %}
  4376   interface(REG_INTER);
  4377 %}
  4379 operand t0_RegN() %{
  4380   constraint(ALLOC_IN_RC(t0_reg));
  4381   match(RegN);
  4382   match(mRegN);
  4384   format %{ %}
  4385   interface(REG_INTER);
  4386 %}
  4388 operand t1_RegN() %{
  4389   constraint(ALLOC_IN_RC(t1_reg));
  4390   match(RegN);
  4391   match(mRegN);
  4393   format %{ %}
  4394   interface(REG_INTER);
  4395 %}
  4397 operand t2_RegN() %{
  4398   constraint(ALLOC_IN_RC(t2_reg));
  4399   match(RegN);
  4400   match(mRegN);
  4402   format %{ %}
  4403   interface(REG_INTER);
  4404 %}
  4406 operand t3_RegN() %{
  4407   constraint(ALLOC_IN_RC(t3_reg));
  4408   match(RegN);
  4409   match(mRegN);
  4411   format %{ %}
  4412   interface(REG_INTER);
  4413 %}
  4415 operand t8_RegN() %{
  4416   constraint(ALLOC_IN_RC(t8_reg));
  4417   match(RegN);
  4418   match(mRegN);
  4420   format %{ %}
  4421   interface(REG_INTER);
  4422 %}
  4424 operand t9_RegN() %{
  4425   constraint(ALLOC_IN_RC(t9_reg));
  4426   match(RegN);
  4427   match(mRegN);
  4429   format %{ %}
  4430   interface(REG_INTER);
  4431 %}
  4433 operand a0_RegN() %{
  4434   constraint(ALLOC_IN_RC(a0_reg));
  4435   match(RegN);
  4436   match(mRegN);
  4438   format %{ %}
  4439   interface(REG_INTER);
  4440 %}
  4442 operand a1_RegN() %{
  4443   constraint(ALLOC_IN_RC(a1_reg));
  4444   match(RegN);
  4445   match(mRegN);
  4447   format %{ %}
  4448   interface(REG_INTER);
  4449 %}
  4451 operand a2_RegN() %{
  4452   constraint(ALLOC_IN_RC(a2_reg));
  4453   match(RegN);
  4454   match(mRegN);
  4456   format %{ %}
  4457   interface(REG_INTER);
  4458 %}
  4460 operand a3_RegN() %{
  4461   constraint(ALLOC_IN_RC(a3_reg));
  4462   match(RegN);
  4463   match(mRegN);
  4465   format %{ %}
  4466   interface(REG_INTER);
  4467 %}
  4469 operand a4_RegN() %{
  4470   constraint(ALLOC_IN_RC(a4_reg));
  4471   match(RegN);
  4472   match(mRegN);
  4474   format %{ %}
  4475   interface(REG_INTER);
  4476 %}
  4478 operand a5_RegN() %{
  4479   constraint(ALLOC_IN_RC(a5_reg));
  4480   match(RegN);
  4481   match(mRegN);
  4483   format %{ %}
  4484   interface(REG_INTER);
  4485 %}
  4487 operand a6_RegN() %{
  4488   constraint(ALLOC_IN_RC(a6_reg));
  4489   match(RegN);
  4490   match(mRegN);
  4492   format %{ %}
  4493   interface(REG_INTER);
  4494 %}
  4496 operand a7_RegN() %{
  4497   constraint(ALLOC_IN_RC(a7_reg));
  4498   match(RegN);
  4499   match(mRegN);
  4501   format %{ %}
  4502   interface(REG_INTER);
  4503 %}
  4505 operand s0_RegN() %{
  4506   constraint(ALLOC_IN_RC(s0_reg));
  4507   match(RegN);
  4508   match(mRegN);
  4510   format %{ %}
  4511   interface(REG_INTER);
  4512 %}
  4514 operand s1_RegN() %{
  4515   constraint(ALLOC_IN_RC(s1_reg));
  4516   match(RegN);
  4517   match(mRegN);
  4519   format %{ %}
  4520   interface(REG_INTER);
  4521 %}
  4523 operand s2_RegN() %{
  4524   constraint(ALLOC_IN_RC(s2_reg));
  4525   match(RegN);
  4526   match(mRegN);
  4528   format %{ %}
  4529   interface(REG_INTER);
  4530 %}
  4532 operand s3_RegN() %{
  4533   constraint(ALLOC_IN_RC(s3_reg));
  4534   match(RegN);
  4535   match(mRegN);
  4537   format %{ %}
  4538   interface(REG_INTER);
  4539 %}
  4541 operand s4_RegN() %{
  4542   constraint(ALLOC_IN_RC(s4_reg));
  4543   match(RegN);
  4544   match(mRegN);
  4546   format %{ %}
  4547   interface(REG_INTER);
  4548 %}
  4550 operand s5_RegN() %{
  4551   constraint(ALLOC_IN_RC(s5_reg));
  4552   match(RegN);
  4553   match(mRegN);
  4555   format %{ %}
  4556   interface(REG_INTER);
  4557 %}
  4559 operand s6_RegN() %{
  4560   constraint(ALLOC_IN_RC(s6_reg));
  4561   match(RegN);
  4562   match(mRegN);
  4564   format %{ %}
  4565   interface(REG_INTER);
  4566 %}
  4568 operand s7_RegN() %{
  4569   constraint(ALLOC_IN_RC(s7_reg));
  4570   match(RegN);
  4571   match(mRegN);
  4573   format %{ %}
  4574   interface(REG_INTER);
  4575 %}
  4577 operand v0_RegN() %{
  4578   constraint(ALLOC_IN_RC(v0_reg));
  4579   match(RegN);
  4580   match(mRegN);
  4582   format %{ %}
  4583   interface(REG_INTER);
  4584 %}
  4586 operand v1_RegN() %{
  4587   constraint(ALLOC_IN_RC(v1_reg));
  4588   match(RegN);
  4589   match(mRegN);
  4591   format %{ %}
  4592   interface(REG_INTER);
  4593 %}
  4595 // Pointer Register
  4596 operand mRegP() %{
  4597   constraint(ALLOC_IN_RC(p_reg));
  4598   match(RegP);
  4599   match(a0_RegP);
  4601   format %{  %}
  4602   interface(REG_INTER);
  4603 %}
  4605 operand no_T8_mRegP() %{
  4606   constraint(ALLOC_IN_RC(no_T8_p_reg));
  4607   match(RegP);
  4608   match(mRegP);
  4610   format %{  %}
  4611   interface(REG_INTER);
  4612 %}
  4614 operand s0_RegP()
  4615 %{
  4616   constraint(ALLOC_IN_RC(s0_long_reg));
  4617   match(RegP);
  4618   match(mRegP);
  4619   match(no_T8_mRegP);
  4621   format %{ %}
  4622   interface(REG_INTER);
  4623 %}
  4625 operand s1_RegP()
  4626 %{
  4627   constraint(ALLOC_IN_RC(s1_long_reg));
  4628   match(RegP);
  4629   match(mRegP);
  4630   match(no_T8_mRegP);
  4632   format %{ %}
  4633   interface(REG_INTER);
  4634 %}
  4636 operand s2_RegP()
  4637 %{
  4638   constraint(ALLOC_IN_RC(s2_long_reg));
  4639   match(RegP);
  4640   match(mRegP);
  4641   match(no_T8_mRegP);
  4643   format %{ %}
  4644   interface(REG_INTER);
  4645 %}
  4647 operand s3_RegP()
  4648 %{
  4649   constraint(ALLOC_IN_RC(s3_long_reg));
  4650   match(RegP);
  4651   match(mRegP);
  4652   match(no_T8_mRegP);
  4654   format %{ %}
  4655   interface(REG_INTER);
  4656 %}
  4658 operand s4_RegP()
  4659 %{
  4660   constraint(ALLOC_IN_RC(s4_long_reg));
  4661   match(RegP);
  4662   match(mRegP);
  4663   match(no_T8_mRegP);
  4665   format %{ %}
  4666   interface(REG_INTER);
  4667 %}
  4669 operand s5_RegP()
  4670 %{
  4671   constraint(ALLOC_IN_RC(s5_long_reg));
  4672   match(RegP);
  4673   match(mRegP);
  4674   match(no_T8_mRegP);
  4676   format %{ %}
  4677   interface(REG_INTER);
  4678 %}
  4680 operand s6_RegP()
  4681 %{
  4682   constraint(ALLOC_IN_RC(s6_long_reg));
  4683   match(RegP);
  4684   match(mRegP);
  4685   match(no_T8_mRegP);
  4687   format %{ %}
  4688   interface(REG_INTER);
  4689 %}
  4691 operand s7_RegP()
  4692 %{
  4693   constraint(ALLOC_IN_RC(s7_long_reg));
  4694   match(RegP);
  4695   match(mRegP);
  4696   match(no_T8_mRegP);
  4698   format %{ %}
  4699   interface(REG_INTER);
  4700 %}
  4702 operand t0_RegP()
  4703 %{
  4704   constraint(ALLOC_IN_RC(t0_long_reg));
  4705   match(RegP);
  4706   match(mRegP);
  4707   match(no_T8_mRegP);
  4709   format %{ %}
  4710   interface(REG_INTER);
  4711 %}
  4713 operand t1_RegP()
  4714 %{
  4715   constraint(ALLOC_IN_RC(t1_long_reg));
  4716   match(RegP);
  4717   match(mRegP);
  4718   match(no_T8_mRegP);
  4720   format %{ %}
  4721   interface(REG_INTER);
  4722 %}
  4724 operand t2_RegP()
  4725 %{
  4726   constraint(ALLOC_IN_RC(t2_long_reg));
  4727   match(RegP);
  4728   match(mRegP);
  4729   match(no_T8_mRegP);
  4731   format %{ %}
  4732   interface(REG_INTER);
  4733 %}
  4735 operand t3_RegP()
  4736 %{
  4737   constraint(ALLOC_IN_RC(t3_long_reg));
  4738   match(RegP);
  4739   match(mRegP);
  4740   match(no_T8_mRegP);
  4742   format %{ %}
  4743   interface(REG_INTER);
  4744 %}
  4746 operand t8_RegP()
  4747 %{
  4748   constraint(ALLOC_IN_RC(t8_long_reg));
  4749   match(RegP);
  4750   match(mRegP);
  4752   format %{ %}
  4753   interface(REG_INTER);
  4754 %}
  4756 operand t9_RegP()
  4757 %{
  4758   constraint(ALLOC_IN_RC(t9_long_reg));
  4759   match(RegP);
  4760   match(mRegP);
  4761   match(no_T8_mRegP);
  4763   format %{ %}
  4764   interface(REG_INTER);
  4765 %}
  4767 operand a0_RegP()
  4768 %{
  4769   constraint(ALLOC_IN_RC(a0_long_reg));
  4770   match(RegP);
  4771   match(mRegP);
  4772   match(no_T8_mRegP);
  4774   format %{ %}
  4775   interface(REG_INTER);
  4776 %}
  4778 operand a1_RegP()
  4779 %{
  4780   constraint(ALLOC_IN_RC(a1_long_reg));
  4781   match(RegP);
  4782   match(mRegP);
  4783   match(no_T8_mRegP);
  4785   format %{ %}
  4786   interface(REG_INTER);
  4787 %}
  4789 operand a2_RegP()
  4790 %{
  4791   constraint(ALLOC_IN_RC(a2_long_reg));
  4792   match(RegP);
  4793   match(mRegP);
  4794   match(no_T8_mRegP);
  4796   format %{ %}
  4797   interface(REG_INTER);
  4798 %}
  4800 operand a3_RegP()
  4801 %{
  4802   constraint(ALLOC_IN_RC(a3_long_reg));
  4803   match(RegP);
  4804   match(mRegP);
  4805   match(no_T8_mRegP);
  4807   format %{ %}
  4808   interface(REG_INTER);
  4809 %}
  4811 operand a4_RegP()
  4812 %{
  4813   constraint(ALLOC_IN_RC(a4_long_reg));
  4814   match(RegP);
  4815   match(mRegP);
  4816   match(no_T8_mRegP);
  4818   format %{ %}
  4819   interface(REG_INTER);
  4820 %}
  4823 operand a5_RegP()
  4824 %{
  4825   constraint(ALLOC_IN_RC(a5_long_reg));
  4826   match(RegP);
  4827   match(mRegP);
  4828   match(no_T8_mRegP);
  4830   format %{ %}
  4831   interface(REG_INTER);
  4832 %}
  4834 operand a6_RegP()
  4835 %{
  4836   constraint(ALLOC_IN_RC(a6_long_reg));
  4837   match(RegP);
  4838   match(mRegP);
  4839   match(no_T8_mRegP);
  4841   format %{ %}
  4842   interface(REG_INTER);
  4843 %}
  4845 operand a7_RegP()
  4846 %{
  4847   constraint(ALLOC_IN_RC(a7_long_reg));
  4848   match(RegP);
  4849   match(mRegP);
  4850   match(no_T8_mRegP);
  4852   format %{ %}
  4853   interface(REG_INTER);
  4854 %}
  4856 operand v0_RegP()
  4857 %{
  4858   constraint(ALLOC_IN_RC(v0_long_reg));
  4859   match(RegP);
  4860   match(mRegP);
  4861   match(no_T8_mRegP);
  4863   format %{ %}
  4864   interface(REG_INTER);
  4865 %}
  4867 operand v1_RegP()
  4868 %{
  4869   constraint(ALLOC_IN_RC(v1_long_reg));
  4870   match(RegP);
  4871   match(mRegP);
  4872   match(no_T8_mRegP);
  4874   format %{ %}
  4875   interface(REG_INTER);
  4876 %}
  4878 /*
  4879 operand mSPRegP(mRegP reg) %{
  4880   constraint(ALLOC_IN_RC(sp_reg));
  4881   match(reg);
  4883   format %{ "SP"  %}
  4884   interface(REG_INTER);
  4885 %}
  4887 operand mFPRegP(mRegP reg) %{
  4888   constraint(ALLOC_IN_RC(fp_reg));
  4889   match(reg);
  4891   format %{ "FP"  %}
  4892   interface(REG_INTER);
  4893 %}
  4894 */
  4896 operand mRegL() %{
  4897   constraint(ALLOC_IN_RC(long_reg));
  4898   match(RegL);
  4900   format %{ %}
  4901   interface(REG_INTER);
  4902 %}
  4904 operand v0RegL() %{
  4905   constraint(ALLOC_IN_RC(v0_long_reg));
  4906   match(RegL);
  4907   match(mRegL);
  4909   format %{ %}
  4910   interface(REG_INTER);
  4911 %}
  4913 operand v1RegL() %{
  4914   constraint(ALLOC_IN_RC(v1_long_reg));
  4915   match(RegL);
  4916   match(mRegL);
  4918   format %{ %}
  4919   interface(REG_INTER);
  4920 %}
  4922 operand a0RegL() %{
  4923   constraint(ALLOC_IN_RC(a0_long_reg));
  4924   match(RegL);
  4925   match(mRegL);
  4927   format %{ "A0" %}
  4928   interface(REG_INTER);
  4929 %}
  4931 operand a1RegL() %{
  4932   constraint(ALLOC_IN_RC(a1_long_reg));
  4933   match(RegL);
  4934   match(mRegL);
  4936   format %{ %}
  4937   interface(REG_INTER);
  4938 %}
  4940 operand a2RegL() %{
  4941   constraint(ALLOC_IN_RC(a2_long_reg));
  4942   match(RegL);
  4943   match(mRegL);
  4945   format %{ %}
  4946   interface(REG_INTER);
  4947 %}
  4949 operand a3RegL() %{
  4950   constraint(ALLOC_IN_RC(a3_long_reg));
  4951   match(RegL);
  4952   match(mRegL);
  4954   format %{ %}
  4955   interface(REG_INTER);
  4956 %}
  4958 operand t0RegL() %{
  4959   constraint(ALLOC_IN_RC(t0_long_reg));
  4960   match(RegL);
  4961   match(mRegL);
  4963   format %{ %}
  4964   interface(REG_INTER);
  4965 %}
  4967 operand t1RegL() %{
  4968   constraint(ALLOC_IN_RC(t1_long_reg));
  4969   match(RegL);
  4970   match(mRegL);
  4972   format %{ %}
  4973   interface(REG_INTER);
  4974 %}
  4976 operand t2RegL() %{
  4977   constraint(ALLOC_IN_RC(t2_long_reg));
  4978   match(RegL);
  4979   match(mRegL);
  4981   format %{ %}
  4982   interface(REG_INTER);
  4983 %}
  4985 operand t3RegL() %{
  4986   constraint(ALLOC_IN_RC(t3_long_reg));
  4987   match(RegL);
  4988   match(mRegL);
  4990   format %{ %}
  4991   interface(REG_INTER);
  4992 %}
  4994 operand t8RegL() %{
  4995   constraint(ALLOC_IN_RC(t8_long_reg));
  4996   match(RegL);
  4997   match(mRegL);
  4999   format %{ %}
  5000   interface(REG_INTER);
  5001 %}
  5003 operand a4RegL() %{
  5004   constraint(ALLOC_IN_RC(a4_long_reg));
  5005   match(RegL);
  5006   match(mRegL);
  5008   format %{ %}
  5009   interface(REG_INTER);
  5010 %}
  5012 operand a5RegL() %{
  5013   constraint(ALLOC_IN_RC(a5_long_reg));
  5014   match(RegL);
  5015   match(mRegL);
  5017   format %{ %}
  5018   interface(REG_INTER);
  5019 %}
  5021 operand a6RegL() %{
  5022   constraint(ALLOC_IN_RC(a6_long_reg));
  5023   match(RegL);
  5024   match(mRegL);
  5026   format %{ %}
  5027   interface(REG_INTER);
  5028 %}
  5030 operand a7RegL() %{
  5031   constraint(ALLOC_IN_RC(a7_long_reg));
  5032   match(RegL);
  5033   match(mRegL);
  5035   format %{ %}
  5036   interface(REG_INTER);
  5037 %}
  5039 operand s0RegL() %{
  5040   constraint(ALLOC_IN_RC(s0_long_reg));
  5041   match(RegL);
  5042   match(mRegL);
  5044   format %{ %}
  5045   interface(REG_INTER);
  5046 %}
  5048 operand s1RegL() %{
  5049   constraint(ALLOC_IN_RC(s1_long_reg));
  5050   match(RegL);
  5051   match(mRegL);
  5053   format %{ %}
  5054   interface(REG_INTER);
  5055 %}
  5057 operand s2RegL() %{
  5058   constraint(ALLOC_IN_RC(s2_long_reg));
  5059   match(RegL);
  5060   match(mRegL);
  5062   format %{ %}
  5063   interface(REG_INTER);
  5064 %}
  5066 operand s3RegL() %{
  5067   constraint(ALLOC_IN_RC(s3_long_reg));
  5068   match(RegL);
  5069   match(mRegL);
  5071   format %{ %}
  5072   interface(REG_INTER);
  5073 %}
  5075 operand s4RegL() %{
  5076   constraint(ALLOC_IN_RC(s4_long_reg));
  5077   match(RegL);
  5078   match(mRegL);
  5080   format %{ %}
  5081   interface(REG_INTER);
  5082 %}
  5084 operand s7RegL() %{
  5085   constraint(ALLOC_IN_RC(s7_long_reg));
  5086   match(RegL);
  5087   match(mRegL);
  5089   format %{ %}
  5090   interface(REG_INTER);
  5091 %}
  5093 // Floating register operands
  5094 operand regF() %{
  5095   constraint(ALLOC_IN_RC(flt_reg));
  5096   match(RegF);
  5098   format %{ %}
  5099   interface(REG_INTER);
  5100 %}
  5102 //Double Precision Floating register operands
  5103 operand regD() %{
  5104   constraint(ALLOC_IN_RC(dbl_reg));
  5105   match(RegD);
  5107   format %{ %}
  5108   interface(REG_INTER);
  5109 %}
  5111 //----------Memory Operands----------------------------------------------------
  5112 // Indirect Memory Operand
  5113 operand indirect(mRegP reg) %{
  5114   constraint(ALLOC_IN_RC(p_reg));
  5115   match(reg);
  5117   format %{ "[$reg] @ indirect" %}
  5118   interface(MEMORY_INTER) %{
  5119     base($reg);
  5120     index(0x0);  /* NO_INDEX */
  5121     scale(0x0);
  5122     disp(0x0);
  5123   %}
  5124 %}
  5126 // Indirect Memory Plus Short Offset Operand
  5127 operand indOffset8(mRegP reg, immL8 off)
  5128 %{
  5129   constraint(ALLOC_IN_RC(p_reg));
  5130   match(AddP reg off);
  5132   op_cost(10);
  5133   format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
  5134   interface(MEMORY_INTER) %{
  5135     base($reg);
  5136     index(0x0); /* NO_INDEX */
  5137     scale(0x0);
  5138     disp($off);
  5139   %}
  5140 %}
  5142 // Indirect Memory Times Scale Plus Index Register
  5143 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
  5144 %{
  5145   constraint(ALLOC_IN_RC(p_reg));
  5146   match(AddP reg (LShiftL lreg scale));
  5148   op_cost(10);
  5149   format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
  5150   interface(MEMORY_INTER) %{
  5151     base($reg);
  5152     index($lreg);
  5153     scale($scale);
  5154     disp(0x0);
  5155   %}
  5156 %}
  5159 // [base + index + offset]
  5160 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
  5161 %{
  5162   constraint(ALLOC_IN_RC(p_reg));
  5163   op_cost(5);
  5164   match(AddP (AddP base index) off);
  5166   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
  5167   interface(MEMORY_INTER) %{
  5168     base($base);
  5169     index($index);
  5170     scale(0x0);
  5171     disp($off);
  5172   %}
  5173 %}
  5175 // [base + index + offset]
  5176 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
  5177 %{
  5178   constraint(ALLOC_IN_RC(p_reg));
  5179   op_cost(5);
  5180   match(AddP (AddP base (ConvI2L index)) off);
  5182   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
  5183   interface(MEMORY_INTER) %{
  5184     base($base);
  5185     index($index);
  5186     scale(0x0);
  5187     disp($off);
  5188   %}
  5189 %}
  5191 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5192 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
  5193 %{
  5194   constraint(ALLOC_IN_RC(p_reg));
  5195   match(AddP (AddP reg (LShiftL lreg scale)) off);
  5197   op_cost(10);
  5198   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
  5199   interface(MEMORY_INTER) %{
  5200     base($reg);
  5201     index($lreg);
  5202     scale($scale);
  5203     disp($off);
  5204   %}
  5205 %}
  5207 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
  5208 %{
  5209   constraint(ALLOC_IN_RC(p_reg));
  5210   match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
  5212   op_cost(10);
  5213   format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
  5214   interface(MEMORY_INTER) %{
  5215     base($reg);
  5216     index($ireg);
  5217     scale($scale);
  5218     disp($off);
  5219   %}
  5220 %}
  5222 // [base + index<<scale + offset]
  5223 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
  5224 %{
  5225   constraint(ALLOC_IN_RC(p_reg));
  5226   //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5227   op_cost(10);
  5228   match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
  5230   format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
  5231   interface(MEMORY_INTER) %{
  5232     base($base);
  5233     index($index);
  5234     scale($scale);
  5235     disp($off);
  5236   %}
  5237 %}
  5239 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5240 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
  5241 %{
  5242   predicate(Universe::narrow_oop_shift() == 0);
  5243   constraint(ALLOC_IN_RC(p_reg));
  5244   match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
  5246   op_cost(10);
  5247   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
  5248   interface(MEMORY_INTER) %{
  5249     base($reg);
  5250     index($lreg);
  5251     scale($scale);
  5252     disp($off);
  5253   %}
  5254 %}
  5256 // [base + index<<scale + offset] for compressd Oops
  5257 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
  5258 %{
  5259   constraint(ALLOC_IN_RC(p_reg));
  5260   //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5261   predicate(Universe::narrow_oop_shift() == 0);
  5262   op_cost(10);
  5263   match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
  5265   format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
  5266   interface(MEMORY_INTER) %{
  5267     base($base);
  5268     index($index);
  5269     scale($scale);
  5270     disp($off);
  5271   %}
  5272 %}
  5274 //FIXME: I think it's better to limit the immI to be 16-bit at most!
  5275 // Indirect Memory Plus Long Offset Operand
  5276 operand indOffset32(mRegP reg, immL32 off) %{
  5277   constraint(ALLOC_IN_RC(p_reg));
  5278   op_cost(20);
  5279   match(AddP reg off);
  5281   format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
  5282   interface(MEMORY_INTER) %{
  5283     base($reg);
  5284     index(0x0);   /* NO_INDEX */
  5285     scale(0x0);
  5286     disp($off);
  5287   %}
  5288 %}
  5290 // Indirect Memory Plus Index Register
  5291 operand indIndex(mRegP addr, mRegL index) %{
  5292   constraint(ALLOC_IN_RC(p_reg));
  5293   match(AddP addr index);
  5295   op_cost(20);
  5296   format %{"[$addr + $index] @ indIndex" %}
  5297   interface(MEMORY_INTER) %{
  5298     base($addr);
  5299     index($index);
  5300     scale(0x0);
  5301     disp(0x0);
  5302   %}
  5303 %}
  5305 operand indirectNarrowKlass(mRegN reg)
  5306 %{
  5307   predicate(Universe::narrow_klass_shift() == 0);
  5308   constraint(ALLOC_IN_RC(p_reg));
  5309   op_cost(10);
  5310   match(DecodeNKlass reg);
  5312   format %{ "[$reg] @ indirectNarrowKlass" %}
  5313   interface(MEMORY_INTER) %{
  5314     base($reg);
  5315     index(0x0);
  5316     scale(0x0);
  5317     disp(0x0);
  5318   %}
  5319 %}
  5321 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
  5322 %{
  5323   predicate(Universe::narrow_klass_shift() == 0);
  5324   constraint(ALLOC_IN_RC(p_reg));
  5325   op_cost(10);
  5326   match(AddP (DecodeNKlass reg) off);
  5328   format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
  5329   interface(MEMORY_INTER) %{
  5330     base($reg);
  5331     index(0x0);
  5332     scale(0x0);
  5333     disp($off);
  5334   %}
  5335 %}
  5337 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
  5338 %{
  5339   predicate(Universe::narrow_klass_shift() == 0);
  5340   constraint(ALLOC_IN_RC(p_reg));
  5341   op_cost(10);
  5342   match(AddP (DecodeNKlass reg) off);
  5344   format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
  5345   interface(MEMORY_INTER) %{
  5346     base($reg);
  5347     index(0x0);
  5348     scale(0x0);
  5349     disp($off);
  5350   %}
  5351 %}
  5353 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
  5354 %{
  5355   predicate(Universe::narrow_klass_shift() == 0);
  5356   constraint(ALLOC_IN_RC(p_reg));
  5357   match(AddP (AddP (DecodeNKlass reg) lreg) off);
  5359   op_cost(10);
  5360   format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
  5361   interface(MEMORY_INTER) %{
  5362     base($reg);
  5363     index($lreg);
  5364     scale(0x0);
  5365     disp($off);
  5366   %}
  5367 %}
  5369 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
  5370 %{
  5371   predicate(Universe::narrow_klass_shift() == 0);
  5372   constraint(ALLOC_IN_RC(p_reg));
  5373   match(AddP (DecodeNKlass reg) lreg);
  5375   op_cost(10);
  5376   format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
  5377   interface(MEMORY_INTER) %{
  5378     base($reg);
  5379     index($lreg);
  5380     scale(0x0);
  5381     disp(0x0);
  5382   %}
  5383 %}
  5385 // Indirect Memory Operand
  5386 operand indirectNarrow(mRegN reg)
  5387 %{
  5388   predicate(Universe::narrow_oop_shift() == 0);
  5389   constraint(ALLOC_IN_RC(p_reg));
  5390   op_cost(10);
  5391   match(DecodeN reg);
  5393   format %{ "[$reg] @ indirectNarrow" %}
  5394   interface(MEMORY_INTER) %{
  5395     base($reg);
  5396     index(0x0);
  5397     scale(0x0);
  5398     disp(0x0);
  5399   %}
  5400 %}
  5402 // Indirect Memory Plus Short Offset Operand
  5403 operand indOffset8Narrow(mRegN reg, immL8 off)
  5404 %{
  5405   predicate(Universe::narrow_oop_shift() == 0);
  5406   constraint(ALLOC_IN_RC(p_reg));
  5407   op_cost(10);
  5408   match(AddP (DecodeN reg) off);
  5410   format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
  5411   interface(MEMORY_INTER) %{
  5412     base($reg);
  5413     index(0x0);
  5414     scale(0x0);
  5415     disp($off);
  5416   %}
  5417 %}
  5419 // Indirect Memory Plus Index Register Plus Offset Operand
  5420 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
  5421 %{
  5422   predicate(Universe::narrow_oop_shift() == 0);
  5423   constraint(ALLOC_IN_RC(p_reg));
  5424   match(AddP (AddP (DecodeN reg) lreg) off);
  5426   op_cost(10);
  5427   format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
  5428   interface(MEMORY_INTER) %{
  5429     base($reg);
  5430     index($lreg);
  5431     scale(0x0);
  5432     disp($off);
  5433   %}
  5434 %}
  5436 //----------Load Long Memory Operands------------------------------------------
  5437 // The load-long idiom will use it's address expression again after loading
  5438 // the first word of the long.  If the load-long destination overlaps with
  5439 // registers used in the addressing expression, the 2nd half will be loaded
  5440 // from a clobbered address.  Fix this by requiring that load-long use
  5441 // address registers that do not overlap with the load-long target.
  5443 // load-long support
  5444 operand load_long_RegP() %{
  5445   constraint(ALLOC_IN_RC(p_reg));
  5446   match(RegP);
  5447   match(mRegP);
  5448   op_cost(100);
  5449   format %{  %}
  5450   interface(REG_INTER);
  5451 %}
  5453 // Indirect Memory Operand Long
  5454 operand load_long_indirect(load_long_RegP reg) %{
  5455   constraint(ALLOC_IN_RC(p_reg));
  5456   match(reg);
  5458   format %{ "[$reg]" %}
  5459   interface(MEMORY_INTER) %{
  5460     base($reg);
  5461     index(0x0);
  5462     scale(0x0);
  5463     disp(0x0);
  5464   %}
  5465 %}
  5467 // Indirect Memory Plus Long Offset Operand
  5468 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
  5469   match(AddP reg off);
  5471   format %{ "[$reg + $off]" %}
  5472   interface(MEMORY_INTER) %{
  5473     base($reg);
  5474     index(0x0);
  5475     scale(0x0);
  5476     disp($off);
  5477   %}
  5478 %}
  5480 //----------Conditional Branch Operands----------------------------------------
  5481 // Comparison Op  - This is the operation of the comparison, and is limited to
  5482 //                  the following set of codes:
  5483 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
  5484 //
  5485 // Other attributes of the comparison, such as unsignedness, are specified
  5486 // by the comparison instruction that sets a condition code flags register.
  5487 // That result is represented by a flags operand whose subtype is appropriate
  5488 // to the unsignedness (etc.) of the comparison.
  5489 //
  5490 // Later, the instruction which matches both the Comparison Op (a Bool) and
  5491 // the flags (produced by the Cmp) specifies the coding of the comparison op
  5492 // by matching a specific subtype of Bool operand below, such as cmpOpU.
  5494 // Comparision Code
  5495 operand cmpOp() %{
  5496   match(Bool);
  5498   format %{ "" %}
  5499   interface(COND_INTER) %{
  5500     equal(0x01);
  5501     not_equal(0x02);
  5502     greater(0x03);
  5503     greater_equal(0x04);
  5504     less(0x05);
  5505     less_equal(0x06);
  5506     overflow(0x7);
  5507     no_overflow(0x8);
  5508   %}
  5509 %}
  5512 // Comparision Code
  5513 // Comparison Code, unsigned compare.  Used by FP also, with
  5514 // C2 (unordered) turned into GT or LT already.  The other bits
  5515 // C0 and C3 are turned into Carry & Zero flags.
  5516 operand cmpOpU() %{
  5517   match(Bool);
  5519   format %{ "" %}
  5520   interface(COND_INTER) %{
  5521     equal(0x01);
  5522     not_equal(0x02);
  5523     greater(0x03);
  5524     greater_equal(0x04);
  5525     less(0x05);
  5526     less_equal(0x06);
  5527     overflow(0x7);
  5528     no_overflow(0x8);
  5529   %}
  5530 %}
  5533 //----------Special Memory Operands--------------------------------------------
  5534 // Stack Slot Operand - This operand is used for loading and storing temporary
  5535 //                      values on the stack where a match requires a value to
  5536 //                      flow through memory.
  5537 operand stackSlotP(sRegP reg) %{
  5538   constraint(ALLOC_IN_RC(stack_slots));
  5539   // No match rule because this operand is only generated in matching
  5540   op_cost(50);
  5541   format %{ "[$reg]" %}
  5542   interface(MEMORY_INTER) %{
  5543     base(0x1d);  // SP
  5544     index(0x0);  // No Index
  5545     scale(0x0);  // No Scale
  5546     disp($reg);  // Stack Offset
  5547   %}
  5548 %}
  5550 operand stackSlotI(sRegI reg) %{
  5551   constraint(ALLOC_IN_RC(stack_slots));
  5552   // No match rule because this operand is only generated in matching
  5553   op_cost(50);
  5554   format %{ "[$reg]" %}
  5555   interface(MEMORY_INTER) %{
  5556     base(0x1d);  // SP
  5557     index(0x0);  // No Index
  5558     scale(0x0);  // No Scale
  5559     disp($reg);  // Stack Offset
  5560   %}
  5561 %}
  5563 operand stackSlotF(sRegF reg) %{
  5564   constraint(ALLOC_IN_RC(stack_slots));
  5565   // No match rule because this operand is only generated in matching
  5566   op_cost(50);
  5567   format %{ "[$reg]" %}
  5568   interface(MEMORY_INTER) %{
  5569     base(0x1d);  // SP
  5570     index(0x0);  // No Index
  5571     scale(0x0);  // No Scale
  5572     disp($reg);  // Stack Offset
  5573   %}
  5574 %}
  5576 operand stackSlotD(sRegD reg) %{
  5577   constraint(ALLOC_IN_RC(stack_slots));
  5578   // No match rule because this operand is only generated in matching
  5579   op_cost(50);
  5580   format %{ "[$reg]" %}
  5581   interface(MEMORY_INTER) %{
  5582     base(0x1d);  // SP
  5583     index(0x0);  // No Index
  5584     scale(0x0);  // No Scale
  5585     disp($reg);  // Stack Offset
  5586   %}
  5587 %}
  5589 operand stackSlotL(sRegL reg) %{
  5590   constraint(ALLOC_IN_RC(stack_slots));
  5591   // No match rule because this operand is only generated in matching
  5592   op_cost(50);
  5593   format %{ "[$reg]" %}
  5594   interface(MEMORY_INTER) %{
  5595     base(0x1d);  // SP
  5596     index(0x0);  // No Index
  5597     scale(0x0);  // No Scale
  5598     disp($reg);  // Stack Offset
  5599   %}
  5600 %}
  5603 //------------------------OPERAND CLASSES--------------------------------------
  5604 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
  5605 opclass memory( indirect, indirectNarrow, indOffset8, indOffset32, indIndex, indIndexScale, load_long_indirect, load_long_indOffset32, baseIndexOffset8, baseIndexOffset8_convI2L, indIndexScaleOffset8, indIndexScaleOffset8_convI2L, basePosIndexScaleOffset8, indIndexScaleOffsetNarrow, indPosIndexI2LScaleOffset8Narrow, indOffset8Narrow, indIndexOffset8Narrow);
  5608 //----------PIPELINE-----------------------------------------------------------
  5609 // Rules which define the behavior of the target architectures pipeline.
  5611 pipeline %{
  5613   //----------ATTRIBUTES---------------------------------------------------------
  5614   attributes %{
  5615     fixed_size_instructions;          // Fixed size instructions
  5616     branch_has_delay_slot;      // branch have delay slot in gs2
  5617     max_instructions_per_bundle = 1;     // 1 instruction per bundle
  5618     max_bundles_per_cycle = 4;         // Up to 4 bundles per cycle
  5619          bundle_unit_size=4;
  5620     instruction_unit_size = 4;           // An instruction is 4 bytes long
  5621     instruction_fetch_unit_size = 16;    // The processor fetches one line
  5622     instruction_fetch_units = 1;         // of 16 bytes
  5624     // List of nop instructions
  5625     nops( MachNop );
  5626   %}
  5628   //----------RESOURCES----------------------------------------------------------
  5629   // Resources are the functional units available to the machine
  5631   resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4,  ALU1, ALU2,  ALU = ALU1 | ALU2,  FPU1, FPU2, FPU = FPU1 | FPU2,  MEM,  BR);
  5633   //----------PIPELINE DESCRIPTION-----------------------------------------------
  5634   // Pipeline Description specifies the stages in the machine's pipeline
  5636   // IF: fetch
  5637   // ID: decode
  5638   // RD: read
  5639   // CA: caculate
  5640   // WB: write back
  5641   // CM: commit
  5643   pipe_desc(IF, ID, RD, CA, WB, CM);
  5646   //----------PIPELINE CLASSES---------------------------------------------------
  5647   // Pipeline Classes describe the stages in which input and output are
  5648   // referenced by the hardware pipeline.
  5650   //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
  5651   pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
  5652     single_instruction;
  5653     src1   : RD(read);
  5654     src2   : RD(read);
  5655     dst    : WB(write)+1;
  5656     DECODE : ID;
  5657     ALU    : CA;
  5658   %}
  5660   //No.19 Integer mult operation : dst <-- reg1 mult reg2
  5661   pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
  5662     src1   : RD(read);
  5663     src2   : RD(read);
  5664     dst    : WB(write)+5;
  5665     DECODE : ID;
  5666     ALU2   : CA;
  5667   %}
  5669   pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  5670     src1   : RD(read);
  5671     src2   : RD(read);
  5672     dst    : WB(write)+10;
  5673     DECODE : ID;
  5674     ALU2   : CA;
  5675   %}
  5677   //No.19 Integer div operation : dst <-- reg1 div reg2
  5678   pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
  5679     src1   : RD(read);
  5680     src2   : RD(read);
  5681     dst    : WB(write)+10;
  5682     DECODE : ID;
  5683     ALU2   : CA;
  5684   %}
  5686   //No.19 Integer mod operation : dst <-- reg1 mod reg2
  5687   pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
  5688     instruction_count(2);
  5689     src1   : RD(read);
  5690     src2   : RD(read);
  5691     dst    : WB(write)+10;
  5692     DECODE : ID;
  5693     ALU2   : CA;
  5694   %}
  5696   //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
  5697   pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
  5698     instruction_count(2);
  5699     src1   : RD(read);
  5700     src2   : RD(read);
  5701     dst    : WB(write);
  5702     DECODE : ID;
  5703     ALU    : CA;
  5704   %}
  5706   //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
  5707   pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
  5708     instruction_count(2);
  5709     src    : RD(read);
  5710     dst    : WB(write);
  5711     DECODE : ID;
  5712     ALU    : CA;
  5713   %}
  5715   //no.16 load Long from memory :
  5716   pipe_class ialu_loadL(mRegL dst, memory mem) %{
  5717     instruction_count(2);
  5718     mem    : RD(read);
  5719     dst    : WB(write)+5;
  5720     DECODE : ID;
  5721     MEM    : RD;
  5722   %}
  5724   //No.17 Store Long to Memory :
  5725   pipe_class ialu_storeL(mRegL src, memory mem) %{
  5726     instruction_count(2);
  5727     mem    : RD(read);
  5728     src    : RD(read);
  5729     DECODE : ID;
  5730     MEM    : RD;
  5731   %}
  5733   //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
  5734   pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
  5735          single_instruction;
  5736     src    : RD(read);
  5737     dst    : WB(write);
  5738     DECODE : ID;
  5739     ALU    : CA;
  5740   %}
  5742   //No.3 Integer move operation : dst <-- reg
  5743   pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
  5744     src    : RD(read);
  5745     dst    : WB(write);
  5746     DECODE : ID;
  5747     ALU    : CA;
  5748   %}
  5750   //No.4 No instructions : do nothing
  5751   pipe_class empty( ) %{
  5752     instruction_count(0);
  5753   %}
  5755   //No.5 UnConditional branch :
  5756   pipe_class pipe_jump( label labl ) %{
  5757     multiple_bundles;
  5758     DECODE : ID;
  5759     BR     : RD;
  5760   %}
  5762   //No.6 ALU Conditional branch :
  5763   pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
  5764     multiple_bundles;
  5765     src1   : RD(read);
  5766     src2   : RD(read);
  5767     DECODE : ID;
  5768     BR     : RD;
  5769   %}
  5771   //no.7 load integer from memory :
  5772   pipe_class ialu_loadI(mRegI dst, memory mem) %{
  5773     mem    : RD(read);
  5774     dst    : WB(write)+3;
  5775     DECODE : ID;
  5776     MEM    : RD;
  5777   %}
  5779   //No.8 Store Integer to Memory :
  5780   pipe_class ialu_storeI(mRegI src, memory mem) %{
  5781     mem    : RD(read);
  5782     src    : RD(read);
  5783     DECODE : ID;
  5784     MEM    : RD;
  5785   %}
  5788   //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
  5789   pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
  5790     src1   : RD(read);
  5791     src2   : RD(read);
  5792     dst    : WB(write);
  5793     DECODE : ID;
  5794     FPU    : CA;
  5795   %}
  5797   //No.22 Floating div operation : dst <-- reg1 div reg2
  5798   pipe_class fpu_div(regF dst, regF src1, regF src2) %{
  5799     src1   : RD(read);
  5800     src2   : RD(read);
  5801     dst    : WB(write);
  5802     DECODE : ID;
  5803     FPU2   : CA;
  5804   %}
  5806   pipe_class fcvt_I2D(regD dst, mRegI src) %{
  5807     src    : RD(read);
  5808     dst    : WB(write);
  5809     DECODE : ID;
  5810     FPU1   : CA;
  5811   %}
  5813   pipe_class fcvt_D2I(mRegI dst, regD src) %{
  5814     src    : RD(read);
  5815     dst    : WB(write);
  5816     DECODE : ID;
  5817     FPU1   : CA;
  5818   %}
  5820   pipe_class pipe_mfc1(mRegI dst, regD src) %{
  5821     src    : RD(read);
  5822     dst    : WB(write);
  5823     DECODE : ID;
  5824     MEM    : RD;
  5825   %}
  5827   pipe_class pipe_mtc1(regD dst, mRegI src) %{
  5828     src    : RD(read);
  5829     dst    : WB(write);
  5830     DECODE : ID;
  5831     MEM    : RD(5);
  5832   %}
  5834   //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
  5835   pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
  5836     multiple_bundles;
  5837     src1   : RD(read);
  5838     src2   : RD(read);
  5839     dst    : WB(write);
  5840     DECODE : ID;
  5841     FPU2   : CA;
  5842   %}
  5844   //No.11 Load Floating from Memory :
  5845   pipe_class fpu_loadF(regF dst, memory mem) %{
  5846     instruction_count(1);
  5847     mem    : RD(read);
  5848     dst    : WB(write)+3;
  5849     DECODE : ID;
  5850     MEM    : RD;
  5851   %}
  5853   //No.12 Store Floating to Memory :
  5854   pipe_class fpu_storeF(regF src, memory mem) %{
  5855     instruction_count(1);
  5856     mem    : RD(read);
  5857     src    : RD(read);
  5858     DECODE : ID;
  5859     MEM    : RD;
  5860   %}
  5862   //No.13 FPU Conditional branch :
  5863   pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
  5864     multiple_bundles;
  5865     src1   : RD(read);
  5866     src2   : RD(read);
  5867     DECODE : ID;
  5868     BR     : RD;
  5869   %}
  5871 //No.14 Floating FPU reg operation : dst <-- op reg
  5872   pipe_class fpu1_regF(regF dst, regF src) %{
  5873     src    : RD(read);
  5874     dst    : WB(write);
  5875     DECODE : ID;
  5876     FPU    : CA;
  5877   %}
  5879   pipe_class long_memory_op() %{
  5880     instruction_count(10); multiple_bundles; force_serialization;
  5881     fixed_latency(30);
  5882   %}
  5884   pipe_class simple_call() %{
  5885    instruction_count(10); multiple_bundles; force_serialization;
  5886    fixed_latency(200);
  5887    BR     : RD;
  5888   %}
  5890   pipe_class call() %{
  5891     instruction_count(10); multiple_bundles; force_serialization;
  5892     fixed_latency(200);
  5893   %}
  5895   //FIXME:
  5896   //No.9 Piple slow : for multi-instructions
  5897   pipe_class pipe_slow(  ) %{
  5898     instruction_count(20);
  5899     force_serialization;
  5900     multiple_bundles;
  5901     fixed_latency(50);
  5902   %}
  5904 %}
  5908 //----------INSTRUCTIONS-------------------------------------------------------
  5909 //
  5910 // match      -- States which machine-independent subtree may be replaced
  5911 //               by this instruction.
  5912 // ins_cost   -- The estimated cost of this instruction is used by instruction
  5913 //               selection to identify a minimum cost tree of machine
  5914 //               instructions that matches a tree of machine-independent
  5915 //               instructions.
  5916 // format     -- A string providing the disassembly for this instruction.
  5917 //               The value of an instruction's operand may be inserted
  5918 //               by referring to it with a '$' prefix.
  5919 // opcode     -- Three instruction opcodes may be provided.  These are referred
  5920 //               to within an encode class as $primary, $secondary, and $tertiary
  5921 //               respectively.  The primary opcode is commonly used to
  5922 //               indicate the type of machine instruction, while secondary
  5923 //               and tertiary are often used for prefix options or addressing
  5924 //               modes.
  5925 // ins_encode -- A list of encode classes with parameters. The encode class
  5926 //               name must have been defined in an 'enc_class' specification
  5927 //               in the encode section of the architecture description.
  5930 // Load Integer
  5931 instruct loadI(mRegI dst, memory mem) %{
  5932   match(Set dst (LoadI mem));
  5934   ins_cost(125);
  5935   format %{ "lw    $dst, $mem   #@loadI" %}
  5936   ins_encode (load_I_enc(dst, mem));
  5937   ins_pipe( ialu_loadI );
  5938 %}
  5940 instruct loadI_convI2L(mRegL dst, memory mem) %{
  5941   match(Set dst (ConvI2L (LoadI mem)));
  5943   ins_cost(125);
  5944   format %{ "lw    $dst, $mem   #@loadI_convI2L" %}
  5945   ins_encode (load_I_enc(dst, mem));
  5946   ins_pipe( ialu_loadI );
  5947 %}
  5949 // Load Integer (32 bit signed) to Byte (8 bit signed)
  5950 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  5951   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
  5953   ins_cost(125);
  5954   format %{ "lb  $dst, $mem\t# int -> byte #@loadI2B" %}
  5955   ins_encode(load_B_enc(dst, mem));
  5956   ins_pipe(ialu_loadI);
  5957 %}
  5959 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
  5960 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
  5961   match(Set dst (AndI (LoadI mem) mask));
  5963   ins_cost(125);
  5964   format %{ "lbu  $dst, $mem\t# int -> ubyte #@loadI2UB" %}
  5965   ins_encode(load_UB_enc(dst, mem));
  5966   ins_pipe(ialu_loadI);
  5967 %}
  5969 // Load Integer (32 bit signed) to Short (16 bit signed)
  5970 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
  5971   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
  5973   ins_cost(125);
  5974   format %{ "lh  $dst, $mem\t# int -> short #@loadI2S" %}
  5975   ins_encode(load_S_enc(dst, mem));
  5976   ins_pipe(ialu_loadI);
  5977 %}
  5979 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
  5980 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
  5981   match(Set dst (AndI (LoadI mem) mask));
  5983   ins_cost(125);
  5984   format %{ "lhu  $dst, $mem\t# int -> ushort/char #@loadI2US" %}
  5985   ins_encode(load_C_enc(dst, mem));
  5986   ins_pipe(ialu_loadI);
  5987 %}
  5989 // Load Long.
  5990 instruct loadL(mRegL dst, memory mem) %{
  5991 //  predicate(!((LoadLNode*)n)->require_atomic_access());
  5992   match(Set dst (LoadL mem));
  5994   ins_cost(250);
  5995   format %{ "ld    $dst, $mem   #@loadL" %}
  5996   ins_encode(load_L_enc(dst, mem));
  5997   ins_pipe( ialu_loadL );
  5998 %}
  6000 // Load Long - UNaligned
  6001 instruct loadL_unaligned(mRegL dst, memory mem) %{
  6002   match(Set dst (LoadL_unaligned mem));
  6004   // FIXME: Need more effective ldl/ldr
  6005   ins_cost(450);
  6006   format %{ "ld    $dst, $mem   #@loadL_unaligned\n\t" %}
  6007   ins_encode(load_L_enc(dst, mem));
  6008   ins_pipe( ialu_loadL );
  6009 %}
  6011 // Store Long
  6012 instruct storeL_reg(memory mem, mRegL src) %{
  6013   match(Set mem (StoreL mem src));
  6015   ins_cost(200);
  6016   format %{ "sd    $mem,   $src #@storeL_reg\n" %}
  6017   ins_encode(store_L_reg_enc(mem, src));
  6018   ins_pipe( ialu_storeL );
  6019 %}
  6021 instruct storeL_immL0(memory mem, immL0 zero) %{
  6022   match(Set mem (StoreL mem zero));
  6024   ins_cost(180);
  6025   format %{ "sd    zero, $mem #@storeL_immL0" %}
  6026   ins_encode(store_L_immL0_enc(mem, zero));
  6027   ins_pipe( ialu_storeL );
  6028 %}
  6030 instruct storeL_imm(memory mem, immL src) %{
  6031   match(Set mem (StoreL mem src));
  6033   ins_cost(200);
  6034   format %{ "sd    $src, $mem #@storeL_imm" %}
  6035   ins_encode(store_L_immL_enc(mem, src));
  6036   ins_pipe( ialu_storeL );
  6037 %}
  6039 // Load Compressed Pointer
  6040 instruct loadN(mRegN dst, memory mem)
  6041 %{
  6042    match(Set dst (LoadN mem));
  6044    ins_cost(125); // XXX
  6045    format %{ "lwu    $dst, $mem\t# compressed ptr @ loadN" %}
  6046    ins_encode (load_N_enc(dst, mem));
  6047    ins_pipe( ialu_loadI ); // XXX
  6048 %}
  6050 instruct loadN2P(mRegP dst, memory mem)
  6051 %{
  6052    match(Set dst (DecodeN (LoadN mem)));
  6053    predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6055    ins_cost(125); // XXX
  6056    format %{ "lwu    $dst, $mem\t# @ loadN2P" %}
  6057    ins_encode (load_N_enc(dst, mem));
  6058    ins_pipe( ialu_loadI ); // XXX
  6059 %}
  6061 // Load Pointer
  6062 instruct loadP(mRegP dst, memory mem) %{
  6063   match(Set dst (LoadP mem));
  6065   ins_cost(125);
  6066   format %{ "ld    $dst, $mem #@loadP" %}
  6067   ins_encode (load_P_enc(dst, mem));
  6068   ins_pipe( ialu_loadI );
  6069 %}
  6071 // Load Klass Pointer
  6072 instruct loadKlass(mRegP dst, memory mem) %{
  6073   match(Set dst (LoadKlass mem));
  6075   ins_cost(125);
  6076   format %{ "MOV    $dst,$mem @ loadKlass" %}
  6077   ins_encode (load_P_enc(dst, mem));
  6078   ins_pipe( ialu_loadI );
  6079 %}
  6081 // Load narrow Klass Pointer
  6082 instruct loadNKlass(mRegN dst, memory mem)
  6083 %{
  6084   match(Set dst (LoadNKlass mem));
  6086   ins_cost(125); // XXX
  6087   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
  6088   ins_encode (load_N_enc(dst, mem));
  6089   ins_pipe( ialu_loadI ); // XXX
  6090 %}
  6092 instruct loadN2PKlass(mRegP dst, memory mem)
  6093 %{
  6094   match(Set dst (DecodeNKlass (LoadNKlass mem)));
  6095   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6097   ins_cost(125); // XXX
  6098   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
  6099   ins_encode (load_N_enc(dst, mem));
  6100   ins_pipe( ialu_loadI ); // XXX
  6101 %}
  6103 // Load Constant
  6104 instruct loadConI(mRegI dst, immI src) %{
  6105   match(Set dst src);
  6107   ins_cost(150);
  6108   format %{ "mov    $dst, $src #@loadConI" %}
  6109   ins_encode %{
  6110     Register dst = $dst$$Register;
  6111     int    value = $src$$constant;
  6112     __ move(dst, value);
  6113   %}
  6114   ins_pipe( ialu_regI_regI );
  6115 %}
  6118 instruct loadConL_set64(mRegL dst, immL src) %{
  6119   match(Set dst src);
  6120   ins_cost(120);
  6121   format %{ "li   $dst, $src @ loadConL_set64" %}
  6122   ins_encode %{
  6123     __ set64($dst$$Register, $src$$constant);
  6124   %}
  6125   ins_pipe(ialu_regL_regL);
  6126 %}
  6128 /*
  6129 // Load long value from constant table (predicated by immL_expensive).
  6130 instruct loadConL_load(mRegL dst, immL_expensive src) %{
  6131   match(Set dst src);
  6132   ins_cost(150);
  6133   format %{ "ld  $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
  6134   ins_encode %{
  6135     int con_offset = $constantoffset($src);
  6137     if (Assembler::is_simm16(con_offset)) {
  6138        __ ld($dst$$Register, $constanttablebase, con_offset);
  6139     } else {
  6140        __ set64(AT, con_offset);
  6141        if (UseLoongsonISA) {
  6142           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6143        } else {
  6144           __ daddu(AT, $constanttablebase, AT);
  6145           __ ld($dst$$Register, AT, 0);
  6148   %}
  6149   ins_pipe(ialu_loadI);
  6150 %}
  6151 */
  6153 instruct loadConL16(mRegL dst, immL16 src) %{
  6154   match(Set dst src);
  6155   ins_cost(105);
  6156   format %{ "mov    $dst, $src #@loadConL16" %}
  6157   ins_encode %{
  6158     Register dst_reg = as_Register($dst$$reg);
  6159     int      value   = $src$$constant;
  6160     __ daddiu(dst_reg, R0, value);
  6161   %}
  6162   ins_pipe( ialu_regL_regL );
  6163 %}
  6166 instruct loadConL0(mRegL dst, immL0 src) %{
  6167   match(Set dst src);
  6168   ins_cost(100);
  6169   format %{ "mov    $dst, zero #@loadConL0" %}
  6170   ins_encode %{
  6171     Register dst_reg = as_Register($dst$$reg);
  6172     __ daddu(dst_reg, R0, R0);
  6173   %}
  6174   ins_pipe( ialu_regL_regL );
  6175 %}
  6177 // Load Range
  6178 instruct loadRange(mRegI dst, memory mem) %{
  6179   match(Set dst (LoadRange mem));
  6181   ins_cost(125);
  6182   format %{ "MOV    $dst,$mem @ loadRange" %}
  6183   ins_encode(load_I_enc(dst, mem));
  6184   ins_pipe( ialu_loadI );
  6185 %}
  6188 instruct storeP(memory mem, mRegP src ) %{
  6189   match(Set mem (StoreP mem src));
  6191   ins_cost(125);
  6192   format %{ "sd    $src, $mem #@storeP" %}
  6193   ins_encode(store_P_reg_enc(mem, src));
  6194   ins_pipe( ialu_storeI );
  6195 %}
  6197 // Store NULL Pointer, mark word, or other simple pointer constant.
  6198 instruct storeImmP0(memory mem, immP0 zero) %{
  6199   match(Set mem (StoreP mem zero));
  6201   ins_cost(125);
  6202   format %{ "mov    $mem, $zero #@storeImmP0" %}
  6203   ins_encode(store_P_immP0_enc(mem));
  6204   ins_pipe( ialu_storeI );
  6205 %}
  6207 // Store Byte Immediate
  6208 instruct storeImmB(memory mem, immI8 src) %{
  6209   match(Set mem (StoreB mem src));
  6211   ins_cost(150);
  6212   format %{ "movb   $mem, $src #@storeImmB" %}
  6213   ins_encode(store_B_immI_enc(mem, src));
  6214   ins_pipe( ialu_storeI );
  6215 %}
  6217 // Store Compressed Pointer
  6218 instruct storeN(memory mem, mRegN src)
  6219 %{
  6220   match(Set mem (StoreN mem src));
  6222   ins_cost(125); // XXX
  6223   format %{ "sw    $mem, $src\t# compressed ptr @ storeN" %}
  6224   ins_encode(store_N_reg_enc(mem, src));
  6225   ins_pipe( ialu_storeI );
  6226 %}
  6228 instruct storeP2N(memory mem, mRegP src)
  6229 %{
  6230   match(Set mem (StoreN mem (EncodeP src)));
  6231   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6233   ins_cost(125); // XXX
  6234   format %{ "sw    $mem, $src\t# @ storeP2N" %}
  6235   ins_encode(store_N_reg_enc(mem, src));
  6236   ins_pipe( ialu_storeI );
  6237 %}
  6239 instruct storeNKlass(memory mem, mRegN src)
  6240 %{
  6241   match(Set mem (StoreNKlass mem src));
  6243   ins_cost(125); // XXX
  6244   format %{ "sw    $mem, $src\t# compressed klass ptr @ storeNKlass" %}
  6245   ins_encode(store_N_reg_enc(mem, src));
  6246   ins_pipe( ialu_storeI );
  6247 %}
  6249 instruct storeP2NKlass(memory mem, mRegP src)
  6250 %{
  6251   match(Set mem (StoreNKlass mem (EncodePKlass src)));
  6252   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6254   ins_cost(125); // XXX
  6255   format %{ "sw    $mem, $src\t# @ storeP2NKlass" %}
  6256   ins_encode(store_N_reg_enc(mem, src));
  6257   ins_pipe( ialu_storeI );
  6258 %}
  6260 instruct storeImmN0(memory mem, immN0 zero)
  6261 %{
  6262   match(Set mem (StoreN mem zero));
  6264   ins_cost(125); // XXX
  6265   format %{ "storeN0    zero, $mem\t# compressed ptr" %}
  6266   ins_encode(storeImmN0_enc(mem, zero));
  6267   ins_pipe( ialu_storeI );
  6268 %}
  6270 // Store Byte
  6271 instruct storeB(memory mem, mRegI src) %{
  6272   match(Set mem (StoreB mem src));
  6274   ins_cost(125);
  6275   format %{ "sb    $src, $mem #@storeB" %}
  6276   ins_encode(store_B_reg_enc(mem, src));
  6277   ins_pipe( ialu_storeI );
  6278 %}
  6280 instruct storeB_convL2I(memory mem, mRegL src) %{
  6281   match(Set mem (StoreB mem (ConvL2I src)));
  6283   ins_cost(125);
  6284   format %{ "sb    $src, $mem #@storeB_convL2I" %}
  6285   ins_encode(store_B_reg_enc(mem, src));
  6286   ins_pipe( ialu_storeI );
  6287 %}
  6289 // Load Byte (8bit signed)
  6290 instruct loadB(mRegI dst, memory mem) %{
  6291   match(Set dst (LoadB mem));
  6293   ins_cost(125);
  6294   format %{ "lb   $dst, $mem #@loadB" %}
  6295   ins_encode(load_B_enc(dst, mem));
  6296   ins_pipe( ialu_loadI );
  6297 %}
  6299 instruct loadB_convI2L(mRegL dst, memory mem) %{
  6300   match(Set dst (ConvI2L (LoadB mem)));
  6302   ins_cost(125);
  6303   format %{ "lb   $dst, $mem #@loadB_convI2L" %}
  6304   ins_encode(load_B_enc(dst, mem));
  6305   ins_pipe( ialu_loadI );
  6306 %}
  6308 // Load Byte (8bit UNsigned)
  6309 instruct loadUB(mRegI dst, memory mem) %{
  6310   match(Set dst (LoadUB mem));
  6312   ins_cost(125);
  6313   format %{ "lbu   $dst, $mem #@loadUB" %}
  6314   ins_encode(load_UB_enc(dst, mem));
  6315   ins_pipe( ialu_loadI );
  6316 %}
  6318 instruct loadUB_convI2L(mRegL dst, memory mem) %{
  6319   match(Set dst (ConvI2L (LoadUB mem)));
  6321   ins_cost(125);
  6322   format %{ "lbu   $dst, $mem #@loadUB_convI2L" %}
  6323   ins_encode(load_UB_enc(dst, mem));
  6324   ins_pipe( ialu_loadI );
  6325 %}
  6327 // Load Short (16bit signed)
  6328 instruct loadS(mRegI dst, memory mem) %{
  6329   match(Set dst (LoadS mem));
  6331   ins_cost(125);
  6332   format %{ "lh   $dst, $mem #@loadS" %}
  6333   ins_encode(load_S_enc(dst, mem));
  6334   ins_pipe( ialu_loadI );
  6335 %}
  6337 // Load Short (16 bit signed) to Byte (8 bit signed)
  6338 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  6339   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
  6341   ins_cost(125);
  6342   format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
  6343   ins_encode(load_B_enc(dst, mem));
  6344   ins_pipe(ialu_loadI);
  6345 %}
  6347 instruct loadS_convI2L(mRegL dst, memory mem) %{
  6348   match(Set dst (ConvI2L (LoadS mem)));
  6350   ins_cost(125);
  6351   format %{ "lh   $dst, $mem #@loadS_convI2L" %}
  6352   ins_encode(load_S_enc(dst, mem));
  6353   ins_pipe( ialu_loadI );
  6354 %}
  6356 // Store Integer Immediate
  6357 instruct storeImmI(memory mem, immI src) %{
  6358   match(Set mem (StoreI mem src));
  6360   ins_cost(150);
  6361   format %{ "mov    $mem, $src #@storeImmI" %}
  6362   ins_encode(store_I_immI_enc(mem, src));
  6363   ins_pipe( ialu_storeI );
  6364 %}
  6366 // Store Integer
  6367 instruct storeI(memory mem, mRegI src) %{
  6368   match(Set mem (StoreI mem src));
  6370   ins_cost(125);
  6371   format %{ "sw    $mem, $src #@storeI" %}
  6372   ins_encode(store_I_reg_enc(mem, src));
  6373   ins_pipe( ialu_storeI );
  6374 %}
  6376 instruct storeI_convL2I(memory mem, mRegL src) %{
  6377   match(Set mem (StoreI mem (ConvL2I src)));
  6379   ins_cost(125);
  6380   format %{ "sw    $mem, $src #@storeI_convL2I" %}
  6381   ins_encode(store_I_reg_enc(mem, src));
  6382   ins_pipe( ialu_storeI );
  6383 %}
  6385 // Load Float
  6386 instruct loadF(regF dst, memory mem) %{
  6387   match(Set dst (LoadF mem));
  6389   ins_cost(150);
  6390   format %{ "loadF $dst, $mem #@loadF" %}
  6391   ins_encode(load_F_enc(dst, mem));
  6392   ins_pipe( ialu_loadI );
  6393 %}
  6395 instruct loadConP_general(mRegP dst, immP src) %{
  6396   match(Set dst src);
  6398   ins_cost(120);
  6399   format %{ "li   $dst, $src #@loadConP_general" %}
  6401   ins_encode %{
  6402     Register dst = $dst$$Register;
  6403     long* value = (long*)$src$$constant;
  6405     if($src->constant_reloc() == relocInfo::metadata_type){
  6406       int klass_index = __ oop_recorder()->find_index((Klass*)value);
  6407       RelocationHolder rspec = metadata_Relocation::spec(klass_index);
  6409       __ relocate(rspec);
  6410       __ patchable_set48(dst, (long)value);
  6411     }else if($src->constant_reloc() == relocInfo::oop_type){
  6412       int oop_index = __ oop_recorder()->find_index((jobject)value);
  6413       RelocationHolder rspec = oop_Relocation::spec(oop_index);
  6415       __ relocate(rspec);
  6416       __ patchable_set48(dst, (long)value);
  6417     } else if ($src->constant_reloc() == relocInfo::none) {
  6418         __ set64(dst, (long)value);
  6420   %}
  6422   ins_pipe( ialu_regI_regI );
  6423 %}
  6425 /*
  6426 instruct loadConP_load(mRegP dst, immP_load src) %{
  6427   match(Set dst src);
  6429   ins_cost(100);
  6430   format %{ "ld     $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
  6432   ins_encode %{
  6434     int con_offset = $constantoffset($src);
  6436     if (Assembler::is_simm16(con_offset)) {
  6437        __ ld($dst$$Register, $constanttablebase, con_offset);
  6438     } else {
  6439        __ set64(AT, con_offset);
  6440        if (UseLoongsonISA) {
  6441           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6442        } else {
  6443           __ daddu(AT, $constanttablebase, AT);
  6444           __ ld($dst$$Register, AT, 0);
  6447   %}
  6449   ins_pipe(ialu_loadI);
  6450 %}
  6451 */
  6453 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
  6454   match(Set dst src);
  6456   ins_cost(80);
  6457   format %{ "li    $dst, $src @ loadConP_no_oop_cheap" %}
  6459   ins_encode %{
  6460     __ set64($dst$$Register, $src$$constant);
  6461   %}
  6463   ins_pipe(ialu_regI_regI);
  6464 %}
  6467 instruct loadConP_poll(mRegP dst, immP_poll src) %{
  6468   match(Set dst src);
  6470   ins_cost(50);
  6471   format %{ "li   $dst, $src #@loadConP_poll" %}
  6473   ins_encode %{
  6474     Register dst = $dst$$Register;
  6475     intptr_t value = (intptr_t)$src$$constant;
  6477     __ set64(dst, (jlong)value);
  6478   %}
  6480   ins_pipe( ialu_regI_regI );
  6481 %}
  6483 instruct loadConP0(mRegP dst, immP0 src)
  6484 %{
  6485   match(Set dst src);
  6487   ins_cost(50);
  6488   format %{ "mov    $dst, R0\t# ptr" %}
  6489   ins_encode %{
  6490      Register dst_reg = $dst$$Register;
  6491      __ daddu(dst_reg, R0, R0);
  6492   %}
  6493   ins_pipe( ialu_regI_regI );
  6494 %}
  6496 instruct loadConN0(mRegN dst, immN0 src) %{
  6497   match(Set dst src);
  6498   format %{ "move    $dst, R0\t# compressed NULL ptr" %}
  6499   ins_encode %{
  6500     __ move($dst$$Register, R0);
  6501   %}
  6502   ins_pipe( ialu_regI_regI );
  6503 %}
  6505 instruct loadConN(mRegN dst, immN src) %{
  6506   match(Set dst src);
  6508   ins_cost(125);
  6509   format %{ "li    $dst, $src\t# compressed ptr @ loadConN" %}
  6510   ins_encode %{
  6511     Register dst = $dst$$Register;
  6512     __ set_narrow_oop(dst, (jobject)$src$$constant);
  6513   %}
  6514   ins_pipe( ialu_regI_regI ); // XXX
  6515 %}
  6517 instruct loadConNKlass(mRegN dst, immNKlass src) %{
  6518   match(Set dst src);
  6520   ins_cost(125);
  6521   format %{ "li    $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
  6522   ins_encode %{
  6523     Register dst = $dst$$Register;
  6524     __ set_narrow_klass(dst, (Klass*)$src$$constant);
  6525   %}
  6526   ins_pipe( ialu_regI_regI ); // XXX
  6527 %}
  6529 //FIXME
  6530 // Tail Call; Jump from runtime stub to Java code.
  6531 // Also known as an 'interprocedural jump'.
  6532 // Target of jump will eventually return to caller.
  6533 // TailJump below removes the return address.
  6534 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
  6535   match(TailCall jump_target method_oop );
  6536   ins_cost(300);
  6537   format %{ "JMP    $jump_target \t# @TailCalljmpInd" %}
  6539   ins_encode %{
  6540     Register target = $jump_target$$Register;
  6541     Register    oop = $method_oop$$Register;
  6543     // RA will be used in generate_forward_exception()
  6544     __ push(RA);
  6546     __ move(S3, oop);
  6547     __ jr(target);
  6548     __ delayed()->nop();
  6549   %}
  6551   ins_pipe( pipe_jump );
  6552 %}
  6554 // Create exception oop: created by stack-crawling runtime code.
  6555 // Created exception is now available to this handler, and is setup
  6556 // just prior to jumping to this handler.  No code emitted.
  6557 instruct CreateException( a0_RegP ex_oop )
  6558 %{
  6559   match(Set ex_oop (CreateEx));
  6561   // use the following format syntax
  6562   format %{ "# exception oop is in A0; no code emitted @CreateException" %}
  6563   ins_encode %{
  6564     // X86 leaves this function empty
  6565     __ block_comment("CreateException is empty in MIPS");
  6566   %}
  6567   ins_pipe( empty );
  6568 //  ins_pipe( pipe_jump );
  6569 %}
  6572 /* The mechanism of exception handling is clear now.
  6574 - Common try/catch:
  6575   [stubGenerator_mips.cpp] generate_forward_exception()
  6576       |- V0, V1 are created
  6577       |- T9 <= SharedRuntime::exception_handler_for_return_address
  6578       `- jr T9
  6579            `- the caller's exception_handler
  6580                  `- jr OptoRuntime::exception_blob
  6581                         `- here
  6582 - Rethrow(e.g. 'unwind'):
  6583   * The callee:
  6584      |- an exception is triggered during execution
  6585      `- exits the callee method through RethrowException node
  6586           |- The callee pushes exception_oop(T0) and exception_pc(RA)
  6587           `- The callee jumps to OptoRuntime::rethrow_stub()
  6588   * In OptoRuntime::rethrow_stub:
  6589      |- The VM calls _rethrow_Java to determine the return address in the caller method
  6590      `- exits the stub with tailjmpInd
  6591           |- pops exception_oop(V0) and exception_pc(V1)
  6592           `- jumps to the return address(usually an exception_handler)
  6593   * The caller:
  6594      `- continues processing the exception_blob with V0/V1
  6595 */
  6597 /*
  6598 Disassembling OptoRuntime::rethrow_stub()
  6600 ; locals
  6601    0x2d3bf320: addiu sp, sp, 0xfffffff8
  6602    0x2d3bf324: sw ra, 0x4(sp)
  6603    0x2d3bf328: sw fp, 0x0(sp)
  6604    0x2d3bf32c: addu fp, sp, zero
  6605    0x2d3bf330: addiu sp, sp, 0xfffffff0
  6606    0x2d3bf334: sw ra, 0x8(sp)
  6607    0x2d3bf338: sw t0, 0x4(sp)
  6608    0x2d3bf33c: sw sp, 0x0(sp)
  6610 ; get_thread(S2)
  6611    0x2d3bf340: addu s2, sp, zero
  6612    0x2d3bf344: srl s2, s2, 12
  6613    0x2d3bf348: sll s2, s2, 2
  6614    0x2d3bf34c: lui at, 0x2c85
  6615    0x2d3bf350: addu at, at, s2
  6616    0x2d3bf354: lw s2, 0xffffcc80(at)
  6618    0x2d3bf358: lw s0, 0x0(sp)
  6619    0x2d3bf35c: sw s0, 0x118(s2)    // last_sp -> threa
  6620    0x2d3bf360: sw s2, 0xc(sp)
  6622 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
  6623    0x2d3bf364: lw a0, 0x4(sp)
  6624    0x2d3bf368: lw a1, 0xc(sp)
  6625    0x2d3bf36c: lw a2, 0x8(sp)
  6626   ;; Java_To_Runtime
  6627    0x2d3bf370: lui t9, 0x2c34
  6628    0x2d3bf374: addiu t9, t9, 0xffff8a48
  6629    0x2d3bf378: jalr t9
  6630    0x2d3bf37c: nop
  6632    0x2d3bf380: addu s3, v0, zero     ; S3: SharedRuntime::raw_exception_handler_for_return_address()
  6634    0x2d3bf384: lw s0, 0xc(sp)
  6635    0x2d3bf388: sw zero, 0x118(s0)
  6636    0x2d3bf38c: sw zero, 0x11c(s0)
  6637    0x2d3bf390: lw s1, 0x144(s0)      ; ex_oop: S1
  6638    0x2d3bf394: addu s2, s0, zero
  6639    0x2d3bf398: sw zero, 0x144(s2)
  6640    0x2d3bf39c: lw s0, 0x4(s2)
  6641    0x2d3bf3a0: addiu s4, zero, 0x0
  6642    0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
  6643    0x2d3bf3a8: nop
  6644    0x2d3bf3ac: addiu sp, sp, 0x10
  6645    0x2d3bf3b0: addiu sp, sp, 0x8
  6646    0x2d3bf3b4: lw ra, 0xfffffffc(sp)
  6647    0x2d3bf3b8: lw fp, 0xfffffff8(sp)
  6648    0x2d3bf3bc: lui at, 0x2b48
  6649    0x2d3bf3c0: lw at, 0x100(at)
  6651 ; tailjmpInd: Restores exception_oop & exception_pc
  6652    0x2d3bf3c4: addu v1, ra, zero
  6653    0x2d3bf3c8: addu v0, s1, zero
  6654    0x2d3bf3cc: jr s3
  6655    0x2d3bf3d0: nop
  6656 ; Exception:
  6657    0x2d3bf3d4: lui s1, 0x2cc8    ; generate_forward_exception()
  6658    0x2d3bf3d8: addiu s1, s1, 0x40
  6659    0x2d3bf3dc: addiu s2, zero, 0x0
  6660    0x2d3bf3e0: addiu sp, sp, 0x10
  6661    0x2d3bf3e4: addiu sp, sp, 0x8
  6662    0x2d3bf3e8: lw ra, 0xfffffffc(sp)
  6663    0x2d3bf3ec: lw fp, 0xfffffff8(sp)
  6664    0x2d3bf3f0: lui at, 0x2b48
  6665    0x2d3bf3f4: lw at, 0x100(at)
  6666 ; TailCalljmpInd
  6667               __ push(RA);    ; to be used in generate_forward_exception()
  6668    0x2d3bf3f8: addu t7, s2, zero
  6669    0x2d3bf3fc: jr s1
  6670    0x2d3bf400: nop
  6671 */
  6672 // Rethrow exception:
  6673 // The exception oop will come in the first argument position.
  6674 // Then JUMP (not call) to the rethrow stub code.
  6675 instruct RethrowException()
  6676 %{
  6677   match(Rethrow);
  6679   // use the following format syntax
  6680   format %{ "JMP    rethrow_stub #@RethrowException" %}
  6681   ins_encode %{
  6682     __ block_comment("@ RethrowException");
  6684     cbuf.set_insts_mark();
  6685     cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
  6687     // call OptoRuntime::rethrow_stub to get the exception handler in parent method
  6688     __ patchable_jump((address)OptoRuntime::rethrow_stub());
  6689   %}
  6690   ins_pipe( pipe_jump );
  6691 %}
  6693 // ============================================================================
  6694 // Branch Instructions --- long offset versions
  6696 // Jump Direct
  6697 instruct jmpDir_long(label labl) %{
  6698   match(Goto);
  6699   effect(USE labl);
  6701   ins_cost(300);
  6702   format %{ "JMP    $labl #@jmpDir_long" %}
  6704   ins_encode %{
  6705     Label* L = $labl$$label;
  6706     __ jmp_far(*L);
  6707   %}
  6709   ins_pipe( pipe_jump );
  6710   //ins_pc_relative(1);
  6711 %}
  6713 // Jump Direct Conditional - Label defines a relative address from Jcc+1
  6714 instruct  jmpLoopEnd_long(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
  6715   match(CountedLoopEnd cop (CmpI src1 src2));
  6716   effect(USE labl);
  6718   ins_cost(300);
  6719   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_long" %}
  6720   ins_encode %{
  6721     Register op1 = $src1$$Register;
  6722     Register op2 = $src2$$Register;
  6723     Label*     L = $labl$$label;
  6724     int     flag = $cop$$cmpcode;
  6726     switch(flag) {
  6727       case 0x01: //equal
  6728         __ beq_long(op1, op2, *L);
  6729         break;
  6730       case 0x02: //not_equal
  6731         __ bne_long(op1, op2, *L);
  6732         break;
  6733       case 0x03: //above
  6734         __ slt(AT, op2, op1);
  6735         __ bne_long(AT, R0, *L);
  6736         break;
  6737       case 0x04: //above_equal
  6738         __ slt(AT, op1, op2);
  6739         __ beq_long(AT, R0, *L);
  6740         break;
  6741       case 0x05: //below
  6742         __ slt(AT, op1, op2);
  6743         __ bne_long(AT, R0, *L);
  6744         break;
  6745       case 0x06: //below_equal
  6746         __ slt(AT, op2, op1);
  6747         __ beq_long(AT, R0, *L);
  6748         break;
  6749       default:
  6750         Unimplemented();
  6752   %}
  6753   ins_pipe( pipe_jump );
  6754   ins_pc_relative(1);
  6755 %}
  6757 instruct  jmpLoopEnd_reg_immI_long(cmpOp cop, mRegI src1, immI src2, label labl) %{
  6758   match(CountedLoopEnd cop (CmpI src1 src2));
  6759   effect(USE labl);
  6761   ins_cost(300);
  6762   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI_long" %}
  6763   ins_encode %{
  6764     Register op1 = $src1$$Register;
  6765     Register op2 = AT;
  6766     Label*     L = $labl$$label;
  6767     int     flag = $cop$$cmpcode;
  6769     __ move(op2, $src2$$constant);
  6771     switch(flag) {
  6772       case 0x01: //equal
  6773         __ beq_long(op1, op2, *L);
  6774         break;
  6775       case 0x02: //not_equal
  6776         __ bne_long(op1, op2, *L);
  6777         break;
  6778       case 0x03: //above
  6779         __ slt(AT, op2, op1);
  6780         __ bne_long(AT, R0, *L);
  6781         break;
  6782       case 0x04: //above_equal
  6783         __ slt(AT, op1, op2);
  6784         __ beq_long(AT, R0, *L);
  6785         break;
  6786       case 0x05: //below
  6787         __ slt(AT, op1, op2);
  6788         __ bne_long(AT, R0, *L);
  6789         break;
  6790       case 0x06: //below_equal
  6791         __ slt(AT, op2, op1);
  6792         __ beq_long(AT, R0, *L);
  6793         break;
  6794       default:
  6795         Unimplemented();
  6797   %}
  6798   ins_pipe( pipe_jump );
  6799   ins_pc_relative(1);
  6800 %}
  6803 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
  6804 instruct jmpCon_flags_long(cmpOp cop, FlagsReg cr, label labl) %{
  6805   match(If cop cr);
  6806   effect(USE labl);
  6808   ins_cost(300);
  6809   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags_long" %}
  6811   ins_encode %{
  6812     Label*    L =  $labl$$label;
  6813     switch($cop$$cmpcode) {
  6814       case 0x01: //equal
  6815         __ bne_long(AT, R0, *L);
  6816         break;
  6817       case 0x02: //not equal
  6818         __ beq_long(AT, R0, *L);
  6819         break;
  6820       default:
  6821         Unimplemented();
  6823   %}
  6825   ins_pipe( pipe_jump );
  6826   ins_pc_relative(1);
  6827 %}
  6829 // Conditional jumps
  6830 instruct branchConP_zero_long(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  6831   match(If cmp (CmpP op1 zero));
  6832   effect(USE labl);
  6834   ins_cost(180);
  6835   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero_long" %}
  6837   ins_encode %{
  6838     Register op1 = $op1$$Register;
  6839     Register op2 = R0;
  6840     Label*    L  = $labl$$label;
  6841     int     flag = $cmp$$cmpcode;
  6843     switch(flag) {
  6844       case 0x01: //equal
  6845         __ beq_long(op1, op2, *L);
  6846         break;
  6847       case 0x02: //not_equal
  6848         __ bne_long(op1, op2, *L);
  6849         break;
  6850       default:
  6851         Unimplemented();
  6853   %}
  6855   ins_pc_relative(1);
  6856   ins_pipe( pipe_alu_branch );
  6857 %}
  6859 instruct branchConN2P_zero_long(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  6860   match(If cmp (CmpP (DecodeN op1) zero));
  6861   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6862   effect(USE labl);
  6864   ins_cost(180);
  6865   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero_long" %}
  6867   ins_encode %{
  6868     Register op1 = $op1$$Register;
  6869     Register op2 = R0;
  6870     Label*    L  = $labl$$label;
  6871     int     flag = $cmp$$cmpcode;
  6873     switch(flag)
  6875       case 0x01: //equal
  6876         __ beq_long(op1, op2, *L);
  6877         break;
  6878       case 0x02: //not_equal
  6879         __ bne_long(op1, op2, *L);
  6880         break;
  6881       default:
  6882         Unimplemented();
  6884   %}
  6886   ins_pc_relative(1);
  6887   ins_pipe( pipe_alu_branch );
  6888 %}
  6891 instruct branchConP_long(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  6892   match(If cmp (CmpP op1 op2));
  6893 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  6894   effect(USE labl);
  6896   ins_cost(200);
  6897   format %{ "b$cmp   $op1, $op2, $labl #@branchConP_long" %}
  6899   ins_encode %{
  6900     Register op1 = $op1$$Register;
  6901     Register op2 = $op2$$Register;
  6902     Label*    L  = $labl$$label;
  6903     int     flag = $cmp$$cmpcode;
  6905     switch(flag) {
  6906       case 0x01: //equal
  6907         __ beq_long(op1, op2, *L);
  6908         break;
  6909       case 0x02: //not_equal
  6910         __ bne_long(op1, op2, *L);
  6911         break;
  6912       case 0x03: //above
  6913         __ sltu(AT, op2, op1);
  6914         __ bne_long(R0, AT, *L);
  6915         break;
  6916       case 0x04: //above_equal
  6917         __ sltu(AT, op1, op2);
  6918         __ beq_long(AT, R0, *L);
  6919         break;
  6920       case 0x05: //below
  6921         __ sltu(AT, op1, op2);
  6922         __ bne_long(R0, AT, *L);
  6923         break;
  6924       case 0x06: //below_equal
  6925         __ sltu(AT, op2, op1);
  6926         __ beq_long(AT, R0, *L);
  6927        break;
  6928       default:
  6929           Unimplemented();
  6931   %}
  6933   ins_pc_relative(1);
  6934   ins_pipe( pipe_alu_branch );
  6935 %}
  6937 instruct cmpN_null_branch_long(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  6938   match(If cmp (CmpN op1 null));
  6939   effect(USE labl);
  6941   ins_cost(180);
  6942   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  6943             "BP$cmp   $labl @ cmpN_null_branch_long" %}
  6944   ins_encode %{
  6945     Register op1 = $op1$$Register;
  6946     Register op2 = R0;
  6947     Label*    L  = $labl$$label;
  6948     int     flag = $cmp$$cmpcode;
  6950     switch(flag) {
  6951     case 0x01: //equal
  6952       __ beq_long(op1, op2, *L);
  6953       break;
  6954     case 0x02: //not_equal
  6955       __ bne_long(op1, op2, *L);
  6956       break;
  6957     default:
  6958           Unimplemented();
  6960   %}
  6961 //TODO: pipe_branchP or create pipe_branchN LEE
  6962   ins_pc_relative(1);
  6963   ins_pipe( pipe_alu_branch );
  6964 %}
  6966 instruct cmpN_reg_branch_long(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  6967   match(If cmp (CmpN op1 op2));
  6968   effect(USE labl);
  6970   ins_cost(180);
  6971   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  6972             "BP$cmp   $labl @ cmpN_reg_branch_long" %}
  6973   ins_encode %{
  6974     Register op1_reg = $op1$$Register;
  6975     Register op2_reg = $op2$$Register;
  6976     Label*    L  = $labl$$label;
  6977     int     flag = $cmp$$cmpcode;
  6979     switch(flag) {
  6980     case 0x01: //equal
  6981       __ beq_long(op1_reg, op2_reg, *L);
  6982       break;
  6983     case 0x02: //not_equal
  6984       __ bne_long(op1_reg, op2_reg, *L);
  6985       break;
  6986     case 0x03: //above
  6987       __ sltu(AT, op2_reg, op1_reg);
  6988       __ bne_long(R0, AT, *L);
  6989       break;
  6990     case 0x04: //above_equal
  6991       __ sltu(AT, op1_reg, op2_reg);
  6992       __ beq_long(AT, R0, *L);
  6993       break;
  6994     case 0x05: //below
  6995       __ sltu(AT, op1_reg, op2_reg);
  6996       __ bne_long(R0, AT, *L);
  6997       break;
  6998     case 0x06: //below_equal
  6999       __ sltu(AT, op2_reg, op1_reg);
  7000       __ beq_long(AT, R0, *L);
  7001       break;
  7002     default:
  7003       Unimplemented();
  7005   %}
  7006   ins_pc_relative(1);
  7007   ins_pipe( pipe_alu_branch );
  7008 %}
  7010 instruct branchConIU_reg_reg_long(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  7011   match( If cmp (CmpU src1 src2) );
  7012   effect(USE labl);
  7013   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg_long" %}
  7015   ins_encode %{
  7016     Register op1 = $src1$$Register;
  7017     Register op2 = $src2$$Register;
  7018     Label*     L = $labl$$label;
  7019     int     flag = $cmp$$cmpcode;
  7021     switch(flag) {
  7022       case 0x01: //equal
  7023         __ beq_long(op1, op2, *L);
  7024         break;
  7025       case 0x02: //not_equal
  7026         __ bne_long(op1, op2, *L);
  7027         break;
  7028       case 0x03: //above
  7029         __ sltu(AT, op2, op1);
  7030         __ bne_long(AT, R0, *L);
  7031         break;
  7032       case 0x04: //above_equal
  7033         __ sltu(AT, op1, op2);
  7034         __ beq_long(AT, R0, *L);
  7035         break;
  7036       case 0x05: //below
  7037         __ sltu(AT, op1, op2);
  7038         __ bne_long(AT, R0, *L);
  7039         break;
  7040       case 0x06: //below_equal
  7041         __ sltu(AT, op2, op1);
  7042         __ beq_long(AT, R0, *L);
  7043         break;
  7044       default:
  7045         Unimplemented();
  7047   %}
  7049   ins_pc_relative(1);
  7050   ins_pipe( pipe_alu_branch );
  7051 %}
  7054 instruct branchConIU_reg_imm_long(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  7055   match( If cmp (CmpU src1 src2) );
  7056   effect(USE labl);
  7057   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm_long" %}
  7059   ins_encode %{
  7060     Register op1 = $src1$$Register;
  7061     int      val = $src2$$constant;
  7062     Label*     L = $labl$$label;
  7063     int     flag = $cmp$$cmpcode;
  7065     __ move(AT, val);
  7066     switch(flag) {
  7067       case 0x01: //equal
  7068         __ beq_long(op1, AT, *L);
  7069         break;
  7070       case 0x02: //not_equal
  7071         __ bne_long(op1, AT, *L);
  7072         break;
  7073       case 0x03: //above
  7074         __ sltu(AT, AT, op1);
  7075         __ bne_long(R0, AT, *L);
  7076         break;
  7077       case 0x04: //above_equal
  7078         __ sltu(AT, op1, AT);
  7079         __ beq_long(AT, R0, *L);
  7080         break;
  7081       case 0x05: //below
  7082         __ sltu(AT, op1, AT);
  7083         __ bne_long(R0, AT, *L);
  7084         break;
  7085       case 0x06: //below_equal
  7086         __ sltu(AT, AT, op1);
  7087         __ beq_long(AT, R0, *L);
  7088        break;
  7089       default:
  7090         Unimplemented();
  7092   %}
  7094   ins_pc_relative(1);
  7095   ins_pipe( pipe_alu_branch );
  7096 %}
  7098 instruct branchConI_reg_reg_long(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  7099   match( If cmp (CmpI src1 src2) );
  7100   effect(USE labl);
  7101   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg_long" %}
  7103   ins_encode %{
  7104     Register op1 = $src1$$Register;
  7105     Register op2 = $src2$$Register;
  7106     Label*     L = $labl$$label;
  7107     int     flag = $cmp$$cmpcode;
  7109     switch(flag) {
  7110       case 0x01: //equal
  7111         __ beq_long(op1, op2, *L);
  7112         break;
  7113       case 0x02: //not_equal
  7114         __ bne_long(op1, op2, *L);
  7115         break;
  7116       case 0x03: //above
  7117         __ slt(AT, op2, op1);
  7118         __ bne_long(R0, AT, *L);
  7119         break;
  7120       case 0x04: //above_equal
  7121         __ slt(AT, op1, op2);
  7122         __ beq_long(AT, R0, *L);
  7123         break;
  7124       case 0x05: //below
  7125         __ slt(AT, op1, op2);
  7126         __ bne_long(R0, AT, *L);
  7127         break;
  7128       case 0x06: //below_equal
  7129         __ slt(AT, op2, op1);
  7130         __ beq_long(AT, R0, *L);
  7131         break;
  7132       default:
  7133         Unimplemented();
  7135   %}
  7137   ins_pc_relative(1);
  7138   ins_pipe( pipe_alu_branch );
  7139 %}
  7141 instruct branchConI_reg_imm0_long(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  7142   match( If cmp (CmpI src1 src2) );
  7143   effect(USE labl);
  7144   ins_cost(170);
  7145   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0_long" %}
  7147   ins_encode %{
  7148     Register op1 = $src1$$Register;
  7149     Label*     L =  $labl$$label;
  7150     int     flag = $cmp$$cmpcode;
  7152     switch(flag) {
  7153       case 0x01: //equal
  7154         __ beq_long(op1, R0, *L);
  7155         break;
  7156       case 0x02: //not_equal
  7157         __ bne_long(op1, R0, *L);
  7158         break;
  7159       case 0x03: //greater
  7160         __ slt(AT, R0, op1);
  7161         __ bne_long(R0, AT, *L);
  7162         break;
  7163       case 0x04: //greater_equal
  7164         __ slt(AT, op1, R0);
  7165         __ beq_long(AT, R0, *L);
  7166         break;
  7167       case 0x05: //less
  7168         __ slt(AT, op1, R0);
  7169         __ bne_long(R0, AT, *L);
  7170         break;
  7171       case 0x06: //less_equal
  7172         __ slt(AT, R0, op1);
  7173         __ beq_long(AT, R0, *L);
  7174         break;
  7175       default:
  7176         Unimplemented();
  7178   %}
  7180   ins_pc_relative(1);
  7181   ins_pipe( pipe_alu_branch );
  7182 %}
  7184 instruct branchConI_reg_imm_long(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  7185   match( If cmp (CmpI src1 src2) );
  7186   effect(USE labl);
  7187   ins_cost(200);
  7188   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm_long" %}
  7190   ins_encode %{
  7191     Register op1 = $src1$$Register;
  7192     int      val = $src2$$constant;
  7193     Label*     L =  $labl$$label;
  7194     int     flag = $cmp$$cmpcode;
  7196     __ move(AT, val);
  7197     switch(flag) {
  7198       case 0x01: //equal
  7199         __ beq_long(op1, AT, *L);
  7200         break;
  7201       case 0x02: //not_equal
  7202         __ bne_long(op1, AT, *L);
  7203         break;
  7204       case 0x03: //greater
  7205         __ slt(AT, AT, op1);
  7206         __ bne_long(R0, AT, *L);
  7207         break;
  7208       case 0x04: //greater_equal
  7209         __ slt(AT, op1, AT);
  7210         __ beq_long(AT, R0, *L);
  7211         break;
  7212       case 0x05: //less
  7213         __ slt(AT, op1, AT);
  7214         __ bne_long(R0, AT, *L);
  7215         break;
  7216       case 0x06: //less_equal
  7217         __ slt(AT, AT, op1);
  7218         __ beq_long(AT, R0, *L);
  7219        break;
  7220       default:
  7221           Unimplemented();
  7223   %}
  7225   ins_pc_relative(1);
  7226   ins_pipe( pipe_alu_branch );
  7227 %}
  7229 instruct branchConIU_reg_imm0_long(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  7230   match( If cmp (CmpU src1 zero) );
  7231   effect(USE labl);
  7232   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0_long" %}
  7234   ins_encode %{
  7235     Register op1 = $src1$$Register;
  7236     Label*     L = $labl$$label;
  7237     int     flag = $cmp$$cmpcode;
  7239     switch(flag) {
  7240       case 0x01: //equal
  7241         __ beq_long(op1, R0, *L);
  7242         break;
  7243       case 0x02: //not_equal
  7244         __ bne_long(op1, R0, *L);
  7245         break;
  7246       case 0x03: //above
  7247         __ bne_long(R0, op1, *L);
  7248         break;
  7249       case 0x04: //above_equal
  7250         __ beq_long(R0, R0, *L);
  7251         break;
  7252       case 0x05: //below
  7253         return;
  7254         break;
  7255       case 0x06: //below_equal
  7256         __ beq_long(op1, R0, *L);
  7257         break;
  7258       default:
  7259         Unimplemented();
  7261   %}
  7263   ins_pc_relative(1);
  7264   ins_pipe( pipe_alu_branch );
  7265 %}
  7268 instruct branchConIU_reg_immI16_long(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  7269   match( If cmp (CmpU src1 src2) );
  7270   effect(USE labl);
  7271   ins_cost(180);
  7272   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16_long" %}
  7274   ins_encode %{
  7275     Register op1 = $src1$$Register;
  7276     int      val = $src2$$constant;
  7277     Label*     L = $labl$$label;
  7278     int     flag = $cmp$$cmpcode;
  7280     switch(flag) {
  7281       case 0x01: //equal
  7282         __ move(AT, val);
  7283         __ beq_long(op1, AT, *L);
  7284         break;
  7285       case 0x02: //not_equal
  7286         __ move(AT, val);
  7287         __ bne_long(op1, AT, *L);
  7288         break;
  7289       case 0x03: //above
  7290         __ move(AT, val);
  7291         __ sltu(AT, AT, op1);
  7292         __ bne_long(R0, AT, *L);
  7293         break;
  7294       case 0x04: //above_equal
  7295         __ sltiu(AT, op1, val);
  7296         __ beq_long(AT, R0, *L);
  7297         break;
  7298       case 0x05: //below
  7299         __ sltiu(AT, op1, val);
  7300         __ bne_long(R0, AT, *L);
  7301         break;
  7302       case 0x06: //below_equal
  7303         __ move(AT, val);
  7304         __ sltu(AT, AT, op1);
  7305         __ beq_long(AT, R0, *L);
  7306         break;
  7307       default:
  7308         Unimplemented();
  7310   %}
  7312   ins_pc_relative(1);
  7313   ins_pipe( pipe_alu_branch );
  7314 %}
  7317 instruct branchConL_regL_regL_long(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  7318   match( If cmp (CmpL src1 src2) );
  7319   effect(USE labl);
  7320   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL_long" %}
  7321   ins_cost(250);
  7323   ins_encode %{
  7324     Register opr1_reg = as_Register($src1$$reg);
  7325     Register opr2_reg = as_Register($src2$$reg);
  7327     Label*   target = $labl$$label;
  7328     int     flag = $cmp$$cmpcode;
  7330     switch(flag) {
  7331       case 0x01: //equal
  7332         __ beq_long(opr1_reg, opr2_reg, *target);
  7333         break;
  7335       case 0x02: //not_equal
  7336         __ bne_long(opr1_reg, opr2_reg, *target);
  7337         break;
  7339       case 0x03: //greater
  7340         __ slt(AT, opr2_reg, opr1_reg);
  7341         __ bne_long(AT, R0, *target);
  7342         break;
  7344       case 0x04: //greater_equal
  7345         __ slt(AT, opr1_reg, opr2_reg);
  7346         __ beq_long(AT, R0, *target);
  7347         break;
  7349       case 0x05: //less
  7350         __ slt(AT, opr1_reg, opr2_reg);
  7351         __ bne_long(AT, R0, *target);
  7352         break;
  7354       case 0x06: //less_equal
  7355         __ slt(AT, opr2_reg, opr1_reg);
  7356         __ beq_long(AT, R0, *target);
  7357         break;
  7359       default:
  7360         Unimplemented();
  7362   %}
  7365   ins_pc_relative(1);
  7366   ins_pipe( pipe_alu_branch );
  7367 %}
  7369 instruct branchConL_regL_immL0_long(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  7370   match( If cmp (CmpL src1 zero) );
  7371   effect(USE labl);
  7372   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0_long" %}
  7373   ins_cost(150);
  7375   ins_encode %{
  7376     Register opr1_reg = as_Register($src1$$reg);
  7377     Register opr2_reg = R0;
  7379     Label*   target = $labl$$label;
  7380     int     flag = $cmp$$cmpcode;
  7382     switch(flag) {
  7383       case 0x01: //equal
  7384         __ beq_long(opr1_reg, opr2_reg, *target);
  7385         break;
  7387       case 0x02: //not_equal
  7388         __ bne_long(opr1_reg, opr2_reg, *target);
  7389         break;
  7391       case 0x03: //greater
  7392         __ slt(AT, opr2_reg, opr1_reg);
  7393         __ bne_long(AT, R0, *target);
  7394         break;
  7396       case 0x04: //greater_equal
  7397         __ slt(AT, opr1_reg, opr2_reg);
  7398         __ beq_long(AT, R0, *target);
  7399         break;
  7401       case 0x05: //less
  7402         __ slt(AT, opr1_reg, opr2_reg);
  7403         __ bne_long(AT, R0, *target);
  7404         break;
  7406       case 0x06: //less_equal
  7407         __ slt(AT, opr2_reg, opr1_reg);
  7408         __ beq_long(AT, R0, *target);
  7409         break;
  7411       default:
  7412         Unimplemented();
  7414   %}
  7417   ins_pc_relative(1);
  7418   ins_pipe( pipe_alu_branch );
  7419 %}
  7421 instruct branchConL_regL_immL_long(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  7422   match( If cmp (CmpL src1 src2) );
  7423   effect(USE labl);
  7424   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL_long" %}
  7425   ins_cost(180);
  7427   ins_encode %{
  7428     Register opr1_reg = as_Register($src1$$reg);
  7429     Register opr2_reg = AT;
  7431     Label*   target = $labl$$label;
  7432     int     flag = $cmp$$cmpcode;
  7434     __ set64(opr2_reg, $src2$$constant);
  7436     switch(flag) {
  7437       case 0x01: //equal
  7438         __ beq_long(opr1_reg, opr2_reg, *target);
  7439         break;
  7441       case 0x02: //not_equal
  7442         __ bne_long(opr1_reg, opr2_reg, *target);
  7443         break;
  7445       case 0x03: //greater
  7446         __ slt(AT, opr2_reg, opr1_reg);
  7447         __ bne_long(AT, R0, *target);
  7448         break;
  7450       case 0x04: //greater_equal
  7451         __ slt(AT, opr1_reg, opr2_reg);
  7452         __ beq_long(AT, R0, *target);
  7453         break;
  7455       case 0x05: //less
  7456         __ slt(AT, opr1_reg, opr2_reg);
  7457         __ bne_long(AT, R0, *target);
  7458         break;
  7460       case 0x06: //less_equal
  7461         __ slt(AT, opr2_reg, opr1_reg);
  7462         __ beq_long(AT, R0, *target);
  7463         break;
  7465       default:
  7466         Unimplemented();
  7468   %}
  7471   ins_pc_relative(1);
  7472   ins_pipe( pipe_alu_branch );
  7473 %}
  7476 //FIXME
  7477 instruct branchConF_reg_reg_long(cmpOp cmp, regF src1, regF src2, label labl) %{
  7478   match( If cmp (CmpF src1 src2) );
  7479   effect(USE labl);
  7480   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg_long" %}
  7482   ins_encode %{
  7483     FloatRegister reg_op1 = $src1$$FloatRegister;
  7484     FloatRegister reg_op2 = $src2$$FloatRegister;
  7485     Label*     L =  $labl$$label;
  7486     int     flag = $cmp$$cmpcode;
  7488     switch(flag) {
  7489       case 0x01: //equal
  7490         __ c_eq_s(reg_op1, reg_op2);
  7491         __ bc1t_long(*L);
  7492         break;
  7493       case 0x02: //not_equal
  7494         __ c_eq_s(reg_op1, reg_op2);
  7495         __ bc1f_long(*L);
  7496         break;
  7497       case 0x03: //greater
  7498         __ c_ule_s(reg_op1, reg_op2);
  7499         __ bc1f_long(*L);
  7500         break;
  7501       case 0x04: //greater_equal
  7502         __ c_ult_s(reg_op1, reg_op2);
  7503         __ bc1f_long(*L);
  7504         break;
  7505       case 0x05: //less
  7506         __ c_ult_s(reg_op1, reg_op2);
  7507         __ bc1t_long(*L);
  7508         break;
  7509       case 0x06: //less_equal
  7510         __ c_ule_s(reg_op1, reg_op2);
  7511         __ bc1t_long(*L);
  7512         break;
  7513       default:
  7514         Unimplemented();
  7516   %}
  7518   ins_pc_relative(1);
  7519   ins_pipe(pipe_slow);
  7520 %}
  7522 instruct branchConD_reg_reg_long(cmpOp cmp, regD src1, regD src2, label labl) %{
  7523   match( If cmp (CmpD src1 src2) );
  7524   effect(USE labl);
  7525   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg_long" %}
  7527   ins_encode %{
  7528     FloatRegister reg_op1 = $src1$$FloatRegister;
  7529     FloatRegister reg_op2 = $src2$$FloatRegister;
  7530     Label*     L =  $labl$$label;
  7531     int     flag = $cmp$$cmpcode;
  7533     switch(flag) {
  7534       case 0x01: //equal
  7535         __ c_eq_d(reg_op1, reg_op2);
  7536         __ bc1t_long(*L);
  7537         break;
  7538       case 0x02: //not_equal
  7539         // 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.
  7540         __ c_eq_d(reg_op1, reg_op2);
  7541         __ bc1f_long(*L);
  7542         break;
  7543       case 0x03: //greater
  7544         __ c_ule_d(reg_op1, reg_op2);
  7545         __ bc1f_long(*L);
  7546         break;
  7547       case 0x04: //greater_equal
  7548         __ c_ult_d(reg_op1, reg_op2);
  7549         __ bc1f_long(*L);
  7550         break;
  7551       case 0x05: //less
  7552         __ c_ult_d(reg_op1, reg_op2);
  7553         __ bc1t_long(*L);
  7554         break;
  7555       case 0x06: //less_equal
  7556         __ c_ule_d(reg_op1, reg_op2);
  7557         __ bc1t_long(*L);
  7558         break;
  7559       default:
  7560         Unimplemented();
  7562   %}
  7564   ins_pc_relative(1);
  7565   ins_pipe(pipe_slow);
  7566 %}
  7569 // ============================================================================
  7570 // Branch Instructions -- short offset versions
  7572 // Jump Direct
  7573 instruct jmpDir_short(label labl) %{
  7574   match(Goto);
  7575   effect(USE labl);
  7577   ins_cost(300);
  7578   format %{ "JMP    $labl #@jmpDir_short" %}
  7580   ins_encode %{
  7581     Label &L = *($labl$$label);
  7582     if(&L)
  7583        __ b(L);
  7584     else
  7585        __ b(int(0));
  7586     __ delayed()->nop();
  7587   %}
  7589     ins_pipe( pipe_jump );
  7590     ins_pc_relative(1);
  7591     ins_short_branch(1);
  7592 %}
  7594 // Jump Direct Conditional - Label defines a relative address from Jcc+1
  7595 instruct  jmpLoopEnd_short(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
  7596   match(CountedLoopEnd cop (CmpI src1 src2));
  7597   effect(USE labl);
  7599   ins_cost(300);
  7600   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_short" %}
  7601   ins_encode %{
  7602     Register op1 = $src1$$Register;
  7603     Register op2 = $src2$$Register;
  7604     Label     &L = *($labl$$label);
  7605     int     flag = $cop$$cmpcode;
  7607     switch(flag) {
  7608       case 0x01: //equal
  7609         if (&L)
  7610           __ beq(op1, op2, L);
  7611         else
  7612           __ beq(op1, op2, (int)0);
  7613         break;
  7614       case 0x02: //not_equal
  7615         if (&L)
  7616           __ bne(op1, op2, L);
  7617         else
  7618           __ bne(op1, op2, (int)0);
  7619         break;
  7620       case 0x03: //above
  7621         __ slt(AT, op2, op1);
  7622         if(&L)
  7623           __ bne(AT, R0, L);
  7624         else
  7625           __ bne(AT, R0, (int)0);
  7626         break;
  7627       case 0x04: //above_equal
  7628         __ slt(AT, op1, op2);
  7629         if(&L)
  7630           __ beq(AT, R0, L);
  7631         else
  7632           __ beq(AT, R0, (int)0);
  7633         break;
  7634       case 0x05: //below
  7635         __ slt(AT, op1, op2);
  7636         if(&L)
  7637           __ bne(AT, R0, L);
  7638         else
  7639           __ bne(AT, R0, (int)0);
  7640         break;
  7641       case 0x06: //below_equal
  7642         __ slt(AT, op2, op1);
  7643         if(&L)
  7644           __ beq(AT, R0, L);
  7645         else
  7646           __ beq(AT, R0, (int)0);
  7647         break;
  7648       default:
  7649         Unimplemented();
  7651     __ delayed()->nop();
  7652   %}
  7653   ins_pipe( pipe_jump );
  7654   ins_pc_relative(1);
  7655   ins_short_branch(1);
  7656 %}
  7658 instruct  jmpLoopEnd_reg_immI_short(cmpOp cop, mRegI src1, immI src2, label labl) %{
  7659   match(CountedLoopEnd cop (CmpI src1 src2));
  7660   effect(USE labl);
  7662   ins_cost(300);
  7663   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI_short" %}
  7664   ins_encode %{
  7665     Register op1 = $src1$$Register;
  7666     Register op2 = AT;
  7667     Label     &L = *($labl$$label);
  7668     int     flag = $cop$$cmpcode;
  7670     __ move(op2, $src2$$constant);
  7672     switch(flag) {
  7673       case 0x01: //equal
  7674         if (&L)
  7675           __ beq(op1, op2, L);
  7676         else
  7677           __ beq(op1, op2, (int)0);
  7678         break;
  7679       case 0x02: //not_equal
  7680         if (&L)
  7681           __ bne(op1, op2, L);
  7682         else
  7683           __ bne(op1, op2, (int)0);
  7684         break;
  7685       case 0x03: //above
  7686         __ slt(AT, op2, op1);
  7687         if(&L)
  7688           __ bne(AT, R0, L);
  7689         else
  7690           __ bne(AT, R0, (int)0);
  7691         break;
  7692       case 0x04: //above_equal
  7693         __ slt(AT, op1, op2);
  7694         if(&L)
  7695           __ beq(AT, R0, L);
  7696         else
  7697           __ beq(AT, R0, (int)0);
  7698         break;
  7699       case 0x05: //below
  7700         __ slt(AT, op1, op2);
  7701         if(&L)
  7702           __ bne(AT, R0, L);
  7703         else
  7704           __ bne(AT, R0, (int)0);
  7705         break;
  7706       case 0x06: //below_equal
  7707         __ slt(AT, op2, op1);
  7708         if(&L)
  7709           __ beq(AT, R0, L);
  7710         else
  7711           __ beq(AT, R0, (int)0);
  7712         break;
  7713       default:
  7714         Unimplemented();
  7716     __ delayed()->nop();
  7717   %}
  7718   ins_pipe( pipe_jump );
  7719   ins_pc_relative(1);
  7720   ins_short_branch(1);
  7721 %}
  7724 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
  7725 instruct jmpCon_flags_short(cmpOp cop, FlagsReg cr, label labl) %{
  7726   match(If cop cr);
  7727   effect(USE labl);
  7729   ins_cost(300);
  7730   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags_short" %}
  7732   ins_encode %{
  7733     Label    &L =  *($labl$$label);
  7734     switch($cop$$cmpcode) {
  7735       case 0x01: //equal
  7736         if (&L)
  7737           __ bne(AT, R0, L);
  7738         else
  7739           __ bne(AT, R0, (int)0);
  7740         break;
  7741       case 0x02: //not equal
  7742         if (&L)
  7743           __ beq(AT, R0, L);
  7744         else
  7745           __ beq(AT, R0, (int)0);
  7746         break;
  7747       default:
  7748         Unimplemented();
  7750     __ delayed()->nop();
  7751   %}
  7753   ins_pipe( pipe_jump );
  7754   ins_pc_relative(1);
  7755   ins_short_branch(1);
  7756 %}
  7758 // Conditional jumps
  7759 instruct branchConP_zero_short(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  7760   match(If cmp (CmpP op1 zero));
  7761   effect(USE labl);
  7763   ins_cost(180);
  7764   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero_short" %}
  7766   ins_encode %{
  7767     Register op1 = $op1$$Register;
  7768     Register op2 = R0;
  7769     Label    &L  = *($labl$$label);
  7770     int     flag = $cmp$$cmpcode;
  7772     switch(flag) {
  7773       case 0x01: //equal
  7774         if (&L)
  7775           __ beq(op1, op2, L);
  7776         else
  7777           __ beq(op1, op2, (int)0);
  7778         break;
  7779       case 0x02: //not_equal
  7780         if (&L)
  7781           __ bne(op1, op2, L);
  7782         else
  7783           __ bne(op1, op2, (int)0);
  7784         break;
  7785       default:
  7786         Unimplemented();
  7788     __ delayed()->nop();
  7789   %}
  7791   ins_pc_relative(1);
  7792   ins_pipe( pipe_alu_branch );
  7793   ins_short_branch(1);
  7794 %}
  7796 instruct branchConN2P_zero_short(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  7797   match(If cmp (CmpP (DecodeN op1) zero));
  7798   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  7799   effect(USE labl);
  7801   ins_cost(180);
  7802   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero_short" %}
  7804   ins_encode %{
  7805     Register op1 = $op1$$Register;
  7806     Register op2 = R0;
  7807     Label    &L  = *($labl$$label);
  7808     int     flag = $cmp$$cmpcode;
  7810     switch(flag)
  7812       case 0x01: //equal
  7813         if (&L)
  7814           __ beq(op1, op2, L);
  7815         else
  7816           __ beq(op1, op2, (int)0);
  7817         break;
  7818       case 0x02: //not_equal
  7819         if (&L)
  7820           __ bne(op1, op2, L);
  7821         else
  7822           __ bne(op1, op2, (int)0);
  7823         break;
  7824       default:
  7825         Unimplemented();
  7827     __ delayed()->nop();
  7828   %}
  7830   ins_pc_relative(1);
  7831   ins_pipe( pipe_alu_branch );
  7832   ins_short_branch(1);
  7833 %}
  7836 instruct branchConP_short(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  7837   match(If cmp (CmpP op1 op2));
  7838 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  7839   effect(USE labl);
  7841   ins_cost(200);
  7842   format %{ "b$cmp   $op1, $op2, $labl #@branchConP_short" %}
  7844   ins_encode %{
  7845     Register op1 = $op1$$Register;
  7846     Register op2 = $op2$$Register;
  7847     Label    &L  = *($labl$$label);
  7848     int     flag = $cmp$$cmpcode;
  7850     switch(flag) {
  7851       case 0x01: //equal
  7852         if (&L)
  7853           __ beq(op1, op2, L);
  7854         else
  7855           __ beq(op1, op2, (int)0);
  7856         break;
  7857       case 0x02: //not_equal
  7858         if (&L)
  7859           __ bne(op1, op2, L);
  7860         else
  7861           __ bne(op1, op2, (int)0);
  7862         break;
  7863       case 0x03: //above
  7864         __ sltu(AT, op2, op1);
  7865         if(&L)
  7866           __ bne(R0, AT, L);
  7867         else
  7868                 __ bne(R0, AT, (int)0);
  7869         break;
  7870       case 0x04: //above_equal
  7871         __ sltu(AT, op1, op2);
  7872         if(&L)
  7873                  __ beq(AT, R0, L);
  7874         else
  7875                  __ beq(AT, R0, (int)0);
  7876         break;
  7877       case 0x05: //below
  7878         __ sltu(AT, op1, op2);
  7879         if(&L)
  7880            __ bne(R0, AT, L);
  7881         else
  7882            __ bne(R0, AT, (int)0);
  7883         break;
  7884       case 0x06: //below_equal
  7885         __ sltu(AT, op2, op1);
  7886         if(&L)
  7887           __ beq(AT, R0, L);
  7888         else
  7889           __ beq(AT, R0, (int)0);
  7890        break;
  7891       default:
  7892           Unimplemented();
  7894     __ delayed()->nop();
  7895   %}
  7897   ins_pc_relative(1);
  7898   ins_pipe( pipe_alu_branch );
  7899   ins_short_branch(1);
  7900 %}
  7902 instruct cmpN_null_branch_short(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  7903   match(If cmp (CmpN op1 null));
  7904   effect(USE labl);
  7906   ins_cost(180);
  7907   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  7908             "BP$cmp   $labl @ cmpN_null_branch_short" %}
  7909   ins_encode %{
  7910     Register op1 = $op1$$Register;
  7911     Register op2 = R0;
  7912     Label    &L  = *($labl$$label);
  7913     int     flag = $cmp$$cmpcode;
  7915     switch(flag) {
  7916     case 0x01: //equal
  7917       if (&L)
  7918         __ beq(op1, op2, L);
  7919       else
  7920         __ beq(op1, op2, (int)0);
  7921       break;
  7922     case 0x02: //not_equal
  7923       if (&L)
  7924         __ bne(op1, op2, L);
  7925       else
  7926         __ bne(op1, op2, (int)0);
  7927       break;
  7928     default:
  7929           Unimplemented();
  7931     __ delayed()->nop();
  7932   %}
  7933 //TODO: pipe_branchP or create pipe_branchN LEE
  7934   ins_pc_relative(1);
  7935   ins_pipe( pipe_alu_branch );
  7936   ins_short_branch(1);
  7937 %}
  7939 instruct cmpN_reg_branch_short(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  7940   match(If cmp (CmpN op1 op2));
  7941   effect(USE labl);
  7943   ins_cost(180);
  7944   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  7945             "BP$cmp   $labl @ cmpN_reg_branch_short" %}
  7946   ins_encode %{
  7947     Register op1_reg = $op1$$Register;
  7948     Register op2_reg = $op2$$Register;
  7949     Label    &L  = *($labl$$label);
  7950     int     flag = $cmp$$cmpcode;
  7952     switch(flag) {
  7953     case 0x01: //equal
  7954       if (&L)
  7955         __ beq(op1_reg, op2_reg, L);
  7956       else
  7957         __ beq(op1_reg, op2_reg, (int)0);
  7958       break;
  7959     case 0x02: //not_equal
  7960       if (&L)
  7961         __ bne(op1_reg, op2_reg, L);
  7962       else
  7963         __ bne(op1_reg, op2_reg, (int)0);
  7964       break;
  7965     case 0x03: //above
  7966       __ sltu(AT, op2_reg, op1_reg);
  7967       if(&L)
  7968         __ bne(R0, AT, L);
  7969       else
  7970         __ bne(R0, AT, (int)0);
  7971       break;
  7972     case 0x04: //above_equal
  7973       __ sltu(AT, op1_reg, op2_reg);
  7974       if(&L)
  7975         __ beq(AT, R0, L);
  7976       else
  7977         __ beq(AT, R0, (int)0);
  7978       break;
  7979     case 0x05: //below
  7980       __ sltu(AT, op1_reg, op2_reg);
  7981       if(&L)
  7982         __ bne(R0, AT, L);
  7983       else
  7984         __ bne(R0, AT, (int)0);
  7985       break;
  7986     case 0x06: //below_equal
  7987       __ sltu(AT, op2_reg, op1_reg);
  7988       if(&L)
  7989         __ beq(AT, R0, L);
  7990       else
  7991         __ beq(AT, R0, (int)0);
  7992       break;
  7993     default:
  7994       Unimplemented();
  7996     __ delayed()->nop();
  7997   %}
  7998   ins_pc_relative(1);
  7999   ins_pipe( pipe_alu_branch );
  8000   ins_short_branch(1);
  8001 %}
  8003 instruct branchConIU_reg_reg_short(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  8004   match( If cmp (CmpU src1 src2) );
  8005   effect(USE labl);
  8006   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg_short" %}
  8008   ins_encode %{
  8009     Register op1 = $src1$$Register;
  8010     Register op2 = $src2$$Register;
  8011     Label     &L = *($labl$$label);
  8012     int     flag = $cmp$$cmpcode;
  8014     switch(flag) {
  8015       case 0x01: //equal
  8016         if (&L)
  8017           __ beq(op1, op2, L);
  8018         else
  8019           __ beq(op1, op2, (int)0);
  8020         break;
  8021       case 0x02: //not_equal
  8022         if (&L)
  8023           __ bne(op1, op2, L);
  8024         else
  8025           __ bne(op1, op2, (int)0);
  8026         break;
  8027       case 0x03: //above
  8028         __ sltu(AT, op2, op1);
  8029         if(&L)
  8030           __ bne(AT, R0, L);
  8031         else
  8032                 __ bne(AT, R0, (int)0);
  8033         break;
  8034       case 0x04: //above_equal
  8035         __ sltu(AT, op1, op2);
  8036         if(&L)
  8037           __ beq(AT, R0, L);
  8038         else
  8039                 __ beq(AT, R0, (int)0);
  8040         break;
  8041       case 0x05: //below
  8042         __ sltu(AT, op1, op2);
  8043         if(&L)
  8044            __ bne(AT, R0, L);
  8045         else
  8046            __ bne(AT, R0, (int)0);
  8047         break;
  8048       case 0x06: //below_equal
  8049         __ sltu(AT, op2, op1);
  8050         if(&L)
  8051           __ beq(AT, R0, L);
  8052         else
  8053           __ beq(AT, R0, (int)0);
  8054         break;
  8055       default:
  8056         Unimplemented();
  8058     __ delayed()->nop();
  8059   %}
  8061   ins_pc_relative(1);
  8062   ins_pipe( pipe_alu_branch );
  8063   ins_short_branch(1);
  8064 %}
  8067 instruct branchConIU_reg_imm_short(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  8068   match( If cmp (CmpU src1 src2) );
  8069   effect(USE labl);
  8070   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm_short" %}
  8072   ins_encode %{
  8073     Register op1 = $src1$$Register;
  8074     int      val = $src2$$constant;
  8075     Label     &L = *($labl$$label);
  8076     int     flag = $cmp$$cmpcode;
  8078     __ move(AT, val);
  8079     switch(flag) {
  8080       case 0x01: //equal
  8081         if (&L)
  8082           __ beq(op1, AT, L);
  8083         else
  8084           __ beq(op1, AT, (int)0);
  8085         break;
  8086       case 0x02: //not_equal
  8087         if (&L)
  8088           __ bne(op1, AT, L);
  8089         else
  8090           __ bne(op1, AT, (int)0);
  8091         break;
  8092       case 0x03: //above
  8093         __ sltu(AT, AT, op1);
  8094         if(&L)
  8095           __ bne(R0, AT, L);
  8096         else
  8097                 __ bne(R0, AT, (int)0);
  8098         break;
  8099       case 0x04: //above_equal
  8100         __ sltu(AT, op1, AT);
  8101         if(&L)
  8102           __ beq(AT, R0, L);
  8103         else
  8104                 __ beq(AT, R0, (int)0);
  8105         break;
  8106       case 0x05: //below
  8107         __ sltu(AT, op1, AT);
  8108         if(&L)
  8109            __ bne(R0, AT, L);
  8110         else
  8111            __ bne(R0, AT, (int)0);
  8112         break;
  8113       case 0x06: //below_equal
  8114         __ sltu(AT, AT, op1);
  8115         if(&L)
  8116           __ beq(AT, R0, L);
  8117         else
  8118           __ beq(AT, R0, (int)0);
  8119        break;
  8120       default:
  8121         Unimplemented();
  8123     __ delayed()->nop();
  8124   %}
  8126   ins_pc_relative(1);
  8127   ins_pipe( pipe_alu_branch );
  8128   ins_short_branch(1);
  8129 %}
  8131 instruct branchConI_reg_reg_short(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  8132   match( If cmp (CmpI src1 src2) );
  8133   effect(USE labl);
  8134   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg_short" %}
  8136   ins_encode %{
  8137     Register op1 = $src1$$Register;
  8138     Register op2 = $src2$$Register;
  8139     Label     &L = *($labl$$label);
  8140     int     flag = $cmp$$cmpcode;
  8142     switch(flag) {
  8143       case 0x01: //equal
  8144         if (&L)
  8145           __ beq(op1, op2, L);
  8146         else
  8147           __ beq(op1, op2, (int)0);
  8148         break;
  8149       case 0x02: //not_equal
  8150         if (&L)
  8151           __ bne(op1, op2, L);
  8152         else
  8153           __ bne(op1, op2, (int)0);
  8154         break;
  8155       case 0x03: //above
  8156         __ slt(AT, op2, op1);
  8157         if(&L)
  8158           __ bne(R0, AT, L);
  8159         else
  8160                 __ bne(R0, AT, (int)0);
  8161         break;
  8162       case 0x04: //above_equal
  8163         __ slt(AT, op1, op2);
  8164         if(&L)
  8165           __ beq(AT, R0, L);
  8166         else
  8167                 __ beq(AT, R0, (int)0);
  8168         break;
  8169       case 0x05: //below
  8170         __ slt(AT, op1, op2);
  8171         if(&L)
  8172            __ bne(R0, AT, L);
  8173         else
  8174            __ bne(R0, AT, (int)0);
  8175         break;
  8176       case 0x06: //below_equal
  8177         __ slt(AT, op2, op1);
  8178         if(&L)
  8179           __ beq(AT, R0, L);
  8180         else
  8181           __ beq(AT, R0, (int)0);
  8182        break;
  8183       default:
  8184         Unimplemented();
  8186     __ delayed()->nop();
  8187   %}
  8189   ins_pc_relative(1);
  8190   ins_pipe( pipe_alu_branch );
  8191   ins_short_branch(1);
  8192 %}
  8194 instruct branchConI_reg_imm0_short(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  8195   match( If cmp (CmpI src1 src2) );
  8196   effect(USE labl);
  8197   ins_cost(170);
  8198   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0_short" %}
  8200   ins_encode %{
  8201     Register op1 = $src1$$Register;
  8202     Label     &L =  *($labl$$label);
  8203     int     flag = $cmp$$cmpcode;
  8205     switch(flag) {
  8206       case 0x01: //equal
  8207         if (&L)
  8208           __ beq(op1, R0, L);
  8209         else
  8210           __ beq(op1, R0, (int)0);
  8211         break;
  8212       case 0x02: //not_equal
  8213         if (&L)
  8214           __ bne(op1, R0, L);
  8215         else
  8216           __ bne(op1, R0, (int)0);
  8217         break;
  8218       case 0x03: //greater
  8219         if(&L)
  8220                __ bgtz(op1, L);
  8221         else
  8222                __ bgtz(op1, (int)0);
  8223         break;
  8224       case 0x04: //greater_equal
  8225         if(&L)
  8226                __ bgez(op1, L);
  8227         else
  8228                __ bgez(op1, (int)0);
  8229         break;
  8230       case 0x05: //less
  8231         if(&L)
  8232                 __ bltz(op1, L);
  8233         else
  8234                 __ bltz(op1, (int)0);
  8235         break;
  8236       case 0x06: //less_equal
  8237         if(&L)
  8238                __ blez(op1, L);
  8239         else
  8240                __ blez(op1, (int)0);
  8241        break;
  8242       default:
  8243         Unimplemented();
  8245     __ delayed()->nop();
  8246   %}
  8248   ins_pc_relative(1);
  8249   ins_pipe( pipe_alu_branch );
  8250   ins_short_branch(1);
  8251 %}
  8254 instruct branchConI_reg_imm_short(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  8255   match( If cmp (CmpI src1 src2) );
  8256   effect(USE labl);
  8257   ins_cost(200);
  8258   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm_short" %}
  8260   ins_encode %{
  8261     Register op1 = $src1$$Register;
  8262     int      val = $src2$$constant;
  8263     Label     &L =  *($labl$$label);
  8264     int     flag = $cmp$$cmpcode;
  8266     __ move(AT, val);
  8267     switch(flag) {
  8268       case 0x01: //equal
  8269         if (&L)
  8270           __ beq(op1, AT, L);
  8271         else
  8272           __ beq(op1, AT, (int)0);
  8273         break;
  8274       case 0x02: //not_equal
  8275         if (&L)
  8276           __ bne(op1, AT, L);
  8277         else
  8278           __ bne(op1, AT, (int)0);
  8279         break;
  8280       case 0x03: //greater
  8281         __ slt(AT, AT, op1);
  8282         if(&L)
  8283           __ bne(R0, AT, L);
  8284         else
  8285                 __ bne(R0, AT, (int)0);
  8286         break;
  8287       case 0x04: //greater_equal
  8288         __ slt(AT, op1, AT);
  8289         if(&L)
  8290           __ beq(AT, R0, L);
  8291         else
  8292                 __ beq(AT, R0, (int)0);
  8293         break;
  8294       case 0x05: //less
  8295         __ slt(AT, op1, AT);
  8296         if(&L)
  8297            __ bne(R0, AT, L);
  8298         else
  8299            __ bne(R0, AT, (int)0);
  8300         break;
  8301       case 0x06: //less_equal
  8302         __ slt(AT, AT, op1);
  8303         if(&L)
  8304           __ beq(AT, R0, L);
  8305         else
  8306           __ beq(AT, R0, (int)0);
  8307        break;
  8308       default:
  8309           Unimplemented();
  8311     __ delayed()->nop();
  8312   %}
  8314   ins_pc_relative(1);
  8315   ins_pipe( pipe_alu_branch );
  8316   ins_short_branch(1);
  8317 %}
  8319 instruct branchConIU_reg_imm0_short(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  8320   match( If cmp (CmpU src1 zero) );
  8321   effect(USE labl);
  8322   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0_short" %}
  8324   ins_encode %{
  8325     Register op1 = $src1$$Register;
  8326     Label     &L = *($labl$$label);
  8327     int     flag = $cmp$$cmpcode;
  8329     switch(flag) {
  8330       case 0x01: //equal
  8331         if (&L)
  8332           __ beq(op1, R0, L);
  8333         else
  8334           __ beq(op1, R0, (int)0);
  8335         break;
  8336       case 0x02: //not_equal
  8337         if (&L)
  8338           __ bne(op1, R0, L);
  8339         else
  8340           __ bne(op1, R0, (int)0);
  8341         break;
  8342       case 0x03: //above
  8343         if(&L)
  8344           __ bne(R0, op1, L);
  8345         else
  8346           __ bne(R0, op1, (int)0);
  8347         break;
  8348       case 0x04: //above_equal
  8349         if(&L)
  8350           __ beq(R0, R0, L);
  8351         else
  8352           __ beq(R0, R0, (int)0);
  8353         break;
  8354       case 0x05: //below
  8355         return;
  8356         break;
  8357       case 0x06: //below_equal
  8358         if(&L)
  8359           __ beq(op1, R0, L);
  8360         else
  8361           __ beq(op1, R0, (int)0);
  8362         break;
  8363       default:
  8364         Unimplemented();
  8366     __ delayed()->nop();
  8367     %}
  8369   ins_pc_relative(1);
  8370   ins_pipe( pipe_alu_branch );
  8371   ins_short_branch(1);
  8372 %}
  8375 instruct branchConIU_reg_immI16_short(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  8376   match( If cmp (CmpU src1 src2) );
  8377   effect(USE labl);
  8378   ins_cost(180);
  8379   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16_short" %}
  8381   ins_encode %{
  8382     Register op1 = $src1$$Register;
  8383     int      val = $src2$$constant;
  8384     Label     &L = *($labl$$label);
  8385     int     flag = $cmp$$cmpcode;
  8387     switch(flag) {
  8388       case 0x01: //equal
  8389         __ move(AT, val);
  8390         if (&L)
  8391           __ beq(op1, AT, L);
  8392         else
  8393           __ beq(op1, AT, (int)0);
  8394         break;
  8395       case 0x02: //not_equal
  8396         __ move(AT, val);
  8397         if (&L)
  8398           __ bne(op1, AT, L);
  8399         else
  8400           __ bne(op1, AT, (int)0);
  8401         break;
  8402       case 0x03: //above
  8403         __ move(AT, val);
  8404         __ sltu(AT, AT, op1);
  8405         if(&L)
  8406           __ bne(R0, AT, L);
  8407         else
  8408           __ bne(R0, AT, (int)0);
  8409         break;
  8410       case 0x04: //above_equal
  8411         __ sltiu(AT, op1, val);
  8412         if(&L)
  8413           __ beq(AT, R0, L);
  8414         else
  8415           __ beq(AT, R0, (int)0);
  8416         break;
  8417       case 0x05: //below
  8418         __ sltiu(AT, op1, val);
  8419         if(&L)
  8420           __ bne(R0, AT, L);
  8421         else
  8422           __ bne(R0, AT, (int)0);
  8423         break;
  8424       case 0x06: //below_equal
  8425         __ move(AT, val);
  8426         __ sltu(AT, AT, op1);
  8427         if(&L)
  8428           __ beq(AT, R0, L);
  8429         else
  8430           __ beq(AT, R0, (int)0);
  8431         break;
  8432       default:
  8433         Unimplemented();
  8435     __ delayed()->nop();
  8436   %}
  8438   ins_pc_relative(1);
  8439   ins_pipe( pipe_alu_branch );
  8440   ins_short_branch(1);
  8441 %}
  8444 instruct branchConL_regL_regL_short(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  8445   match( If cmp (CmpL src1 src2) );
  8446   effect(USE labl);
  8447   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL_short" %}
  8448   ins_cost(250);
  8450   ins_encode %{
  8451     Register opr1_reg = as_Register($src1$$reg);
  8452     Register opr2_reg = as_Register($src2$$reg);
  8454     Label   &target = *($labl$$label);
  8455     int     flag = $cmp$$cmpcode;
  8457     switch(flag) {
  8458       case 0x01: //equal
  8459         if (&target)
  8460           __ beq(opr1_reg, opr2_reg, target);
  8461         else
  8462           __ beq(opr1_reg, opr2_reg, (int)0);
  8463         __ delayed()->nop();
  8464         break;
  8466       case 0x02: //not_equal
  8467         if(&target)
  8468           __ bne(opr1_reg, opr2_reg, target);
  8469         else
  8470           __ bne(opr1_reg, opr2_reg, (int)0);
  8471         __ delayed()->nop();
  8472         break;
  8474       case 0x03: //greater
  8475         __ slt(AT, opr2_reg, opr1_reg);
  8476         if(&target)
  8477           __ bne(AT, R0, target);
  8478         else
  8479           __ bne(AT, R0, (int)0);
  8480         __ delayed()->nop();
  8481         break;
  8483       case 0x04: //greater_equal
  8484         __ slt(AT, opr1_reg, opr2_reg);
  8485         if(&target)
  8486           __ beq(AT, R0, target);
  8487         else
  8488           __ beq(AT, R0, (int)0);
  8489         __ delayed()->nop();
  8491         break;
  8493       case 0x05: //less
  8494         __ slt(AT, opr1_reg, opr2_reg);
  8495         if(&target)
  8496           __ bne(AT, R0, target);
  8497         else
  8498           __ bne(AT, R0, (int)0);
  8499         __ delayed()->nop();
  8501         break;
  8503       case 0x06: //less_equal
  8504         __ slt(AT, opr2_reg, opr1_reg);
  8506         if(&target)
  8507           __ beq(AT, R0, target);
  8508         else
  8509           __ beq(AT, R0, (int)0);
  8510         __ delayed()->nop();
  8512         break;
  8514       default:
  8515         Unimplemented();
  8517   %}
  8520   ins_pc_relative(1);
  8521   ins_pipe( pipe_alu_branch );
  8522   ins_short_branch(1);
  8523 %}
  8526 instruct branchConL_regL_immL0_short(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  8527   match( If cmp (CmpL src1 zero) );
  8528   effect(USE labl);
  8529   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0_short" %}
  8530   ins_cost(150);
  8532   ins_encode %{
  8533     Register opr1_reg = as_Register($src1$$reg);
  8534     Label   &target = *($labl$$label);
  8535     int     flag = $cmp$$cmpcode;
  8537     switch(flag) {
  8538       case 0x01: //equal
  8539         if (&target)
  8540            __ beq(opr1_reg, R0, target);
  8541         else
  8542            __ beq(opr1_reg, R0, int(0));
  8543         break;
  8545       case 0x02: //not_equal
  8546         if(&target)
  8547            __ bne(opr1_reg, R0, target);
  8548         else
  8549            __ bne(opr1_reg, R0, (int)0);
  8550         break;
  8552       case 0x03: //greater
  8553         if(&target)
  8554            __ bgtz(opr1_reg, target);
  8555         else
  8556            __ bgtz(opr1_reg, (int)0);
  8557        break;
  8559       case 0x04: //greater_equal
  8560         if(&target)
  8561            __ bgez(opr1_reg, target);
  8562         else
  8563            __ bgez(opr1_reg, (int)0);
  8564         break;
  8566       case 0x05: //less
  8567         __ slt(AT, opr1_reg, R0);
  8568         if(&target)
  8569            __ bne(AT, R0, target);
  8570         else
  8571            __ bne(AT, R0, (int)0);
  8572         break;
  8574       case 0x06: //less_equal
  8575         if (&target)
  8576            __ blez(opr1_reg, target);
  8577         else
  8578            __ blez(opr1_reg, int(0));
  8579         break;
  8581       default:
  8582           Unimplemented();
  8584     __ delayed()->nop();
  8585   %}
  8588   ins_pc_relative(1);
  8589   ins_pipe( pipe_alu_branch );
  8590   ins_short_branch(1);
  8591 %}
  8593 instruct branchConL_regL_immL_short(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  8594   match( If cmp (CmpL src1 src2) );
  8595   effect(USE labl);
  8596   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL_short" %}
  8597   ins_cost(180);
  8599   ins_encode %{
  8600     Register opr1_reg = as_Register($src1$$reg);
  8601     Register opr2_reg = AT;
  8603     Label   &target = *($labl$$label);
  8604     int     flag = $cmp$$cmpcode;
  8606     __ set64(opr2_reg, $src2$$constant);
  8608     switch(flag) {
  8609       case 0x01: //equal
  8610         if (&target)
  8611           __ beq(opr1_reg, opr2_reg, target);
  8612         else
  8613           __ beq(opr1_reg, opr2_reg, (int)0);
  8614         break;
  8616       case 0x02: //not_equal
  8617         if(&target)
  8618           __ bne(opr1_reg, opr2_reg, target);
  8619         else
  8620           __ bne(opr1_reg, opr2_reg, (int)0);
  8621         break;
  8623       case 0x03: //greater
  8624         __ slt(AT, opr2_reg, opr1_reg);
  8625         if(&target)
  8626           __ bne(AT, R0, target);
  8627         else
  8628           __ bne(AT, R0, (int)0);
  8629         break;
  8631       case 0x04: //greater_equal
  8632         __ slt(AT, opr1_reg, opr2_reg);
  8633         if(&target)
  8634           __ beq(AT, R0, target);
  8635         else
  8636           __ beq(AT, R0, (int)0);
  8637         break;
  8639       case 0x05: //less
  8640         __ slt(AT, opr1_reg, opr2_reg);
  8641         if(&target)
  8642           __ bne(AT, R0, target);
  8643         else
  8644           __ bne(AT, R0, (int)0);
  8645         break;
  8647       case 0x06: //less_equal
  8648         __ slt(AT, opr2_reg, opr1_reg);
  8649         if(&target)
  8650           __ beq(AT, R0, target);
  8651         else
  8652           __ beq(AT, R0, (int)0);
  8653         break;
  8655       default:
  8656         Unimplemented();
  8658     __ delayed()->nop();
  8659   %}
  8662   ins_pc_relative(1);
  8663   ins_pipe( pipe_alu_branch );
  8664   ins_short_branch(1);
  8665 %}
  8668 //FIXME
  8669 instruct branchConF_reg_reg_short(cmpOp cmp, regF src1, regF src2, label labl) %{
  8670   match( If cmp (CmpF src1 src2) );
  8671   effect(USE labl);
  8672   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg_short" %}
  8674   ins_encode %{
  8675     FloatRegister reg_op1 = $src1$$FloatRegister;
  8676     FloatRegister reg_op2 = $src2$$FloatRegister;
  8677     Label     &L =  *($labl$$label);
  8678     int     flag = $cmp$$cmpcode;
  8680     switch(flag) {
  8681       case 0x01: //equal
  8682         __ c_eq_s(reg_op1, reg_op2);
  8683         if (&L)
  8684           __ bc1t(L);
  8685         else
  8686           __ bc1t((int)0);
  8687         break;
  8688       case 0x02: //not_equal
  8689         __ c_eq_s(reg_op1, reg_op2);
  8690         if (&L)
  8691           __ bc1f(L);
  8692         else
  8693           __ bc1f((int)0);
  8694         break;
  8695       case 0x03: //greater
  8696         __ c_ule_s(reg_op1, reg_op2);
  8697         if(&L)
  8698           __ bc1f(L);
  8699         else
  8700           __ bc1f((int)0);
  8701         break;
  8702       case 0x04: //greater_equal
  8703         __ c_ult_s(reg_op1, reg_op2);
  8704         if(&L)
  8705           __ bc1f(L);
  8706         else
  8707           __ bc1f((int)0);
  8708         break;
  8709       case 0x05: //less
  8710         __ c_ult_s(reg_op1, reg_op2);
  8711         if(&L)
  8712           __ bc1t(L);
  8713         else
  8714           __ bc1t((int)0);
  8715         break;
  8716       case 0x06: //less_equal
  8717         __ c_ule_s(reg_op1, reg_op2);
  8718         if(&L)
  8719           __ bc1t(L);
  8720         else
  8721           __ bc1t((int)0);
  8722         break;
  8723       default:
  8724         Unimplemented();
  8726     __ delayed()->nop();
  8727   %}
  8729   ins_pc_relative(1);
  8730   ins_pipe(pipe_slow);
  8731   ins_short_branch(1);
  8732 %}
  8734 instruct branchConD_reg_reg_short(cmpOp cmp, regD src1, regD src2, label labl) %{
  8735   match( If cmp (CmpD src1 src2) );
  8736   effect(USE labl);
  8737   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg_short" %}
  8739   ins_encode %{
  8740     FloatRegister reg_op1 = $src1$$FloatRegister;
  8741     FloatRegister reg_op2 = $src2$$FloatRegister;
  8742     Label     &L =  *($labl$$label);
  8743     int     flag = $cmp$$cmpcode;
  8745     switch(flag) {
  8746       case 0x01: //equal
  8747         __ c_eq_d(reg_op1, reg_op2);
  8748         if (&L)
  8749           __ bc1t(L);
  8750         else
  8751           __ bc1t((int)0);
  8752         break;
  8753       case 0x02: //not_equal
  8754         // 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.
  8755         __ c_eq_d(reg_op1, reg_op2);
  8756         if (&L)
  8757           __ bc1f(L);
  8758         else
  8759           __ bc1f((int)0);
  8760         break;
  8761       case 0x03: //greater
  8762         __ c_ule_d(reg_op1, reg_op2);
  8763         if(&L)
  8764           __ bc1f(L);
  8765         else
  8766           __ bc1f((int)0);
  8767         break;
  8768       case 0x04: //greater_equal
  8769         __ c_ult_d(reg_op1, reg_op2);
  8770         if(&L)
  8771           __ bc1f(L);
  8772         else
  8773           __ bc1f((int)0);
  8774         break;
  8775       case 0x05: //less
  8776         __ c_ult_d(reg_op1, reg_op2);
  8777         if(&L)
  8778           __ bc1t(L);
  8779         else
  8780           __ bc1t((int)0);
  8781         break;
  8782       case 0x06: //less_equal
  8783         __ c_ule_d(reg_op1, reg_op2);
  8784         if(&L)
  8785           __ bc1t(L);
  8786         else
  8787           __ bc1t((int)0);
  8788         break;
  8789       default:
  8790         Unimplemented();
  8792     __ delayed()->nop();
  8793   %}
  8795   ins_pc_relative(1);
  8796   ins_pipe(pipe_slow);
  8797   ins_short_branch(1);
  8798 %}
  8800 // =================== End of branch instructions ==========================
  8802 // Call Runtime Instruction
  8803 instruct CallRuntimeDirect(method meth) %{
  8804   match(CallRuntime );
  8805   effect(USE meth);
  8807   ins_cost(300);
  8808   format %{ "CALL,runtime #@CallRuntimeDirect" %}
  8809   ins_encode( Java_To_Runtime( meth ) );
  8810   ins_pipe( pipe_slow );
  8811   ins_alignment(16);
  8812 %}
  8816 //------------------------MemBar Instructions-------------------------------
  8817 //Memory barrier flavors
  8819 instruct membar_acquire() %{
  8820   match(MemBarAcquire);
  8821   ins_cost(400);
  8823   format %{ "MEMBAR-acquire @ membar_acquire" %}
  8824   ins_encode %{
  8825     __ sync();
  8826   %}
  8827   ins_pipe(empty);
  8828 %}
  8830 instruct load_fence() %{
  8831   match(LoadFence);
  8832   ins_cost(400);
  8834   format %{ "MEMBAR @ load_fence" %}
  8835   ins_encode %{
  8836     __ sync();
  8837   %}
  8838   ins_pipe(pipe_slow);
  8839 %}
  8841 instruct membar_acquire_lock()
  8842 %{
  8843   match(MemBarAcquireLock);
  8844   ins_cost(0);
  8846   size(0);
  8847   format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
  8848   ins_encode();
  8849   ins_pipe(empty);
  8850 %}
  8852 instruct membar_release() %{
  8853   match(MemBarRelease);
  8854   ins_cost(400);
  8856   format %{ "MEMBAR-release @ membar_release" %}
  8858   ins_encode %{
  8859     // Attention: DO NOT DELETE THIS GUY!
  8860     __ sync();
  8861   %}
  8863   ins_pipe(pipe_slow);
  8864 %}
  8866 instruct store_fence() %{
  8867   match(StoreFence);
  8868   ins_cost(400);
  8870   format %{ "MEMBAR @ store_fence" %}
  8872   ins_encode %{
  8873     __ sync();
  8874   %}
  8876   ins_pipe(pipe_slow);
  8877 %}
  8879 instruct membar_release_lock()
  8880 %{
  8881   match(MemBarReleaseLock);
  8882   ins_cost(0);
  8884   size(0);
  8885   format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
  8886   ins_encode();
  8887   ins_pipe(empty);
  8888 %}
  8891 instruct membar_volatile() %{
  8892   match(MemBarVolatile);
  8893   ins_cost(400);
  8895   format %{ "MEMBAR-volatile" %}
  8896   ins_encode %{
  8897     if( !os::is_MP() ) return;     // Not needed on single CPU
  8898     __ sync();
  8900   %}
  8901   ins_pipe(pipe_slow);
  8902 %}
  8904 instruct unnecessary_membar_volatile() %{
  8905   match(MemBarVolatile);
  8906   predicate(Matcher::post_store_load_barrier(n));
  8907   ins_cost(0);
  8909   size(0);
  8910   format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
  8911   ins_encode( );
  8912   ins_pipe(empty);
  8913 %}
  8915 instruct membar_storestore() %{
  8916   match(MemBarStoreStore);
  8918   ins_cost(400);
  8919   format %{ "MEMBAR-storestore @ membar_storestore" %}
  8920   ins_encode %{
  8921     __ sync();
  8922   %}
  8923   ins_pipe(empty);
  8924 %}
  8926 //----------Move Instructions--------------------------------------------------
  8927 instruct castX2P(mRegP dst, mRegL src) %{
  8928   match(Set dst (CastX2P src));
  8929   format %{ "castX2P  $dst, $src @ castX2P" %}
  8930   ins_encode %{
  8931     Register src = $src$$Register;
  8932     Register dst = $dst$$Register;
  8934   if(src != dst)
  8935     __ move(dst, src);
  8936   %}
  8937   ins_cost(10);
  8938   ins_pipe( ialu_regI_mov );
  8939 %}
  8941 instruct castP2X(mRegL dst, mRegP src ) %{
  8942   match(Set dst (CastP2X src));
  8944   format %{ "mov    $dst, $src\t  #@castP2X" %}
  8945   ins_encode %{
  8946     Register src = $src$$Register;
  8947     Register dst = $dst$$Register;
  8949   if(src != dst)
  8950     __ move(dst, src);
  8951   %}
  8952   ins_pipe( ialu_regI_mov );
  8953 %}
  8955 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
  8956   match(Set dst (MoveF2I src));
  8957   effect(DEF dst, USE src);
  8958   ins_cost(85);
  8959   format %{ "MoveF2I   $dst, $src @ MoveF2I_reg_reg" %}
  8960   ins_encode %{
  8961     Register dst = as_Register($dst$$reg);
  8962     FloatRegister src = as_FloatRegister($src$$reg);
  8964     __ mfc1(dst, src);
  8965   %}
  8966   ins_pipe( pipe_slow );
  8967 %}
  8969 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
  8970   match(Set dst (MoveI2F src));
  8971   effect(DEF dst, USE src);
  8972   ins_cost(85);
  8973   format %{ "MoveI2F   $dst, $src @ MoveI2F_reg_reg" %}
  8974   ins_encode %{
  8975     Register src = as_Register($src$$reg);
  8976     FloatRegister dst = as_FloatRegister($dst$$reg);
  8978     __ mtc1(src, dst);
  8979   %}
  8980   ins_pipe( pipe_slow );
  8981 %}
  8983 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
  8984   match(Set dst (MoveD2L src));
  8985   effect(DEF dst, USE src);
  8986   ins_cost(85);
  8987   format %{ "MoveD2L   $dst, $src @ MoveD2L_reg_reg" %}
  8988   ins_encode %{
  8989     Register dst = as_Register($dst$$reg);
  8990     FloatRegister src = as_FloatRegister($src$$reg);
  8992     __ dmfc1(dst, src);
  8993   %}
  8994   ins_pipe( pipe_slow );
  8995 %}
  8997 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
  8998   match(Set dst (MoveL2D src));
  8999   effect(DEF dst, USE src);
  9000   ins_cost(85);
  9001   format %{ "MoveL2D   $dst, $src @ MoveL2D_reg_reg" %}
  9002   ins_encode %{
  9003     FloatRegister dst = as_FloatRegister($dst$$reg);
  9004     Register src = as_Register($src$$reg);
  9006     __ dmtc1(src, dst);
  9007   %}
  9008   ins_pipe( pipe_slow );
  9009 %}
  9011 //----------Conditional Move---------------------------------------------------
  9012 // Conditional move
  9013 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9014   match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9015   ins_cost(80);
  9016   format %{
  9017              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpI_reg_reg\n"
  9018              "\tCMOV  $dst,$src \t @cmovI_cmpI_reg_reg"
  9019          %}
  9021   ins_encode %{
  9022     Register op1 = $tmp1$$Register;
  9023     Register op2 = $tmp2$$Register;
  9024     Register dst = $dst$$Register;
  9025     Register src = $src$$Register;
  9026     int     flag = $cop$$cmpcode;
  9028     switch(flag) {
  9029       case 0x01: //equal
  9030         __ subu32(AT, op1, op2);
  9031         __ movz(dst, src, AT);
  9032         break;
  9034       case 0x02: //not_equal
  9035         __ subu32(AT, op1, op2);
  9036         __ movn(dst, src, AT);
  9037         break;
  9039       case 0x03: //great
  9040         __ slt(AT, op2, op1);
  9041         __ movn(dst, src, AT);
  9042         break;
  9044       case 0x04: //great_equal
  9045         __ slt(AT, op1, op2);
  9046         __ movz(dst, src, AT);
  9047         break;
  9049       case 0x05: //less
  9050         __ slt(AT, op1, op2);
  9051         __ movn(dst, src, AT);
  9052         break;
  9054       case 0x06: //less_equal
  9055         __ slt(AT, op2, op1);
  9056         __ movz(dst, src, AT);
  9057        break;
  9059       default:
  9060         Unimplemented();
  9062   %}
  9064   ins_pipe( pipe_slow );
  9065 %}
  9067 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9068   match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9069   ins_cost(80);
  9070   format %{
  9071              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
  9072              "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
  9073          %}
  9074   ins_encode %{
  9075     Register op1 = $tmp1$$Register;
  9076     Register op2 = $tmp2$$Register;
  9077     Register dst = $dst$$Register;
  9078     Register src = $src$$Register;
  9079     int     flag = $cop$$cmpcode;
  9081     switch(flag) {
  9082       case 0x01: //equal
  9083         __ subu(AT, op1, op2);
  9084         __ movz(dst, src, AT);
  9085         break;
  9087       case 0x02: //not_equal
  9088         __ subu(AT, op1, op2);
  9089         __ movn(dst, src, AT);
  9090         break;
  9092       case 0x03: //above
  9093         __ sltu(AT, op2, op1);
  9094         __ movn(dst, src, AT);
  9095         break;
  9097       case 0x04: //above_equal
  9098         __ sltu(AT, op1, op2);
  9099         __ movz(dst, src, AT);
  9100         break;
  9102       case 0x05: //below
  9103         __ sltu(AT, op1, op2);
  9104         __ movn(dst, src, AT);
  9105         break;
  9107       case 0x06: //below_equal
  9108         __ sltu(AT, op2, op1);
  9109         __ movz(dst, src, AT);
  9110        break;
  9112       default:
  9113         Unimplemented();
  9115   %}
  9117   ins_pipe( pipe_slow );
  9118 %}
  9120 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9121   match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9122   ins_cost(80);
  9123   format %{
  9124              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
  9125              "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
  9126          %}
  9127   ins_encode %{
  9128     Register op1 = $tmp1$$Register;
  9129     Register op2 = $tmp2$$Register;
  9130     Register dst = $dst$$Register;
  9131     Register src = $src$$Register;
  9132     int     flag = $cop$$cmpcode;
  9134     switch(flag) {
  9135       case 0x01: //equal
  9136         __ subu32(AT, op1, op2);
  9137         __ movz(dst, src, AT);
  9138         break;
  9140       case 0x02: //not_equal
  9141         __ subu32(AT, op1, op2);
  9142         __ movn(dst, src, AT);
  9143         break;
  9145       case 0x03: //above
  9146         __ sltu(AT, op2, op1);
  9147         __ movn(dst, src, AT);
  9148         break;
  9150       case 0x04: //above_equal
  9151         __ sltu(AT, op1, op2);
  9152         __ movz(dst, src, AT);
  9153         break;
  9155       case 0x05: //below
  9156         __ sltu(AT, op1, op2);
  9157         __ movn(dst, src, AT);
  9158         break;
  9160       case 0x06: //below_equal
  9161         __ sltu(AT, op2, op1);
  9162         __ movz(dst, src, AT);
  9163        break;
  9165       default:
  9166           Unimplemented();
  9168   %}
  9170   ins_pipe( pipe_slow );
  9171 %}
  9173 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9174   match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9175   ins_cost(80);
  9176   format %{
  9177              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
  9178              "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
  9179          %}
  9180   ins_encode %{
  9181     Register op1 = $tmp1$$Register;
  9182     Register op2 = $tmp2$$Register;
  9183     Register dst = $dst$$Register;
  9184     Register src = $src$$Register;
  9185     int     flag = $cop$$cmpcode;
  9187     switch(flag) {
  9188       case 0x01: //equal
  9189         __ subu32(AT, op1, op2);
  9190         __ movz(dst, src, AT);
  9191         break;
  9193       case 0x02: //not_equal
  9194         __ subu32(AT, op1, op2);
  9195         __ movn(dst, src, AT);
  9196         break;
  9198       case 0x03: //above
  9199         __ sltu(AT, op2, op1);
  9200         __ movn(dst, src, AT);
  9201         break;
  9203       case 0x04: //above_equal
  9204         __ sltu(AT, op1, op2);
  9205         __ movz(dst, src, AT);
  9206         break;
  9208       case 0x05: //below
  9209         __ sltu(AT, op1, op2);
  9210         __ movn(dst, src, AT);
  9211         break;
  9213       case 0x06: //below_equal
  9214         __ sltu(AT, op2, op1);
  9215         __ movz(dst, src, AT);
  9216        break;
  9218       default:
  9219           Unimplemented();
  9221   %}
  9223   ins_pipe( pipe_slow );
  9224 %}
  9226 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9227   match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9228   ins_cost(80);
  9229   format %{
  9230              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpF_reg_reg\n"
  9231              "\tCMOV  $dst,$src \t @cmovP_cmpF_reg_reg"
  9232          %}
  9234   ins_encode %{
  9235     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9236     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9237     Register dst = $dst$$Register;
  9238     Register src = $src$$Register;
  9239     int     flag = $cop$$cmpcode;
  9241     switch(flag) {
  9242       case 0x01: //equal
  9243         __ c_eq_s(reg_op1, reg_op2);
  9244         __ movt(dst, src);
  9245         break;
  9246       case 0x02: //not_equal
  9247         __ c_eq_s(reg_op1, reg_op2);
  9248         __ movf(dst, src);
  9249         break;
  9250       case 0x03: //greater
  9251         __ c_ole_s(reg_op1, reg_op2);
  9252         __ movf(dst, src);
  9253         break;
  9254       case 0x04: //greater_equal
  9255         __ c_olt_s(reg_op1, reg_op2);
  9256         __ movf(dst, src);
  9257         break;
  9258       case 0x05: //less
  9259         __ c_ult_s(reg_op1, reg_op2);
  9260         __ movt(dst, src);
  9261         break;
  9262       case 0x06: //less_equal
  9263         __ c_ule_s(reg_op1, reg_op2);
  9264         __ movt(dst, src);
  9265         break;
  9266       default:
  9267         Unimplemented();
  9269   %}
  9270   ins_pipe( pipe_slow );
  9271 %}
  9273 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9274   match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9275   ins_cost(80);
  9276   format %{
  9277              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
  9278              "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
  9279          %}
  9280   ins_encode %{
  9281     Register op1 = $tmp1$$Register;
  9282     Register op2 = $tmp2$$Register;
  9283     Register dst = $dst$$Register;
  9284     Register src = $src$$Register;
  9285     int     flag = $cop$$cmpcode;
  9287     switch(flag) {
  9288       case 0x01: //equal
  9289         __ subu32(AT, op1, op2);
  9290         __ movz(dst, src, AT);
  9291         break;
  9293       case 0x02: //not_equal
  9294         __ subu32(AT, op1, op2);
  9295         __ movn(dst, src, AT);
  9296         break;
  9298       case 0x03: //above
  9299         __ sltu(AT, op2, op1);
  9300         __ movn(dst, src, AT);
  9301         break;
  9303       case 0x04: //above_equal
  9304         __ sltu(AT, op1, op2);
  9305         __ movz(dst, src, AT);
  9306         break;
  9308       case 0x05: //below
  9309         __ sltu(AT, op1, op2);
  9310         __ movn(dst, src, AT);
  9311         break;
  9313       case 0x06: //below_equal
  9314         __ sltu(AT, op2, op1);
  9315         __ movz(dst, src, AT);
  9316        break;
  9318       default:
  9319         Unimplemented();
  9321   %}
  9323   ins_pipe( pipe_slow );
  9324 %}
  9326 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9327   match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9328   ins_cost(80);
  9329   format %{
  9330              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
  9331              "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
  9332          %}
  9333   ins_encode %{
  9334     Register op1 = $tmp1$$Register;
  9335     Register op2 = $tmp2$$Register;
  9336     Register dst = $dst$$Register;
  9337     Register src = $src$$Register;
  9338     int     flag = $cop$$cmpcode;
  9340     switch(flag) {
  9341       case 0x01: //equal
  9342         __ subu(AT, op1, op2);
  9343         __ movz(dst, src, AT);
  9344         break;
  9346       case 0x02: //not_equal
  9347         __ subu(AT, op1, op2);
  9348         __ movn(dst, src, AT);
  9349         break;
  9351       case 0x03: //above
  9352         __ sltu(AT, op2, op1);
  9353         __ movn(dst, src, AT);
  9354         break;
  9356       case 0x04: //above_equal
  9357         __ sltu(AT, op1, op2);
  9358         __ movz(dst, src, AT);
  9359         break;
  9361       case 0x05: //below
  9362         __ sltu(AT, op1, op2);
  9363         __ movn(dst, src, AT);
  9364         break;
  9366       case 0x06: //below_equal
  9367         __ sltu(AT, op2, op1);
  9368         __ movz(dst, src, AT);
  9369         break;
  9371       default:
  9372         Unimplemented();
  9374   %}
  9376   ins_pipe( pipe_slow );
  9377 %}
  9379 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9380   match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9381   ins_cost(80);
  9382   format %{
  9383              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpD_reg_reg\n"
  9384              "\tCMOV  $dst,$src \t @cmovP_cmpD_reg_reg"
  9385          %}
  9386   ins_encode %{
  9387     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9388     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9389     Register dst = as_Register($dst$$reg);
  9390     Register src = as_Register($src$$reg);
  9392     int     flag = $cop$$cmpcode;
  9394     switch(flag) {
  9395       case 0x01: //equal
  9396         __ c_eq_d(reg_op1, reg_op2);
  9397         __ movt(dst, src);
  9398         break;
  9399       case 0x02: //not_equal
  9400         __ c_eq_d(reg_op1, reg_op2);
  9401         __ movf(dst, src);
  9402         break;
  9403       case 0x03: //greater
  9404         __ c_ole_d(reg_op1, reg_op2);
  9405         __ movf(dst, src);
  9406         break;
  9407       case 0x04: //greater_equal
  9408         __ c_olt_d(reg_op1, reg_op2);
  9409         __ movf(dst, src);
  9410         break;
  9411       case 0x05: //less
  9412         __ c_ult_d(reg_op1, reg_op2);
  9413         __ movt(dst, src);
  9414         break;
  9415       case 0x06: //less_equal
  9416         __ c_ule_d(reg_op1, reg_op2);
  9417         __ movt(dst, src);
  9418         break;
  9419       default:
  9420         Unimplemented();
  9422   %}
  9424   ins_pipe( pipe_slow );
  9425 %}
  9428 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9429   match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9430   ins_cost(80);
  9431   format %{
  9432              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
  9433              "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
  9434          %}
  9435   ins_encode %{
  9436     Register op1 = $tmp1$$Register;
  9437     Register op2 = $tmp2$$Register;
  9438     Register dst = $dst$$Register;
  9439     Register src = $src$$Register;
  9440     int     flag = $cop$$cmpcode;
  9442     switch(flag) {
  9443       case 0x01: //equal
  9444         __ subu32(AT, op1, op2);
  9445         __ movz(dst, src, AT);
  9446         break;
  9448       case 0x02: //not_equal
  9449         __ subu32(AT, op1, op2);
  9450         __ movn(dst, src, AT);
  9451         break;
  9453       case 0x03: //above
  9454         __ sltu(AT, op2, op1);
  9455         __ movn(dst, src, AT);
  9456         break;
  9458       case 0x04: //above_equal
  9459         __ sltu(AT, op1, op2);
  9460         __ movz(dst, src, AT);
  9461         break;
  9463       case 0x05: //below
  9464         __ sltu(AT, op1, op2);
  9465         __ movn(dst, src, AT);
  9466         break;
  9468       case 0x06: //below_equal
  9469         __ sltu(AT, op2, op1);
  9470         __ movz(dst, src, AT);
  9471         break;
  9473       default:
  9474         Unimplemented();
  9476   %}
  9478   ins_pipe( pipe_slow );
  9479 %}
  9482 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9483   match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9484   ins_cost(80);
  9485   format %{
  9486              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
  9487              "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
  9488          %}
  9489   ins_encode %{
  9490     Register op1 = $tmp1$$Register;
  9491     Register op2 = $tmp2$$Register;
  9492     Register dst = $dst$$Register;
  9493     Register src = $src$$Register;
  9494     int     flag = $cop$$cmpcode;
  9496     switch(flag) {
  9497       case 0x01: //equal
  9498         __ subu(AT, op1, op2);
  9499         __ movz(dst, src, AT);
  9500         break;
  9502       case 0x02: //not_equal
  9503         __ subu(AT, op1, op2);
  9504         __ movn(dst, src, AT);
  9505         break;
  9507       case 0x03: //above
  9508         __ sltu(AT, op2, op1);
  9509         __ movn(dst, src, AT);
  9510         break;
  9512       case 0x04: //above_equal
  9513         __ sltu(AT, op1, op2);
  9514         __ movz(dst, src, AT);
  9515         break;
  9517       case 0x05: //below
  9518         __ sltu(AT, op1, op2);
  9519         __ movn(dst, src, AT);
  9520         break;
  9522       case 0x06: //below_equal
  9523         __ sltu(AT, op2, op1);
  9524         __ movz(dst, src, AT);
  9525         break;
  9527       default:
  9528         Unimplemented();
  9530   %}
  9532   ins_pipe( pipe_slow );
  9533 %}
  9535 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  9536   match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9537   ins_cost(80);
  9538   format %{
  9539              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpL_reg_reg\n"
  9540              "\tCMOV  $dst,$src \t @cmovI_cmpL_reg_reg"
  9541          %}
  9542   ins_encode %{
  9543     Register opr1 = as_Register($tmp1$$reg);
  9544     Register opr2 = as_Register($tmp2$$reg);
  9545     Register dst     = $dst$$Register;
  9546     Register src     = $src$$Register;
  9547     int     flag = $cop$$cmpcode;
  9549     switch(flag) {
  9550       case 0x01: //equal
  9551         __ subu(AT, opr1, opr2);
  9552         __ movz(dst, src, AT);
  9553         break;
  9555       case 0x02: //not_equal
  9556         __ subu(AT, opr1, opr2);
  9557         __ movn(dst, src, AT);
  9558         break;
  9560       case 0x03: //greater
  9561         __ slt(AT, opr2, opr1);
  9562         __ movn(dst, src, AT);
  9563         break;
  9565       case 0x04: //greater_equal
  9566         __ slt(AT, opr1, opr2);
  9567         __ movz(dst, src, AT);
  9568         break;
  9570       case 0x05: //less
  9571         __ slt(AT, opr1, opr2);
  9572         __ movn(dst, src, AT);
  9573         break;
  9575       case 0x06: //less_equal
  9576         __ slt(AT, opr2, opr1);
  9577         __ movz(dst, src, AT);
  9578         break;
  9580       default:
  9581         Unimplemented();
  9583   %}
  9585   ins_pipe( pipe_slow );
  9586 %}
  9588 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  9589   match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9590   ins_cost(80);
  9591   format %{
  9592              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpL_reg_reg\n"
  9593              "\tCMOV  $dst,$src \t @cmovP_cmpL_reg_reg"
  9594          %}
  9595   ins_encode %{
  9596     Register opr1 = as_Register($tmp1$$reg);
  9597     Register opr2 = as_Register($tmp2$$reg);
  9598     Register dst     = $dst$$Register;
  9599     Register src     = $src$$Register;
  9600     int     flag = $cop$$cmpcode;
  9602     switch(flag) {
  9603       case 0x01: //equal
  9604         __ subu(AT, opr1, opr2);
  9605         __ movz(dst, src, AT);
  9606         break;
  9608       case 0x02: //not_equal
  9609         __ subu(AT, opr1, opr2);
  9610         __ movn(dst, src, AT);
  9611         break;
  9613       case 0x03: //greater
  9614         __ slt(AT, opr2, opr1);
  9615         __ movn(dst, src, AT);
  9616         break;
  9618       case 0x04: //greater_equal
  9619         __ slt(AT, opr1, opr2);
  9620         __ movz(dst, src, AT);
  9621         break;
  9623       case 0x05: //less
  9624         __ slt(AT, opr1, opr2);
  9625         __ movn(dst, src, AT);
  9626         break;
  9628       case 0x06: //less_equal
  9629         __ slt(AT, opr2, opr1);
  9630         __ movz(dst, src, AT);
  9631         break;
  9633       default:
  9634         Unimplemented();
  9636   %}
  9638   ins_pipe( pipe_slow );
  9639 %}
  9641 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9642   match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9643   ins_cost(80);
  9644   format %{
  9645              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpD_reg_reg\n"
  9646              "\tCMOV  $dst,$src \t @cmovI_cmpD_reg_reg"
  9647          %}
  9648   ins_encode %{
  9649     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9650     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9651     Register dst = as_Register($dst$$reg);
  9652     Register src = as_Register($src$$reg);
  9654     int     flag = $cop$$cmpcode;
  9656     switch(flag) {
  9657       case 0x01: //equal
  9658         __ c_eq_d(reg_op1, reg_op2);
  9659         __ movt(dst, src);
  9660         break;
  9661       case 0x02: //not_equal
  9662       // See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
  9663         __ c_eq_d(reg_op1, reg_op2);
  9664         __ movf(dst, src);
  9665         break;
  9666       case 0x03: //greater
  9667         __ c_ole_d(reg_op1, reg_op2);
  9668         __ movf(dst, src);
  9669         break;
  9670       case 0x04: //greater_equal
  9671         __ c_olt_d(reg_op1, reg_op2);
  9672         __ movf(dst, src);
  9673         break;
  9674       case 0x05: //less
  9675         __ c_ult_d(reg_op1, reg_op2);
  9676         __ movt(dst, src);
  9677         break;
  9678       case 0x06: //less_equal
  9679         __ c_ule_d(reg_op1, reg_op2);
  9680         __ movt(dst, src);
  9681         break;
  9682       default:
  9683         Unimplemented();
  9685   %}
  9687   ins_pipe( pipe_slow );
  9688 %}
  9691 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9692   match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9693   ins_cost(80);
  9694   format %{
  9695              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
  9696              "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
  9697          %}
  9698   ins_encode %{
  9699     Register op1 = $tmp1$$Register;
  9700     Register op2 = $tmp2$$Register;
  9701     Register dst = $dst$$Register;
  9702     Register src = $src$$Register;
  9703     int     flag = $cop$$cmpcode;
  9705     switch(flag) {
  9706       case 0x01: //equal
  9707         __ subu(AT, op1, op2);
  9708         __ movz(dst, src, AT);
  9709         break;
  9711       case 0x02: //not_equal
  9712         __ subu(AT, op1, op2);
  9713         __ movn(dst, src, AT);
  9714         break;
  9716       case 0x03: //above
  9717         __ sltu(AT, op2, op1);
  9718         __ movn(dst, src, AT);
  9719         break;
  9721       case 0x04: //above_equal
  9722         __ sltu(AT, op1, op2);
  9723         __ movz(dst, src, AT);
  9724         break;
  9726       case 0x05: //below
  9727         __ sltu(AT, op1, op2);
  9728         __ movn(dst, src, AT);
  9729         break;
  9731       case 0x06: //below_equal
  9732         __ sltu(AT, op2, op1);
  9733         __ movz(dst, src, AT);
  9734        break;
  9736       default:
  9737         Unimplemented();
  9739   %}
  9741   ins_pipe( pipe_slow );
  9742 %}
  9744 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9745   match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9746   ins_cost(80);
  9747   format %{
  9748              "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
  9749              "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
  9750          %}
  9751   ins_encode %{
  9752     Register op1 = $tmp1$$Register;
  9753     Register op2 = $tmp2$$Register;
  9754     Register dst = $dst$$Register;
  9755     Register src = $src$$Register;
  9756     int     flag = $cop$$cmpcode;
  9758     switch(flag) {
  9759       case 0x01: //equal
  9760         __ subu32(AT, op1, op2);
  9761         __ movz(dst, src, AT);
  9762         break;
  9764       case 0x02: //not_equal
  9765         __ subu32(AT, op1, op2);
  9766         __ movn(dst, src, AT);
  9767         break;
  9769       case 0x03: //above
  9770         __ slt(AT, op2, op1);
  9771         __ movn(dst, src, AT);
  9772         break;
  9774       case 0x04: //above_equal
  9775         __ slt(AT, op1, op2);
  9776         __ movz(dst, src, AT);
  9777         break;
  9779       case 0x05: //below
  9780         __ slt(AT, op1, op2);
  9781         __ movn(dst, src, AT);
  9782         break;
  9784       case 0x06: //below_equal
  9785         __ slt(AT, op2, op1);
  9786         __ movz(dst, src, AT);
  9787         break;
  9789       default:
  9790         Unimplemented();
  9792   %}
  9794   ins_pipe( pipe_slow );
  9795 %}
  9797 instruct cmovL_cmpP_reg_reg(mRegL dst, mRegL src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9798   match(Set dst (CMoveL (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9799   ins_cost(80);
  9800   format %{
  9801              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpP_reg_reg\n\t"
  9802              "CMOV $dst,$src\t @cmovL_cmpP_reg_reg"
  9803          %}
  9804   ins_encode %{
  9805     Register op1 = $tmp1$$Register;
  9806     Register op2 = $tmp2$$Register;
  9807     Register dst = $dst$$Register;
  9808     Register src = $src$$Register;
  9809     int     flag = $cop$$cmpcode;
  9811     switch(flag) {
  9812       case 0x01: //equal
  9813         __ subu(AT, op1, op2);
  9814         __ movz(dst, src, AT);
  9815         break;
  9817       case 0x02: //not_equal
  9818         __ subu(AT, op1, op2);
  9819         __ movn(dst, src, AT);
  9820         break;
  9822       case 0x03: //above
  9823         __ sltu(AT, op2, op1);
  9824         __ movn(dst, src, AT);
  9825         break;
  9827       case 0x04: //above_equal
  9828         __ sltu(AT, op1, op2);
  9829         __ movz(dst, src, AT);
  9830         break;
  9832       case 0x05: //below
  9833         __ sltu(AT, op1, op2);
  9834         __ movn(dst, src, AT);
  9835         break;
  9837       case 0x06: //below_equal
  9838         __ sltu(AT, op2, op1);
  9839         __ movz(dst, src, AT);
  9840        break;
  9842       default:
  9843         Unimplemented();
  9845   %}
  9847   ins_pipe( pipe_slow );
  9848 %}
  9850 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
  9851   match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9852   ins_cost(80);
  9853   format %{
  9854              "CMP$cop  $tmp1, $tmp2\t  @cmovN_cmpL_reg_reg\n"
  9855              "\tCMOV  $dst,$src \t @cmovN_cmpL_reg_reg"
  9856          %}
  9857   ins_encode %{
  9858     Register opr1 = as_Register($tmp1$$reg);
  9859     Register opr2 = as_Register($tmp2$$reg);
  9860     Register dst  = $dst$$Register;
  9861     Register src  = $src$$Register;
  9862     int     flag  = $cop$$cmpcode;
  9864     switch(flag) {
  9865       case 0x01: //equal
  9866         __ subu(AT, opr1, opr2);
  9867         __ movz(dst, src, AT);
  9868         break;
  9870       case 0x02: //not_equal
  9871         __ subu(AT, opr1, opr2);
  9872         __ movn(dst, src, AT);
  9873         break;
  9875       case 0x03: //greater
  9876         __ slt(AT, opr2, opr1);
  9877         __ movn(dst, src, AT);
  9878         break;
  9880       case 0x04: //greater_equal
  9881         __ slt(AT, opr1, opr2);
  9882         __ movz(dst, src, AT);
  9883         break;
  9885       case 0x05: //less
  9886         __ slt(AT, opr1, opr2);
  9887         __ movn(dst, src, AT);
  9888         break;
  9890       case 0x06: //less_equal
  9891         __ slt(AT, opr2, opr1);
  9892         __ movz(dst, src, AT);
  9893         break;
  9895       default:
  9896         Unimplemented();
  9898   %}
  9900   ins_pipe( pipe_slow );
  9901 %}
  9903 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9904   match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9905   ins_cost(80);
  9906   format %{
  9907              "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
  9908              "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
  9909          %}
  9910   ins_encode %{
  9911     Register op1 = $tmp1$$Register;
  9912     Register op2 = $tmp2$$Register;
  9913     Register dst = $dst$$Register;
  9914     Register src = $src$$Register;
  9915     int     flag = $cop$$cmpcode;
  9917     switch(flag) {
  9918       case 0x01: //equal
  9919         __ subu32(AT, op1, op2);
  9920         __ movz(dst, src, AT);
  9921         break;
  9923       case 0x02: //not_equal
  9924         __ subu32(AT, op1, op2);
  9925         __ movn(dst, src, AT);
  9926         break;
  9928       case 0x03: //above
  9929         __ slt(AT, op2, op1);
  9930         __ movn(dst, src, AT);
  9931         break;
  9933       case 0x04: //above_equal
  9934         __ slt(AT, op1, op2);
  9935         __ movz(dst, src, AT);
  9936         break;
  9938       case 0x05: //below
  9939         __ slt(AT, op1, op2);
  9940         __ movn(dst, src, AT);
  9941         break;
  9943       case 0x06: //below_equal
  9944         __ slt(AT, op2, op1);
  9945         __ movz(dst, src, AT);
  9946        break;
  9948       default:
  9949         Unimplemented();
  9951   %}
  9953   ins_pipe( pipe_slow );
  9954 %}
  9956 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9957   match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9958   ins_cost(80);
  9959   format %{
  9960              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
  9961              "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
  9962          %}
  9963   ins_encode %{
  9964     Register op1 = $tmp1$$Register;
  9965     Register op2 = $tmp2$$Register;
  9966     Register dst = $dst$$Register;
  9967     Register src = $src$$Register;
  9968     int     flag = $cop$$cmpcode;
  9970     switch(flag) {
  9971       case 0x01: //equal
  9972         __ subu32(AT, op1, op2);
  9973         __ movz(dst, src, AT);
  9974         break;
  9976       case 0x02: //not_equal
  9977         __ subu32(AT, op1, op2);
  9978         __ movn(dst, src, AT);
  9979         break;
  9981       case 0x03: //above
  9982         __ sltu(AT, op2, op1);
  9983         __ movn(dst, src, AT);
  9984         break;
  9986       case 0x04: //above_equal
  9987         __ sltu(AT, op1, op2);
  9988         __ movz(dst, src, AT);
  9989         break;
  9991       case 0x05: //below
  9992         __ sltu(AT, op1, op2);
  9993         __ movn(dst, src, AT);
  9994         break;
  9996       case 0x06: //below_equal
  9997         __ sltu(AT, op2, op1);
  9998         __ movz(dst, src, AT);
  9999         break;
 10001       default:
 10002         Unimplemented();
 10004   %}
 10006   ins_pipe( pipe_slow );
 10007 %}
 10009 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10010   match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10011   ins_cost(80);
 10012   format %{
 10013              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpF_reg_reg\n"
 10014              "\tCMOV  $dst,$src \t @cmovL_cmpF_reg_reg"
 10015          %}
 10017   ins_encode %{
 10018     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10019     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10020     Register dst = $dst$$Register;
 10021     Register src = $src$$Register;
 10022     int     flag = $cop$$cmpcode;
 10024     switch(flag) {
 10025       case 0x01: //equal
 10026         __ c_eq_s(reg_op1, reg_op2);
 10027         __ movt(dst, src);
 10028         break;
 10029       case 0x02: //not_equal
 10030         __ c_eq_s(reg_op1, reg_op2);
 10031         __ movf(dst, src);
 10032         break;
 10033       case 0x03: //greater
 10034         __ c_ole_s(reg_op1, reg_op2);
 10035         __ movf(dst, src);
 10036         break;
 10037       case 0x04: //greater_equal
 10038         __ c_olt_s(reg_op1, reg_op2);
 10039         __ movf(dst, src);
 10040         break;
 10041       case 0x05: //less
 10042         __ c_ult_s(reg_op1, reg_op2);
 10043         __ movt(dst, src);
 10044         break;
 10045       case 0x06: //less_equal
 10046         __ c_ule_s(reg_op1, reg_op2);
 10047         __ movt(dst, src);
 10048        break;
 10049       default:
 10050         Unimplemented();
 10052   %}
 10053   ins_pipe( pipe_slow );
 10054 %}
 10056 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10057   match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10058   ins_cost(80);
 10059   format %{
 10060              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpI_reg_reg\n"
 10061              "\tCMOV  $dst,$src \t @cmovL_cmpI_reg_reg"
 10062          %}
 10064   ins_encode %{
 10065     Register op1 = $tmp1$$Register;
 10066     Register op2 = $tmp2$$Register;
 10067     Register dst = as_Register($dst$$reg);
 10068     Register src = as_Register($src$$reg);
 10069     int     flag = $cop$$cmpcode;
 10071     switch(flag)
 10073       case 0x01: //equal
 10074         __ subu32(AT, op1, op2);
 10075         __ movz(dst, src, AT);
 10076         break;
 10078       case 0x02: //not_equal
 10079         __ subu32(AT, op1, op2);
 10080         __ movn(dst, src, AT);
 10081         break;
 10083       case 0x03: //great
 10084         __ slt(AT, op2, op1);
 10085         __ movn(dst, src, AT);
 10086         break;
 10088       case 0x04: //great_equal
 10089         __ slt(AT, op1, op2);
 10090         __ movz(dst, src, AT);
 10091         break;
 10093       case 0x05: //less
 10094         __ slt(AT, op1, op2);
 10095         __ movn(dst, src, AT);
 10096         break;
 10098       case 0x06: //less_equal
 10099         __ slt(AT, op2, op1);
 10100         __ movz(dst, src, AT);
 10101        break;
 10103       default:
 10104         Unimplemented();
 10106   %}
 10108   ins_pipe( pipe_slow );
 10109 %}
 10111 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
 10112   match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
 10113   ins_cost(80);
 10114   format %{
 10115              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpL_reg_reg\n"
 10116              "\tCMOV  $dst,$src \t @cmovL_cmpL_reg_reg"
 10117          %}
 10118   ins_encode %{
 10119     Register opr1 = as_Register($tmp1$$reg);
 10120     Register opr2 = as_Register($tmp2$$reg);
 10121     Register dst  = as_Register($dst$$reg);
 10122     Register src  = as_Register($src$$reg);
 10123     int     flag = $cop$$cmpcode;
 10125     switch(flag) {
 10126       case 0x01: //equal
 10127         __ subu(AT, opr1, opr2);
 10128         __ movz(dst, src, AT);
 10129         break;
 10131       case 0x02: //not_equal
 10132         __ subu(AT, opr1, opr2);
 10133         __ movn(dst, src, AT);
 10134         break;
 10136       case 0x03: //greater
 10137         __ slt(AT, opr2, opr1);
 10138         __ movn(dst, src, AT);
 10139         break;
 10141       case 0x04: //greater_equal
 10142         __ slt(AT, opr1, opr2);
 10143         __ movz(dst, src, AT);
 10144         break;
 10146       case 0x05: //less
 10147         __ slt(AT, opr1, opr2);
 10148         __ movn(dst, src, AT);
 10149         break;
 10151       case 0x06: //less_equal
 10152        __ slt(AT, opr2, opr1);
 10153        __ movz(dst, src, AT);
 10154        break;
 10156       default:
 10157         Unimplemented();
 10159   %}
 10161   ins_pipe( pipe_slow );
 10162 %}
 10164 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
 10165   match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
 10166   ins_cost(80);
 10167   format %{
 10168              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
 10169              "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
 10170          %}
 10171   ins_encode %{
 10172     Register op1 = $tmp1$$Register;
 10173     Register op2 = $tmp2$$Register;
 10174     Register dst = $dst$$Register;
 10175     Register src = $src$$Register;
 10176     int     flag = $cop$$cmpcode;
 10178     switch(flag) {
 10179       case 0x01: //equal
 10180         __ subu32(AT, op1, op2);
 10181         __ movz(dst, src, AT);
 10182         break;
 10184       case 0x02: //not_equal
 10185         __ subu32(AT, op1, op2);
 10186         __ movn(dst, src, AT);
 10187         break;
 10189       case 0x03: //above
 10190         __ sltu(AT, op2, op1);
 10191         __ movn(dst, src, AT);
 10192         break;
 10194       case 0x04: //above_equal
 10195         __ sltu(AT, op1, op2);
 10196         __ movz(dst, src, AT);
 10197         break;
 10199       case 0x05: //below
 10200         __ sltu(AT, op1, op2);
 10201         __ movn(dst, src, AT);
 10202         break;
 10204       case 0x06: //below_equal
 10205         __ sltu(AT, op2, op1);
 10206         __ movz(dst, src, AT);
 10207         break;
 10209       default:
 10210         Unimplemented();
 10212   %}
 10214   ins_pipe( pipe_slow );
 10215 %}
 10218 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
 10219   match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
 10220   ins_cost(80);
 10221   format %{
 10222              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpD_reg_reg\n"
 10223              "\tCMOV  $dst,$src \t @cmovL_cmpD_reg_reg"
 10224          %}
 10225   ins_encode %{
 10226     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
 10227     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
 10228     Register dst = as_Register($dst$$reg);
 10229     Register src = as_Register($src$$reg);
 10231     int     flag = $cop$$cmpcode;
 10233     switch(flag) {
 10234       case 0x01: //equal
 10235         __ c_eq_d(reg_op1, reg_op2);
 10236         __ movt(dst, src);
 10237         break;
 10238       case 0x02: //not_equal
 10239         __ c_eq_d(reg_op1, reg_op2);
 10240         __ movf(dst, src);
 10241         break;
 10242       case 0x03: //greater
 10243         __ c_ole_d(reg_op1, reg_op2);
 10244         __ movf(dst, src);
 10245         break;
 10246       case 0x04: //greater_equal
 10247         __ c_olt_d(reg_op1, reg_op2);
 10248         __ movf(dst, src);
 10249         break;
 10250       case 0x05: //less
 10251         __ c_ult_d(reg_op1, reg_op2);
 10252         __ movt(dst, src);
 10253         break;
 10254       case 0x06: //less_equal
 10255         __ c_ule_d(reg_op1, reg_op2);
 10256         __ movt(dst, src);
 10257         break;
 10258       default:
 10259         Unimplemented();
 10261   %}
 10263   ins_pipe( pipe_slow );
 10264 %}
 10266 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
 10267   match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
 10268   ins_cost(200);
 10269   format %{
 10270              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpD_reg_reg\n"
 10271              "\tCMOV  $dst,$src \t @cmovD_cmpD_reg_reg"
 10272          %}
 10273   ins_encode %{
 10274     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
 10275     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
 10276     FloatRegister dst = as_FloatRegister($dst$$reg);
 10277     FloatRegister src = as_FloatRegister($src$$reg);
 10279     int     flag = $cop$$cmpcode;
 10281     switch(flag) {
 10282       case 0x01: //equal
 10283         __ c_eq_d(reg_op1, reg_op2);
 10284         __ movt_d(dst, src);
 10285         break;
 10286       case 0x02: //not_equal
 10287         __ c_eq_d(reg_op1, reg_op2);
 10288         __ movf_d(dst, src);
 10289         break;
 10290       case 0x03: //greater
 10291         __ c_ole_d(reg_op1, reg_op2);
 10292         __ movf_d(dst, src);
 10293         break;
 10294       case 0x04: //greater_equal
 10295         __ c_olt_d(reg_op1, reg_op2);
 10296         __ movf_d(dst, src);
 10297         break;
 10298       case 0x05: //less
 10299         __ c_ult_d(reg_op1, reg_op2);
 10300         __ movt_d(dst, src);
 10301         break;
 10302       case 0x06: //less_equal
 10303         __ c_ule_d(reg_op1, reg_op2);
 10304         __ movt_d(dst, src);
 10305         break;
 10306       default:
 10307         Unimplemented();
 10309   %}
 10311   ins_pipe( pipe_slow );
 10312 %}
 10314 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10315   match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10316   ins_cost(200);
 10317   format %{
 10318              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpI_reg_reg\n"
 10319              "\tCMOV  $dst, $src \t @cmovF_cmpI_reg_reg"
 10320          %}
 10322   ins_encode %{
 10323     Register op1 = $tmp1$$Register;
 10324     Register op2 = $tmp2$$Register;
 10325     FloatRegister dst = as_FloatRegister($dst$$reg);
 10326     FloatRegister src = as_FloatRegister($src$$reg);
 10327     int     flag = $cop$$cmpcode;
 10328     Label      L;
 10330     switch(flag) {
 10331       case 0x01: //equal
 10332         __ bne(op1, op2, L);
 10333         __ delayed()->nop();
 10334         __ mov_s(dst, src);
 10335         __ bind(L);
 10336         break;
 10337       case 0x02: //not_equal
 10338         __ beq(op1, op2, L);
 10339         __ delayed()->nop();
 10340         __ mov_s(dst, src);
 10341         __ bind(L);
 10342         break;
 10343       case 0x03: //great
 10344         __ slt(AT, op2, op1);
 10345         __ beq(AT, R0, L);
 10346         __ delayed()->nop();
 10347         __ mov_s(dst, src);
 10348         __ bind(L);
 10349         break;
 10350       case 0x04: //great_equal
 10351         __ slt(AT, op1, op2);
 10352         __ bne(AT, R0, L);
 10353         __ delayed()->nop();
 10354         __ mov_s(dst, src);
 10355         __ bind(L);
 10356         break;
 10357       case 0x05: //less
 10358         __ slt(AT, op1, op2);
 10359         __ beq(AT, R0, L);
 10360         __ delayed()->nop();
 10361         __ mov_s(dst, src);
 10362         __ bind(L);
 10363         break;
 10364       case 0x06: //less_equal
 10365         __ slt(AT, op2, op1);
 10366         __ bne(AT, R0, L);
 10367         __ delayed()->nop();
 10368         __ mov_s(dst, src);
 10369         __ bind(L);
 10370        break;
 10371       default:
 10372         Unimplemented();
 10374   %}
 10376   ins_pipe( pipe_slow );
 10377 %}
 10379 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10380   match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10381   ins_cost(200);
 10382   format %{
 10383              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpI_reg_reg\n"
 10384              "\tCMOV  $dst, $src \t @cmovD_cmpI_reg_reg"
 10385          %}
 10387   ins_encode %{
 10388     Register op1 = $tmp1$$Register;
 10389     Register op2 = $tmp2$$Register;
 10390     FloatRegister dst = as_FloatRegister($dst$$reg);
 10391     FloatRegister src = as_FloatRegister($src$$reg);
 10392     int     flag = $cop$$cmpcode;
 10393     Label      L;
 10395     switch(flag) {
 10396       case 0x01: //equal
 10397         __ bne(op1, op2, L);
 10398         __ delayed()->nop();
 10399         __ mov_d(dst, src);
 10400         __ bind(L);
 10401         break;
 10402       case 0x02: //not_equal
 10403         __ beq(op1, op2, L);
 10404         __ delayed()->nop();
 10405         __ mov_d(dst, src);
 10406         __ bind(L);
 10407         break;
 10408       case 0x03: //great
 10409         __ slt(AT, op2, op1);
 10410         __ beq(AT, R0, L);
 10411         __ delayed()->nop();
 10412         __ mov_d(dst, src);
 10413         __ bind(L);
 10414         break;
 10415       case 0x04: //great_equal
 10416         __ slt(AT, op1, op2);
 10417         __ bne(AT, R0, L);
 10418         __ delayed()->nop();
 10419         __ mov_d(dst, src);
 10420         __ bind(L);
 10421         break;
 10422       case 0x05: //less
 10423         __ slt(AT, op1, op2);
 10424         __ beq(AT, R0, L);
 10425         __ delayed()->nop();
 10426         __ mov_d(dst, src);
 10427         __ bind(L);
 10428         break;
 10429       case 0x06: //less_equal
 10430         __ slt(AT, op2, op1);
 10431         __ bne(AT, R0, L);
 10432         __ delayed()->nop();
 10433         __ mov_d(dst, src);
 10434         __ bind(L);
 10435         break;
 10436       default:
 10437         Unimplemented();
 10439   %}
 10441   ins_pipe( pipe_slow );
 10442 %}
 10444 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
 10445   match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
 10446   ins_cost(200);
 10447   format %{
 10448              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpP_reg_reg\n"
 10449              "\tCMOV  $dst, $src \t @cmovD_cmpP_reg_reg"
 10450          %}
 10452   ins_encode %{
 10453     Register op1 = $tmp1$$Register;
 10454     Register op2 = $tmp2$$Register;
 10455     FloatRegister dst = as_FloatRegister($dst$$reg);
 10456     FloatRegister src = as_FloatRegister($src$$reg);
 10457     int     flag = $cop$$cmpcode;
 10458     Label      L;
 10460     switch(flag) {
 10461       case 0x01: //equal
 10462         __ bne(op1, op2, L);
 10463         __ delayed()->nop();
 10464         __ mov_d(dst, src);
 10465         __ bind(L);
 10466         break;
 10467       case 0x02: //not_equal
 10468         __ beq(op1, op2, L);
 10469         __ delayed()->nop();
 10470         __ mov_d(dst, src);
 10471         __ bind(L);
 10472         break;
 10473       case 0x03: //great
 10474         __ slt(AT, op2, op1);
 10475         __ beq(AT, R0, L);
 10476         __ delayed()->nop();
 10477         __ mov_d(dst, src);
 10478         __ bind(L);
 10479         break;
 10480       case 0x04: //great_equal
 10481         __ slt(AT, op1, op2);
 10482         __ bne(AT, R0, L);
 10483         __ delayed()->nop();
 10484         __ mov_d(dst, src);
 10485         __ bind(L);
 10486         break;
 10487       case 0x05: //less
 10488         __ slt(AT, op1, op2);
 10489         __ beq(AT, R0, L);
 10490         __ delayed()->nop();
 10491         __ mov_d(dst, src);
 10492         __ bind(L);
 10493         break;
 10494       case 0x06: //less_equal
 10495         __ slt(AT, op2, op1);
 10496         __ bne(AT, R0, L);
 10497         __ delayed()->nop();
 10498         __ mov_d(dst, src);
 10499         __ bind(L);
 10500         break;
 10501       default:
 10502         Unimplemented();
 10504   %}
 10506   ins_pipe( pipe_slow );
 10507 %}
 10509 //FIXME
 10510 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10511   match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10512   ins_cost(80);
 10513   format %{
 10514              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpF_reg_reg\n"
 10515              "\tCMOV  $dst,$src \t @cmovI_cmpF_reg_reg"
 10516          %}
 10518   ins_encode %{
 10519     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10520     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10521     Register dst = $dst$$Register;
 10522     Register src = $src$$Register;
 10523     int     flag = $cop$$cmpcode;
 10525     switch(flag) {
 10526       case 0x01: //equal
 10527         __ c_eq_s(reg_op1, reg_op2);
 10528         __ movt(dst, src);
 10529         break;
 10530       case 0x02: //not_equal
 10531         __ c_eq_s(reg_op1, reg_op2);
 10532         __ movf(dst, src);
 10533         break;
 10534       case 0x03: //greater
 10535         __ c_ole_s(reg_op1, reg_op2);
 10536         __ movf(dst, src);
 10537         break;
 10538       case 0x04: //greater_equal
 10539         __ c_olt_s(reg_op1, reg_op2);
 10540         __ movf(dst, src);
 10541         break;
 10542       case 0x05: //less
 10543         __ c_ult_s(reg_op1, reg_op2);
 10544         __ movt(dst, src);
 10545         break;
 10546       case 0x06: //less_equal
 10547         __ c_ule_s(reg_op1, reg_op2);
 10548         __ movt(dst, src);
 10549         break;
 10550       default:
 10551         Unimplemented();
 10553   %}
 10554   ins_pipe( pipe_slow );
 10555 %}
 10557 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10558   match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10559   ins_cost(200);
 10560   format %{
 10561              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpF_reg_reg\n"
 10562              "\tCMOV  $dst,$src \t @cmovF_cmpF_reg_reg"
 10563          %}
 10565   ins_encode %{
 10566     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10567     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10568     FloatRegister dst = $dst$$FloatRegister;
 10569     FloatRegister src = $src$$FloatRegister;
 10570     int    flag = $cop$$cmpcode;
 10572     switch(flag) {
 10573       case 0x01: //equal
 10574         __ c_eq_s(reg_op1, reg_op2);
 10575         __ movt_s(dst, src);
 10576         break;
 10577       case 0x02: //not_equal
 10578         __ c_eq_s(reg_op1, reg_op2);
 10579         __ movf_s(dst, src);
 10580         break;
 10581       case 0x03: //greater
 10582         __ c_ole_s(reg_op1, reg_op2);
 10583         __ movf_s(dst, src);
 10584         break;
 10585       case 0x04: //greater_equal
 10586         __ c_olt_s(reg_op1, reg_op2);
 10587         __ movf_s(dst, src);
 10588         break;
 10589       case 0x05: //less
 10590         __ c_ult_s(reg_op1, reg_op2);
 10591         __ movt_s(dst, src);
 10592         break;
 10593       case 0x06: //less_equal
 10594         __ c_ule_s(reg_op1, reg_op2);
 10595         __ movt_s(dst, src);
 10596         break;
 10597       default:
 10598         Unimplemented();
 10600   %}
 10601   ins_pipe( pipe_slow );
 10602 %}
 10604 // Manifest a CmpL result in an integer register.  Very painful.
 10605 // This is the test to avoid.
 10606 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
 10607   match(Set dst (CmpL3 src1 src2));
 10608   ins_cost(1000);
 10609   format %{ "cmpL3  $dst, $src1, $src2 @ cmpL3_reg_reg" %}
 10610   ins_encode %{
 10611     Register opr1 = as_Register($src1$$reg);
 10612     Register opr2 = as_Register($src2$$reg);
 10613     Register dst  = as_Register($dst$$reg);
 10615     Label Done;
 10617     __ subu(AT, opr1, opr2);
 10618     __ bltz(AT, Done);
 10619     __ delayed()->daddiu(dst, R0, -1);
 10621     __ move(dst, 1);
 10622     __ movz(dst, R0, AT);
 10624     __ bind(Done);
 10625   %}
 10626   ins_pipe( pipe_slow );
 10627 %}
 10629 //
 10630 // less_rsult     = -1
 10631 // greater_result =  1
 10632 // equal_result   =  0
 10633 // nan_result     = -1
 10634 //
 10635 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
 10636   match(Set dst (CmpF3 src1 src2));
 10637   ins_cost(1000);
 10638   format %{ "cmpF3  $dst, $src1, $src2 @ cmpF3_reg_reg" %}
 10639   ins_encode %{
 10640     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10641     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10642     Register dst = as_Register($dst$$reg);
 10644     Label Done;
 10646     __ c_ult_s(src1, src2);
 10647     __ bc1t(Done);
 10648     __ delayed()->daddiu(dst, R0, -1);
 10650     __ c_eq_s(src1, src2);
 10651     __ move(dst, 1);
 10652     __ movt(dst, R0);
 10654     __ bind(Done);
 10655   %}
 10656   ins_pipe( pipe_slow );
 10657 %}
 10659 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
 10660   match(Set dst (CmpD3 src1 src2));
 10661   ins_cost(1000);
 10662   format %{ "cmpD3  $dst, $src1, $src2 @ cmpD3_reg_reg" %}
 10663   ins_encode %{
 10664     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10665     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10666     Register dst = as_Register($dst$$reg);
 10668     Label Done;
 10670     __ c_ult_d(src1, src2);
 10671     __ bc1t(Done);
 10672     __ delayed()->daddiu(dst, R0, -1);
 10674     __ c_eq_d(src1, src2);
 10675     __ move(dst, 1);
 10676     __ movt(dst, R0);
 10678     __ bind(Done);
 10679   %}
 10680   ins_pipe( pipe_slow );
 10681 %}
 10683 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
 10684   match(Set dummy (ClearArray cnt base));
 10685   format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
 10686   ins_encode %{
 10687     //Assume cnt is the number of bytes in an array to be cleared,
 10688     //and base points to the starting address of the array.
 10689     Register base = $base$$Register;
 10690     Register num  = $cnt$$Register;
 10691     Label Loop, done;
 10693     __ beq(num, R0, done);
 10694     __ delayed()->daddu(AT, base, R0);
 10696     __ move(T9, num);  /* T9 = words */
 10698     __ bind(Loop);
 10699     __ sd(R0, AT, 0);
 10700     __ daddi(T9, T9, -1);
 10701     __ bne(T9, R0, Loop);
 10702     __ delayed()->daddi(AT, AT, wordSize);
 10704     __ bind(done);
 10705   %}
 10706   ins_pipe( pipe_slow );
 10707 %}
 10709 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2,  mA7RegI cnt2, no_Ax_mRegI result) %{
 10710   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 10711   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
 10713   format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
 10714   ins_encode %{
 10715     // Get the first character position in both strings
 10716     //         [8] char array, [12] offset, [16] count
 10717     Register str1   = $str1$$Register;
 10718     Register str2   = $str2$$Register;
 10719     Register cnt1   = $cnt1$$Register;
 10720     Register cnt2   = $cnt2$$Register;
 10721     Register result = $result$$Register;
 10723     Label L, Loop, haveResult, done;
 10725    // compute the and difference of lengths (in result)
 10726    __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
 10728    // compute the shorter length (in cnt1)
 10729    __ slt(AT, cnt2, cnt1);
 10730    __ movn(cnt1, cnt2, AT);
 10732    // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
 10733    __ bind(Loop);                        // Loop begin
 10734    __ beq(cnt1, R0, done);
 10735    __ delayed()->lhu(AT, str1, 0);;
 10737    // compare current character
 10738    __ lhu(cnt2, str2, 0);
 10739    __ bne(AT, cnt2, haveResult);
 10740    __ delayed()->addi(str1, str1, 2);
 10741    __ addi(str2, str2, 2);
 10742    __ b(Loop);
 10743    __ delayed()->addi(cnt1, cnt1, -1);   // Loop end
 10745    __ bind(haveResult);
 10746    __ subu(result, AT, cnt2);
 10748    __ bind(done);
 10749   %}
 10751   ins_pipe( pipe_slow );
 10752 %}
 10754 // intrinsic optimization
 10755 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
 10756   match(Set result (StrEquals (Binary str1 str2) cnt));
 10757   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
 10759   format %{ "String Equal $str1, $str2, len:$cnt  tmp:$temp -> $result @ string_equals" %}
 10760   ins_encode %{
 10761     // Get the first character position in both strings
 10762     //         [8] char array, [12] offset, [16] count
 10763     Register str1   = $str1$$Register;
 10764     Register str2   = $str2$$Register;
 10765     Register cnt    = $cnt$$Register;
 10766     Register tmp    = $temp$$Register;
 10767     Register result = $result$$Register;
 10769     Label    Loop, done;
 10772    __ beq(str1, str2, done);  // same char[] ?
 10773    __ delayed()->daddiu(result, R0, 1);
 10775    __ bind(Loop);             // Loop begin
 10776    __ beq(cnt, R0, done);
 10777    __ delayed()->daddiu(result, R0, 1); // count == 0
 10779    // compare current character
 10780    __ lhu(AT, str1, 0);;
 10781    __ lhu(tmp, str2, 0);
 10782    __ bne(AT, tmp, done);
 10783    __ delayed()->daddi(result, R0, 0);
 10784    __ addi(str1, str1, 2);
 10785    __ addi(str2, str2, 2);
 10786    __ b(Loop);
 10787    __ delayed()->addi(cnt, cnt, -1);  // Loop end
 10789    __ bind(done);
 10790   %}
 10792   ins_pipe( pipe_slow );
 10793 %}
 10795 //----------Arithmetic Instructions-------------------------------------------
 10796 //----------Addition Instructions---------------------------------------------
 10797 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10798   match(Set dst (AddI src1 src2));
 10800   format %{ "add   $dst, $src1, $src2 #@addI_Reg_Reg" %}
 10801   ins_encode %{
 10802     Register  dst = $dst$$Register;
 10803     Register src1 = $src1$$Register;
 10804     Register src2 = $src2$$Register;
 10805     __ addu32(dst, src1, src2);
 10806   %}
 10807   ins_pipe( ialu_regI_regI );
 10808 %}
 10810 instruct addI_Reg_imm(mRegI dst, mRegI src1,  immI src2) %{
 10811   match(Set dst (AddI src1 src2));
 10813   format %{ "add    $dst, $src1, $src2 #@addI_Reg_imm" %}
 10814   ins_encode %{
 10815     Register  dst = $dst$$Register;
 10816     Register src1 = $src1$$Register;
 10817     int       imm = $src2$$constant;
 10819     if(Assembler::is_simm16(imm)) {
 10820        __ addiu32(dst, src1, imm);
 10821     } else {
 10822        __ move(AT, imm);
 10823        __ addu32(dst, src1, AT);
 10825   %}
 10826   ins_pipe( ialu_regI_regI );
 10827 %}
 10829 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
 10830   match(Set dst (AddP src1 src2));
 10832   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg" %}
 10834   ins_encode %{
 10835     Register  dst = $dst$$Register;
 10836     Register src1 = $src1$$Register;
 10837     Register src2 = $src2$$Register;
 10838     __ daddu(dst, src1, src2);
 10839   %}
 10841   ins_pipe( ialu_regI_regI );
 10842 %}
 10844 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
 10845   match(Set dst (AddP src1 (ConvI2L src2)));
 10847   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
 10849   ins_encode %{
 10850     Register  dst = $dst$$Register;
 10851     Register src1 = $src1$$Register;
 10852     Register src2 = $src2$$Register;
 10853     __ daddu(dst, src1, src2);
 10854   %}
 10856   ins_pipe( ialu_regI_regI );
 10857 %}
 10859 instruct addP_reg_imm(mRegP dst, mRegP src1,  immL src2) %{
 10860   match(Set dst (AddP src1 src2));
 10862   format %{ "daddi   $dst, $src1, $src2 #@addP_reg_imm" %}
 10863   ins_encode %{
 10864     Register src1 = $src1$$Register;
 10865     long      src2 = $src2$$constant;
 10866     Register  dst = $dst$$Register;
 10868     if(Assembler::is_simm16(src2)) {
 10869        __ daddiu(dst, src1, src2);
 10870     } else {
 10871        __ set64(AT, src2);
 10872        __ daddu(dst, src1, AT);
 10874   %}
 10875   ins_pipe( ialu_regI_imm16 );
 10876 %}
 10878 // Add Long Register with Register
 10879 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10880   match(Set dst (AddL src1 src2));
 10881   ins_cost(200);
 10882   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
 10884   ins_encode %{
 10885     Register dst_reg = as_Register($dst$$reg);
 10886     Register src1_reg = as_Register($src1$$reg);
 10887     Register src2_reg = as_Register($src2$$reg);
 10889     __ daddu(dst_reg, src1_reg, src2_reg);
 10890   %}
 10892   ins_pipe( ialu_regL_regL );
 10893 %}
 10895 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
 10896 %{
 10897   match(Set dst (AddL src1 src2));
 10899   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_imm " %}
 10900   ins_encode %{
 10901     Register dst_reg  = as_Register($dst$$reg);
 10902     Register src1_reg = as_Register($src1$$reg);
 10903     int      src2_imm = $src2$$constant;
 10905     __ daddiu(dst_reg, src1_reg, src2_imm);
 10906   %}
 10908   ins_pipe( ialu_regL_regL );
 10909 %}
 10911 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
 10912 %{
 10913   match(Set dst (AddL (ConvI2L src1) src2));
 10915   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_imm " %}
 10916   ins_encode %{
 10917     Register dst_reg  = as_Register($dst$$reg);
 10918     Register src1_reg = as_Register($src1$$reg);
 10919     int      src2_imm = $src2$$constant;
 10921     __ daddiu(dst_reg, src1_reg, src2_imm);
 10922   %}
 10924   ins_pipe( ialu_regL_regL );
 10925 %}
 10927 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
 10928   match(Set dst (AddL (ConvI2L src1) src2));
 10929   ins_cost(200);
 10930   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
 10932   ins_encode %{
 10933     Register dst_reg = as_Register($dst$$reg);
 10934     Register src1_reg = as_Register($src1$$reg);
 10935     Register src2_reg = as_Register($src2$$reg);
 10937     __ daddu(dst_reg, src1_reg, src2_reg);
 10938   %}
 10940   ins_pipe( ialu_regL_regL );
 10941 %}
 10943 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
 10944   match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
 10945   ins_cost(200);
 10946   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
 10948   ins_encode %{
 10949     Register dst_reg = as_Register($dst$$reg);
 10950     Register src1_reg = as_Register($src1$$reg);
 10951     Register src2_reg = as_Register($src2$$reg);
 10953     __ daddu(dst_reg, src1_reg, src2_reg);
 10954   %}
 10956   ins_pipe( ialu_regL_regL );
 10957 %}
 10959 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
 10960   match(Set dst (AddL src1 (ConvI2L src2)));
 10961   ins_cost(200);
 10962   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
 10964   ins_encode %{
 10965     Register dst_reg = as_Register($dst$$reg);
 10966     Register src1_reg = as_Register($src1$$reg);
 10967     Register src2_reg = as_Register($src2$$reg);
 10969     __ daddu(dst_reg, src1_reg, src2_reg);
 10970   %}
 10972   ins_pipe( ialu_regL_regL );
 10973 %}
 10975 //----------Subtraction Instructions-------------------------------------------
 10976 // Integer Subtraction Instructions
 10977 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10978   match(Set dst (SubI src1 src2));
 10979   ins_cost(100);
 10981   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_Reg" %}
 10982   ins_encode %{
 10983     Register  dst = $dst$$Register;
 10984     Register src1 = $src1$$Register;
 10985     Register src2 = $src2$$Register;
 10986     __ subu32(dst, src1, src2);
 10987   %}
 10988   ins_pipe( ialu_regI_regI );
 10989 %}
 10991 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1,  immI16_sub src2) %{
 10992   match(Set dst (SubI src1 src2));
 10993   ins_cost(80);
 10995   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
 10996   ins_encode %{
 10997     Register  dst = $dst$$Register;
 10998     Register src1 = $src1$$Register;
 10999     __ addiu32(dst, src1, -1 * $src2$$constant);
 11000   %}
 11001   ins_pipe( ialu_regI_regI );
 11002 %}
 11004 instruct negI_Reg(mRegI dst, immI0 zero,  mRegI src) %{
 11005   match(Set dst (SubI zero src));
 11006   ins_cost(80);
 11008   format %{ "neg    $dst, $src #@negI_Reg" %}
 11009   ins_encode %{
 11010     Register  dst = $dst$$Register;
 11011     Register  src = $src$$Register;
 11012     __ subu32(dst, R0, src);
 11013   %}
 11014   ins_pipe( ialu_regI_regI );
 11015 %}
 11017 instruct negL_Reg(mRegL dst, immL0 zero,  mRegL src) %{
 11018   match(Set dst (SubL zero src));
 11019   ins_cost(80);
 11021   format %{ "neg    $dst, $src #@negL_Reg" %}
 11022   ins_encode %{
 11023     Register  dst = $dst$$Register;
 11024     Register  src = $src$$Register;
 11025     __ subu(dst, R0, src);
 11026   %}
 11027   ins_pipe( ialu_regI_regI );
 11028 %}
 11030 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1,  immL16_sub src2) %{
 11031   match(Set dst (SubL src1 src2));
 11032   ins_cost(80);
 11034   format %{ "sub    $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
 11035   ins_encode %{
 11036     Register  dst = $dst$$Register;
 11037     Register src1 = $src1$$Register;
 11038     __ daddiu(dst, src1, -1 * $src2$$constant);
 11039   %}
 11040   ins_pipe( ialu_regI_regI );
 11041 %}
 11043 // Subtract Long Register with Register.
 11044 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11045   match(Set dst (SubL src1 src2));
 11046   ins_cost(100);
 11047   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_Reg" %}
 11048   ins_encode %{
 11049     Register dst  = as_Register($dst$$reg);
 11050     Register src1 = as_Register($src1$$reg);
 11051     Register src2 = as_Register($src2$$reg);
 11053     __ subu(dst, src1, src2);
 11054   %}
 11055   ins_pipe( ialu_regL_regL );
 11056 %}
 11058 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11059   match(Set dst (SubL src1 (ConvI2L src2)));
 11060   ins_cost(100);
 11061   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
 11062   ins_encode %{
 11063     Register dst  = as_Register($dst$$reg);
 11064     Register src1 = as_Register($src1$$reg);
 11065     Register src2 = as_Register($src2$$reg);
 11067     __ subu(dst, src1, src2);
 11068   %}
 11069   ins_pipe( ialu_regL_regL );
 11070 %}
 11072 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
 11073   match(Set dst (SubL (ConvI2L src1) src2));
 11074   ins_cost(200);
 11075   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
 11076   ins_encode %{
 11077     Register dst  = as_Register($dst$$reg);
 11078     Register src1 = as_Register($src1$$reg);
 11079     Register src2 = as_Register($src2$$reg);
 11081     __ subu(dst, src1, src2);
 11082   %}
 11083   ins_pipe( ialu_regL_regL );
 11084 %}
 11086 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
 11087   match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
 11088   ins_cost(200);
 11089   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
 11090   ins_encode %{
 11091     Register dst  = as_Register($dst$$reg);
 11092     Register src1 = as_Register($src1$$reg);
 11093     Register src2 = as_Register($src2$$reg);
 11095     __ subu(dst, src1, src2);
 11096   %}
 11097   ins_pipe( ialu_regL_regL );
 11098 %}
 11100 // Integer MOD with Register
 11101 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11102   match(Set dst (ModI src1 src2));
 11103   ins_cost(300);
 11104   format %{ "modi   $dst, $src1, $src2 @ modI_Reg_Reg" %}
 11105   ins_encode %{
 11106     Register  dst = $dst$$Register;
 11107     Register src1 = $src1$$Register;
 11108     Register src2 = $src2$$Register;
 11110     //if (UseLoongsonISA) {
 11111     if (0) {
 11112       // 2016.08.10
 11113       // Experiments show that gsmod is slower that div+mfhi.
 11114       // So I just disable it here.
 11115       __ gsmod(dst, src1, src2);
 11116     } else {
 11117       __ div(src1, src2);
 11118       __ mfhi(dst);
 11120   %}
 11122   //ins_pipe( ialu_mod );
 11123   ins_pipe( ialu_regI_regI );
 11124 %}
 11126 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11127   match(Set dst (ModL src1 src2));
 11128   format %{ "modL  $dst, $src1, $src2 @modL_reg_reg" %}
 11130   ins_encode %{
 11131     Register dst = as_Register($dst$$reg);
 11132     Register op1 = as_Register($src1$$reg);
 11133     Register op2 = as_Register($src2$$reg);
 11135     if (UseLoongsonISA) {
 11136       __ gsdmod(dst, op1, op2);
 11137     } else {
 11138       __ ddiv(op1, op2);
 11139       __ mfhi(dst);
 11141   %}
 11142   ins_pipe( pipe_slow );
 11143 %}
 11145 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11146   match(Set dst (MulI src1 src2));
 11148   ins_cost(300);
 11149   format %{ "mul   $dst, $src1, $src2 @ mulI_Reg_Reg" %}
 11150   ins_encode %{
 11151      Register src1 = $src1$$Register;
 11152      Register src2 = $src2$$Register;
 11153      Register dst  = $dst$$Register;
 11155      __ mul(dst, src1, src2);
 11156   %}
 11157   ins_pipe( ialu_mult );
 11158 %}
 11160 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
 11161   match(Set dst (AddI (MulI src1 src2) src3));
 11163   ins_cost(999);
 11164   format %{ "madd   $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
 11165   ins_encode %{
 11166      Register src1 = $src1$$Register;
 11167      Register src2 = $src2$$Register;
 11168      Register src3 = $src3$$Register;
 11169      Register dst  = $dst$$Register;
 11171      __ mtlo(src3);
 11172      __ madd(src1, src2);
 11173      __ mflo(dst);
 11174   %}
 11175   ins_pipe( ialu_mult );
 11176 %}
 11178 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11179   match(Set dst (DivI src1 src2));
 11181   ins_cost(300);
 11182   format %{ "div   $dst, $src1, $src2 @ divI_Reg_Reg" %}
 11183   ins_encode %{
 11184      Register src1 = $src1$$Register;
 11185      Register src2 = $src2$$Register;
 11186      Register dst  = $dst$$Register;
 11188     // In MIPS, div does not cause exception.
 11189     //   We must trap an exception manually.
 11190     __ teq(R0, src2, 0x7);
 11192     if (UseLoongsonISA) {
 11193       __ gsdiv(dst, src1, src2);
 11194     } else {
 11195       __ div(src1, src2);
 11197       __ nop();
 11198       __ nop();
 11199       __ mflo(dst);
 11201   %}
 11202   ins_pipe( ialu_mod );
 11203 %}
 11205 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
 11206   match(Set dst (DivF src1 src2));
 11208   ins_cost(300);
 11209   format %{ "divF   $dst, $src1, $src2 @ divF_Reg_Reg" %}
 11210   ins_encode %{
 11211      FloatRegister src1 = $src1$$FloatRegister;
 11212      FloatRegister src2 = $src2$$FloatRegister;
 11213      FloatRegister dst  = $dst$$FloatRegister;
 11215     /* Here do we need to trap an exception manually ? */
 11216     __ div_s(dst, src1, src2);
 11217   %}
 11218   ins_pipe( pipe_slow );
 11219 %}
 11221 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
 11222   match(Set dst (DivD src1 src2));
 11224   ins_cost(300);
 11225   format %{ "divD   $dst, $src1, $src2 @ divD_Reg_Reg" %}
 11226   ins_encode %{
 11227      FloatRegister src1 = $src1$$FloatRegister;
 11228      FloatRegister src2 = $src2$$FloatRegister;
 11229      FloatRegister dst  = $dst$$FloatRegister;
 11231     /* Here do we need to trap an exception manually ? */
 11232     __ div_d(dst, src1, src2);
 11233   %}
 11234   ins_pipe( pipe_slow );
 11235 %}
 11237 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11238   match(Set dst (MulL src1 src2));
 11239   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_reg" %}
 11240   ins_encode %{
 11241     Register dst = as_Register($dst$$reg);
 11242     Register op1 = as_Register($src1$$reg);
 11243     Register op2 = as_Register($src2$$reg);
 11245     if (UseLoongsonISA) {
 11246       __ gsdmult(dst, op1, op2);
 11247     } else {
 11248       __ dmult(op1, op2);
 11249       __ mflo(dst);
 11251   %}
 11252   ins_pipe( pipe_slow );
 11253 %}
 11255 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11256   match(Set dst (MulL src1 (ConvI2L src2)));
 11257   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_regI2L" %}
 11258   ins_encode %{
 11259     Register dst = as_Register($dst$$reg);
 11260     Register op1 = as_Register($src1$$reg);
 11261     Register op2 = as_Register($src2$$reg);
 11263     if (UseLoongsonISA) {
 11264       __ gsdmult(dst, op1, op2);
 11265     } else {
 11266       __ dmult(op1, op2);
 11267       __ mflo(dst);
 11269   %}
 11270   ins_pipe( pipe_slow );
 11271 %}
 11273 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11274   match(Set dst (DivL src1 src2));
 11275   format %{ "divL  $dst, $src1, $src2 @divL_reg_reg" %}
 11277   ins_encode %{
 11278     Register dst = as_Register($dst$$reg);
 11279     Register op1 = as_Register($src1$$reg);
 11280     Register op2 = as_Register($src2$$reg);
 11282     if (UseLoongsonISA) {
 11283       __ gsddiv(dst, op1, op2);
 11284     } else {
 11285       __ ddiv(op1, op2);
 11286       __ mflo(dst);
 11288   %}
 11289   ins_pipe( pipe_slow );
 11290 %}
 11292 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 11293   match(Set dst (AddF src1 src2));
 11294   format %{ "AddF  $dst, $src1, $src2 @addF_reg_reg" %}
 11295   ins_encode %{
 11296     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11297     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11298     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11300     __ add_s(dst, src1, src2);
 11301   %}
 11302   ins_pipe( fpu_regF_regF );
 11303 %}
 11305 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 11306   match(Set dst (SubF src1 src2));
 11307   format %{ "SubF  $dst, $src1, $src2 @subF_reg_reg" %}
 11308   ins_encode %{
 11309     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11310     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11311     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11313     __ sub_s(dst, src1, src2);
 11314   %}
 11315   ins_pipe( fpu_regF_regF );
 11316 %}
 11317 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 11318   match(Set dst (AddD src1 src2));
 11319   format %{ "AddD  $dst, $src1, $src2 @addD_reg_reg" %}
 11320   ins_encode %{
 11321     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11322     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11323     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11325     __ add_d(dst, src1, src2);
 11326   %}
 11327   ins_pipe( fpu_regF_regF );
 11328 %}
 11330 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 11331   match(Set dst (SubD src1 src2));
 11332   format %{ "SubD  $dst, $src1, $src2 @subD_reg_reg" %}
 11333   ins_encode %{
 11334     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11335     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11336     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11338     __ sub_d(dst, src1, src2);
 11339   %}
 11340   ins_pipe( fpu_regF_regF );
 11341 %}
 11343 instruct negF_reg(regF dst, regF src) %{
 11344   match(Set dst (NegF src));
 11345   format %{ "negF  $dst, $src @negF_reg" %}
 11346   ins_encode %{
 11347     FloatRegister src = as_FloatRegister($src$$reg);
 11348     FloatRegister dst = as_FloatRegister($dst$$reg);
 11350     __ neg_s(dst, src);
 11351   %}
 11352   ins_pipe( fpu_regF_regF );
 11353 %}
 11355 instruct negD_reg(regD dst, regD src) %{
 11356   match(Set dst (NegD src));
 11357   format %{ "negD  $dst, $src @negD_reg" %}
 11358   ins_encode %{
 11359     FloatRegister src = as_FloatRegister($src$$reg);
 11360     FloatRegister dst = as_FloatRegister($dst$$reg);
 11362     __ neg_d(dst, src);
 11363   %}
 11364   ins_pipe( fpu_regF_regF );
 11365 %}
 11368 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 11369   match(Set dst (MulF src1 src2));
 11370   format %{ "MULF  $dst, $src1, $src2 @mulF_reg_reg" %}
 11371   ins_encode %{
 11372     FloatRegister src1 = $src1$$FloatRegister;
 11373     FloatRegister src2 = $src2$$FloatRegister;
 11374     FloatRegister dst  = $dst$$FloatRegister;
 11376     __ mul_s(dst, src1, src2);
 11377   %}
 11378   ins_pipe( fpu_regF_regF );
 11379 %}
 11381 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
 11382   match(Set dst (AddF (MulF src1 src2) src3));
 11383   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 11384   ins_cost(44444);
 11385   format %{ "maddF  $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
 11386   ins_encode %{
 11387     FloatRegister src1 = $src1$$FloatRegister;
 11388     FloatRegister src2 = $src2$$FloatRegister;
 11389     FloatRegister src3 = $src3$$FloatRegister;
 11390     FloatRegister dst  = $dst$$FloatRegister;
 11392     __ madd_s(dst, src1, src2, src3);
 11393   %}
 11394   ins_pipe( fpu_regF_regF );
 11395 %}
 11397 // Mul two double precision floating piont number
 11398 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 11399   match(Set dst (MulD src1 src2));
 11400   format %{ "MULD  $dst, $src1, $src2 @mulD_reg_reg" %}
 11401   ins_encode %{
 11402     FloatRegister src1 = $src1$$FloatRegister;
 11403     FloatRegister src2 = $src2$$FloatRegister;
 11404     FloatRegister dst  = $dst$$FloatRegister;
 11406     __ mul_d(dst, src1, src2);
 11407   %}
 11408   ins_pipe( fpu_regF_regF );
 11409 %}
 11411 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
 11412   match(Set dst (AddD (MulD src1 src2) src3));
 11413   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 11414   ins_cost(44444);
 11415   format %{ "maddD  $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
 11416   ins_encode %{
 11417     FloatRegister src1 = $src1$$FloatRegister;
 11418     FloatRegister src2 = $src2$$FloatRegister;
 11419     FloatRegister src3 = $src3$$FloatRegister;
 11420     FloatRegister dst  = $dst$$FloatRegister;
 11422     __ madd_d(dst, src1, src2, src3);
 11423   %}
 11424   ins_pipe( fpu_regF_regF );
 11425 %}
 11427 instruct absF_reg(regF dst, regF src) %{
 11428   match(Set dst (AbsF src));
 11429   ins_cost(100);
 11430   format %{ "absF  $dst, $src @absF_reg" %}
 11431   ins_encode %{
 11432     FloatRegister src = as_FloatRegister($src$$reg);
 11433     FloatRegister dst = as_FloatRegister($dst$$reg);
 11435     __ abs_s(dst, src);
 11436   %}
 11437   ins_pipe( fpu_regF_regF );
 11438 %}
 11441 // intrinsics for math_native.
 11442 // AbsD  SqrtD  CosD  SinD  TanD  LogD  Log10D
 11444 instruct absD_reg(regD dst, regD src) %{
 11445   match(Set dst (AbsD src));
 11446   ins_cost(100);
 11447   format %{ "absD  $dst, $src @absD_reg" %}
 11448   ins_encode %{
 11449     FloatRegister src = as_FloatRegister($src$$reg);
 11450     FloatRegister dst = as_FloatRegister($dst$$reg);
 11452     __ abs_d(dst, src);
 11453   %}
 11454   ins_pipe( fpu_regF_regF );
 11455 %}
 11457 instruct sqrtD_reg(regD dst, regD src) %{
 11458   match(Set dst (SqrtD src));
 11459   ins_cost(100);
 11460   format %{ "SqrtD  $dst, $src @sqrtD_reg" %}
 11461   ins_encode %{
 11462     FloatRegister src = as_FloatRegister($src$$reg);
 11463     FloatRegister dst = as_FloatRegister($dst$$reg);
 11465     __ sqrt_d(dst, src);
 11466   %}
 11467   ins_pipe( fpu_regF_regF );
 11468 %}
 11470 instruct sqrtF_reg(regF dst, regF src) %{
 11471   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 11472   ins_cost(100);
 11473   format %{ "SqrtF  $dst, $src @sqrtF_reg" %}
 11474   ins_encode %{
 11475     FloatRegister src = as_FloatRegister($src$$reg);
 11476     FloatRegister dst = as_FloatRegister($dst$$reg);
 11478     __ sqrt_s(dst, src);
 11479   %}
 11480   ins_pipe( fpu_regF_regF );
 11481 %}
 11482 //----------------------------------Logical Instructions----------------------
 11483 //__________________________________Integer Logical Instructions-------------
 11485 //And Instuctions
 11486 // And Register with Immediate
 11487 instruct andI_Reg_immI(mRegI dst, mRegI src1,  immI src2) %{
 11488   match(Set dst (AndI src1 src2));
 11490   format %{ "and  $dst, $src1, $src2 #@andI_Reg_immI" %}
 11491   ins_encode %{
 11492     Register dst = $dst$$Register;
 11493     Register src = $src1$$Register;
 11494     int      val = $src2$$constant;
 11496     __ move(AT, val);
 11497     __ andr(dst, src, AT);
 11498   %}
 11499   ins_pipe( ialu_regI_regI );
 11500 %}
 11502 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 11503   match(Set dst (AndI src1 src2));
 11504   ins_cost(60);
 11506   format %{ "and  $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
 11507   ins_encode %{
 11508     Register dst = $dst$$Register;
 11509     Register src = $src1$$Register;
 11510     int      val = $src2$$constant;
 11512     __ andi(dst, src, val);
 11513   %}
 11514   ins_pipe( ialu_regI_regI );
 11515 %}
 11517 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1,  immI_nonneg_mask mask) %{
 11518   match(Set dst (AndI src1 mask));
 11519   ins_cost(60);
 11521   format %{ "and  $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
 11522   ins_encode %{
 11523     Register dst = $dst$$Register;
 11524     Register src = $src1$$Register;
 11525     int     size = Assembler::is_int_mask($mask$$constant);
 11527     __ ext(dst, src, 0, size);
 11528   %}
 11529   ins_pipe( ialu_regI_regI );
 11530 %}
 11532 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1,  immL_nonneg_mask mask) %{
 11533   match(Set dst (AndL src1 mask));
 11534   ins_cost(60);
 11536   format %{ "and  $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
 11537   ins_encode %{
 11538     Register dst = $dst$$Register;
 11539     Register src = $src1$$Register;
 11540     int     size = Assembler::is_jlong_mask($mask$$constant);
 11542     __ dext(dst, src, 0, size);
 11543   %}
 11544   ins_pipe( ialu_regI_regI );
 11545 %}
 11547 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 11548   match(Set dst (XorI src1 src2));
 11549   ins_cost(60);
 11551   format %{ "xori  $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
 11552   ins_encode %{
 11553     Register dst = $dst$$Register;
 11554     Register src = $src1$$Register;
 11555     int      val = $src2$$constant;
 11557        __ xori(dst, src, val);
 11558   %}
 11559   ins_pipe( ialu_regI_regI );
 11560 %}
 11562 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1,  immI_M1 M1) %{
 11563   match(Set dst (XorI src1 M1));
 11564   predicate(UseLoongsonISA && Use3A2000);
 11565   ins_cost(60);
 11567   format %{ "xor  $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
 11568   ins_encode %{
 11569     Register dst = $dst$$Register;
 11570     Register src = $src1$$Register;
 11572     __ gsorn(dst, R0, src);
 11573   %}
 11574   ins_pipe( ialu_regI_regI );
 11575 %}
 11577 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1,  immI_M1 M1) %{
 11578   match(Set dst (XorI (ConvL2I src1) M1));
 11579   predicate(UseLoongsonISA && Use3A2000);
 11580   ins_cost(60);
 11582   format %{ "xor  $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
 11583   ins_encode %{
 11584     Register dst = $dst$$Register;
 11585     Register src = $src1$$Register;
 11587     __ gsorn(dst, R0, src);
 11588   %}
 11589   ins_pipe( ialu_regI_regI );
 11590 %}
 11592 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 11593   match(Set dst (XorL src1 src2));
 11594   ins_cost(60);
 11596   format %{ "xori  $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
 11597   ins_encode %{
 11598     Register dst = $dst$$Register;
 11599     Register src = $src1$$Register;
 11600     int      val = $src2$$constant;
 11602        __ xori(dst, src, val);
 11603   %}
 11604   ins_pipe( ialu_regI_regI );
 11605 %}
 11607 /*
 11608 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1,  immL_M1 M1) %{
 11609   match(Set dst (XorL src1 M1));
 11610   predicate(UseLoongsonISA);
 11611   ins_cost(60);
 11613   format %{ "xor  $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
 11614   ins_encode %{
 11615     Register dst = $dst$$Register;
 11616     Register src = $src1$$Register;
 11618     __ gsorn(dst, R0, src);
 11619   %}
 11620   ins_pipe( ialu_regI_regI );
 11621 %}
 11622 */
 11624 instruct lbu_and_lmask(mRegI dst, memory mem,  immI_255 mask) %{
 11625   match(Set dst (AndI mask (LoadB mem)));
 11626   ins_cost(60);
 11628   format %{ "lhu  $dst, $mem #@lbu_and_lmask" %}
 11629   ins_encode(load_UB_enc(dst, mem));
 11630   ins_pipe( ialu_loadI );
 11631 %}
 11633 instruct lbu_and_rmask(mRegI dst, memory mem,  immI_255 mask) %{
 11634   match(Set dst (AndI (LoadB mem) mask));
 11635   ins_cost(60);
 11637   format %{ "lhu  $dst, $mem #@lbu_and_rmask" %}
 11638   ins_encode(load_UB_enc(dst, mem));
 11639   ins_pipe( ialu_loadI );
 11640 %}
 11642 instruct andI_Reg_Reg(mRegI dst, mRegI src1,  mRegI src2) %{
 11643   match(Set dst (AndI src1 src2));
 11645   format %{ "and    $dst, $src1, $src2 #@andI_Reg_Reg" %}
 11646   ins_encode %{
 11647     Register dst = $dst$$Register;
 11648     Register src1 = $src1$$Register;
 11649     Register src2 = $src2$$Register;
 11650     __ andr(dst, src1, src2);
 11651   %}
 11652   ins_pipe( ialu_regI_regI );
 11653 %}
 11655 instruct andnI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11656   match(Set dst (AndI src1 (XorI src2 M1)));
 11657   predicate(UseLoongsonISA && Use3A2000);
 11659   format %{ "andn   $dst, $src1, $src2 #@andnI_Reg_nReg" %}
 11660   ins_encode %{
 11661     Register dst = $dst$$Register;
 11662     Register src1 = $src1$$Register;
 11663     Register src2 = $src2$$Register;
 11665     __ gsandn(dst, src1, src2);
 11666   %}
 11667   ins_pipe( ialu_regI_regI );
 11668 %}
 11670 instruct ornI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11671   match(Set dst (OrI src1 (XorI src2 M1)));
 11672   predicate(UseLoongsonISA && Use3A2000);
 11674   format %{ "orn    $dst, $src1, $src2 #@ornI_Reg_nReg" %}
 11675   ins_encode %{
 11676     Register dst = $dst$$Register;
 11677     Register src1 = $src1$$Register;
 11678     Register src2 = $src2$$Register;
 11680     __ gsorn(dst, src1, src2);
 11681   %}
 11682   ins_pipe( ialu_regI_regI );
 11683 %}
 11685 instruct andnI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11686   match(Set dst (AndI (XorI src1 M1) src2));
 11687   predicate(UseLoongsonISA && Use3A2000);
 11689   format %{ "andn   $dst, $src2, $src1 #@andnI_nReg_Reg" %}
 11690   ins_encode %{
 11691     Register dst = $dst$$Register;
 11692     Register src1 = $src1$$Register;
 11693     Register src2 = $src2$$Register;
 11695     __ gsandn(dst, src2, src1);
 11696   %}
 11697   ins_pipe( ialu_regI_regI );
 11698 %}
 11700 instruct ornI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11701   match(Set dst (OrI (XorI src1 M1) src2));
 11702   predicate(UseLoongsonISA && Use3A2000);
 11704   format %{ "orn    $dst, $src2, $src1 #@ornI_nReg_Reg" %}
 11705   ins_encode %{
 11706     Register dst = $dst$$Register;
 11707     Register src1 = $src1$$Register;
 11708     Register src2 = $src2$$Register;
 11710     __ gsorn(dst, src2, src1);
 11711   %}
 11712   ins_pipe( ialu_regI_regI );
 11713 %}
 11715 // And Long Register with Register
 11716 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11717   match(Set dst (AndL src1 src2));
 11718   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
 11719   ins_encode %{
 11720     Register dst_reg = as_Register($dst$$reg);
 11721     Register src1_reg = as_Register($src1$$reg);
 11722     Register src2_reg = as_Register($src2$$reg);
 11724     __ andr(dst_reg, src1_reg, src2_reg);
 11725   %}
 11726   ins_pipe( ialu_regL_regL );
 11727 %}
 11729 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11730   match(Set dst (AndL src1 (ConvI2L src2)));
 11731   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
 11732   ins_encode %{
 11733     Register dst_reg = as_Register($dst$$reg);
 11734     Register src1_reg = as_Register($src1$$reg);
 11735     Register src2_reg = as_Register($src2$$reg);
 11737     __ andr(dst_reg, src1_reg, src2_reg);
 11738   %}
 11739   ins_pipe( ialu_regL_regL );
 11740 %}
 11742 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 11743   match(Set dst (AndL src1 src2));
 11744   ins_cost(60);
 11746   format %{ "and  $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
 11747   ins_encode %{
 11748     Register dst = $dst$$Register;
 11749     Register src = $src1$$Register;
 11750     long     val = $src2$$constant;
 11752        __ andi(dst, src, val);
 11753   %}
 11754   ins_pipe( ialu_regI_regI );
 11755 %}
 11757 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1,  immL_0_65535 src2) %{
 11758   match(Set dst (ConvL2I (AndL src1 src2)));
 11759   ins_cost(60);
 11761   format %{ "and  $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
 11762   ins_encode %{
 11763     Register dst = $dst$$Register;
 11764     Register src = $src1$$Register;
 11765     long     val = $src2$$constant;
 11767        __ andi(dst, src, val);
 11768   %}
 11769   ins_pipe( ialu_regI_regI );
 11770 %}
 11772 /*
 11773 instruct andnL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11774   match(Set dst (AndL src1 (XorL src2 M1)));
 11775   predicate(UseLoongsonISA);
 11777   format %{ "andn   $dst, $src1, $src2 #@andnL_Reg_nReg" %}
 11778   ins_encode %{
 11779     Register dst = $dst$$Register;
 11780     Register src1 = $src1$$Register;
 11781     Register src2 = $src2$$Register;
 11783     __ gsandn(dst, src1, src2);
 11784   %}
 11785   ins_pipe( ialu_regI_regI );
 11786 %}
 11787 */
 11789 /*
 11790 instruct ornL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11791   match(Set dst (OrL src1 (XorL src2 M1)));
 11792   predicate(UseLoongsonISA);
 11794   format %{ "orn    $dst, $src1, $src2 #@ornL_Reg_nReg" %}
 11795   ins_encode %{
 11796     Register dst = $dst$$Register;
 11797     Register src1 = $src1$$Register;
 11798     Register src2 = $src2$$Register;
 11800     __ gsorn(dst, src1, src2);
 11801   %}
 11802   ins_pipe( ialu_regI_regI );
 11803 %}
 11804 */
 11806 /*
 11807 instruct andnL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11808   match(Set dst (AndL (XorL src1 M1) src2));
 11809   predicate(UseLoongsonISA);
 11811   format %{ "andn   $dst, $src2, $src1 #@andnL_nReg_Reg" %}
 11812   ins_encode %{
 11813     Register dst = $dst$$Register;
 11814     Register src1 = $src1$$Register;
 11815     Register src2 = $src2$$Register;
 11817     __ gsandn(dst, src2, src1);
 11818   %}
 11819   ins_pipe( ialu_regI_regI );
 11820 %}
 11821 */
 11823 /*
 11824 instruct ornL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11825   match(Set dst (OrL (XorL src1 M1) src2));
 11826   predicate(UseLoongsonISA);
 11828   format %{ "orn    $dst, $src2, $src1 #@ornL_nReg_Reg" %}
 11829   ins_encode %{
 11830     Register dst = $dst$$Register;
 11831     Register src1 = $src1$$Register;
 11832     Register src2 = $src2$$Register;
 11834     __ gsorn(dst, src2, src1);
 11835   %}
 11836   ins_pipe( ialu_regI_regI );
 11837 %}
 11838 */
 11840 instruct andL_Reg_immL_M8(mRegL dst,  immL_M8 M8) %{
 11841   match(Set dst (AndL dst M8));
 11842   ins_cost(60);
 11844   format %{ "and  $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
 11845   ins_encode %{
 11846     Register dst = $dst$$Register;
 11848     __ dins(dst, R0, 0, 3);
 11849   %}
 11850   ins_pipe( ialu_regI_regI );
 11851 %}
 11853 instruct andL_Reg_immL_M5(mRegL dst,  immL_M5 M5) %{
 11854   match(Set dst (AndL dst M5));
 11855   ins_cost(60);
 11857   format %{ "and  $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
 11858   ins_encode %{
 11859     Register dst = $dst$$Register;
 11861     __ dins(dst, R0, 2, 1);
 11862   %}
 11863   ins_pipe( ialu_regI_regI );
 11864 %}
 11866 instruct andL_Reg_immL_M7(mRegL dst,  immL_M7 M7) %{
 11867   match(Set dst (AndL dst M7));
 11868   ins_cost(60);
 11870   format %{ "and  $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
 11871   ins_encode %{
 11872     Register dst = $dst$$Register;
 11874     __ dins(dst, R0, 1, 2);
 11875   %}
 11876   ins_pipe( ialu_regI_regI );
 11877 %}
 11879 instruct andL_Reg_immL_M4(mRegL dst,  immL_M4 M4) %{
 11880   match(Set dst (AndL dst M4));
 11881   ins_cost(60);
 11883   format %{ "and  $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
 11884   ins_encode %{
 11885     Register dst = $dst$$Register;
 11887     __ dins(dst, R0, 0, 2);
 11888   %}
 11889   ins_pipe( ialu_regI_regI );
 11890 %}
 11892 instruct andL_Reg_immL_M121(mRegL dst,  immL_M121 M121) %{
 11893   match(Set dst (AndL dst M121));
 11894   ins_cost(60);
 11896   format %{ "and  $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
 11897   ins_encode %{
 11898     Register dst = $dst$$Register;
 11900     __ dins(dst, R0, 3, 4);
 11901   %}
 11902   ins_pipe( ialu_regI_regI );
 11903 %}
 11905 // Or Long Register with Register
 11906 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11907   match(Set dst (OrL src1 src2));
 11908   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
 11909   ins_encode %{
 11910     Register dst_reg  = $dst$$Register;
 11911     Register src1_reg = $src1$$Register;
 11912     Register src2_reg = $src2$$Register;
 11914     __ orr(dst_reg, src1_reg, src2_reg);
 11915   %}
 11916   ins_pipe( ialu_regL_regL );
 11917 %}
 11919 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
 11920   match(Set dst (OrL (CastP2X src1) src2));
 11921   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
 11922   ins_encode %{
 11923     Register dst_reg  = $dst$$Register;
 11924     Register src1_reg = $src1$$Register;
 11925     Register src2_reg = $src2$$Register;
 11927     __ orr(dst_reg, src1_reg, src2_reg);
 11928   %}
 11929   ins_pipe( ialu_regL_regL );
 11930 %}
 11932 // Xor Long Register with Register
 11933 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11934   match(Set dst (XorL src1 src2));
 11935   format %{ "XOR    $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
 11936   ins_encode %{
 11937     Register dst_reg = as_Register($dst$$reg);
 11938     Register src1_reg = as_Register($src1$$reg);
 11939     Register src2_reg = as_Register($src2$$reg);
 11941     __ xorr(dst_reg, src1_reg, src2_reg);
 11942   %}
 11943   ins_pipe( ialu_regL_regL );
 11944 %}
 11946 // Shift Left by 8-bit immediate
 11947 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 11948   match(Set dst (LShiftI src shift));
 11950   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm" %}
 11951   ins_encode %{
 11952     Register src = $src$$Register;
 11953     Register dst = $dst$$Register;
 11954     int    shamt = $shift$$constant;
 11956     __ sll(dst, src, shamt);
 11957   %}
 11958   ins_pipe( ialu_regI_regI );
 11959 %}
 11961 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
 11962   match(Set dst (LShiftI (ConvL2I src) shift));
 11964   format %{ "SHL    $dst, $src, $shift #@salL2I_Reg_imm" %}
 11965   ins_encode %{
 11966     Register src = $src$$Register;
 11967     Register dst = $dst$$Register;
 11968     int    shamt = $shift$$constant;
 11970     __ sll(dst, src, shamt);
 11971   %}
 11972   ins_pipe( ialu_regI_regI );
 11973 %}
 11975 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
 11976   match(Set dst (AndI (LShiftI src shift) mask));
 11978   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
 11979   ins_encode %{
 11980     Register src = $src$$Register;
 11981     Register dst = $dst$$Register;
 11983     __ sll(dst, src, 16);
 11984   %}
 11985   ins_pipe( ialu_regI_regI );
 11986 %}
 11988 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
 11989 %{
 11990   match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
 11992   format %{ "andi  $dst, $src, 7\t# @land7_2_s" %}
 11993   ins_encode %{
 11994     Register src = $src$$Register;
 11995     Register dst = $dst$$Register;
 11997     __ andi(dst, src, 7);
 11998   %}
 11999   ins_pipe(ialu_regI_regI);
 12000 %}
 12002 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
 12003 %{
 12004   match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
 12006   format %{ "ori  $dst, $src1, $src2\t# @ori2s" %}
 12007   ins_encode %{
 12008     Register src = $src1$$Register;
 12009     int      val = $src2$$constant;
 12010     Register dst = $dst$$Register;
 12012     __ ori(dst, src, val);
 12013   %}
 12014   ins_pipe(ialu_regI_regI);
 12015 %}
 12017 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
 12018 // This idiom is used by the compiler the i2s bytecode.
 12019 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
 12020 %{
 12021   match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
 12023   format %{ "i2s  $dst, $src\t# @i2s" %}
 12024   ins_encode %{
 12025     Register src = $src$$Register;
 12026     Register dst = $dst$$Register;
 12028     __ seh(dst, src);
 12029   %}
 12030   ins_pipe(ialu_regI_regI);
 12031 %}
 12033 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 12034 // This idiom is used by the compiler for the i2b bytecode.
 12035 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
 12036 %{
 12037   match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
 12039   format %{ "i2b  $dst, $src\t# @i2b" %}
 12040   ins_encode %{
 12041     Register src = $src$$Register;
 12042     Register dst = $dst$$Register;
 12044     __ seb(dst, src);
 12045   %}
 12046   ins_pipe(ialu_regI_regI);
 12047 %}
 12050 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
 12051   match(Set dst (LShiftI (ConvL2I src) shift));
 12053   format %{ "SHL    $dst, $src, $shift #@salI_RegL2I_imm" %}
 12054   ins_encode %{
 12055     Register src = $src$$Register;
 12056     Register dst = $dst$$Register;
 12057     int    shamt = $shift$$constant;
 12059     __ sll(dst, src, shamt);
 12060   %}
 12061   ins_pipe( ialu_regI_regI );
 12062 %}
 12064 // Shift Left by 8-bit immediate
 12065 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12066   match(Set dst (LShiftI src shift));
 12068   format %{ "SHL    $dst, $src, $shift #@salI_Reg_Reg" %}
 12069   ins_encode %{
 12070     Register src = $src$$Register;
 12071     Register dst = $dst$$Register;
 12072     Register shamt = $shift$$Register;
 12073     __ sllv(dst, src, shamt);
 12074   %}
 12075   ins_pipe( ialu_regI_regI );
 12076 %}
 12079 // Shift Left Long
 12080 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 12081   //predicate(UseNewLongLShift);
 12082   match(Set dst (LShiftL src shift));
 12083   ins_cost(100);
 12084   format %{ "salL    $dst, $src, $shift @ salL_Reg_imm" %}
 12085   ins_encode %{
 12086     Register src_reg = as_Register($src$$reg);
 12087     Register dst_reg = as_Register($dst$$reg);
 12088     int      shamt = $shift$$constant;
 12090     if (__ is_simm(shamt, 5))
 12091         __ dsll(dst_reg, src_reg, shamt);
 12092     else {
 12093       int sa = Assembler::low(shamt, 6);
 12094       if (sa < 32) {
 12095         __ dsll(dst_reg, src_reg, sa);
 12096       } else {
 12097         __ dsll32(dst_reg, src_reg, sa - 32);
 12100   %}
 12101   ins_pipe( ialu_regL_regL );
 12102 %}
 12104 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
 12105   //predicate(UseNewLongLShift);
 12106   match(Set dst (LShiftL (ConvI2L src) shift));
 12107   ins_cost(100);
 12108   format %{ "salL    $dst, $src, $shift @ salL_RegI2L_imm" %}
 12109   ins_encode %{
 12110     Register src_reg = as_Register($src$$reg);
 12111     Register dst_reg = as_Register($dst$$reg);
 12112     int      shamt = $shift$$constant;
 12114     if (__ is_simm(shamt, 5))
 12115         __ dsll(dst_reg, src_reg, shamt);
 12116     else {
 12117       int sa = Assembler::low(shamt, 6);
 12118       if (sa < 32) {
 12119         __ dsll(dst_reg, src_reg, sa);
 12120       } else {
 12121         __ dsll32(dst_reg, src_reg, sa - 32);
 12124   %}
 12125   ins_pipe( ialu_regL_regL );
 12126 %}
 12128 // Shift Left Long
 12129 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12130   //predicate(UseNewLongLShift);
 12131   match(Set dst (LShiftL src shift));
 12132   ins_cost(100);
 12133   format %{ "salL    $dst, $src, $shift @ salL_Reg_Reg" %}
 12134   ins_encode %{
 12135     Register src_reg = as_Register($src$$reg);
 12136     Register dst_reg = as_Register($dst$$reg);
 12138     __ dsllv(dst_reg, src_reg, $shift$$Register);
 12139   %}
 12140   ins_pipe( ialu_regL_regL );
 12141 %}
 12143 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
 12144   match(Set dst (LShiftL (ConvI2L src) shift));
 12145   ins_cost(100);
 12146   format %{ "salL    $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
 12147   ins_encode %{
 12148     Register src_reg = as_Register($src$$reg);
 12149     Register dst_reg = as_Register($dst$$reg);
 12150     int      shamt = $shift$$constant;
 12152     if (__ is_simm(shamt, 5)) {
 12153       __ dsll(dst_reg, src_reg, shamt);
 12154     } else {
 12155       int sa = Assembler::low(shamt, 6);
 12156       if (sa < 32) {
 12157         __ dsll(dst_reg, src_reg, sa);
 12158       } else {
 12159         __ dsll32(dst_reg, src_reg, sa - 32);
 12162     %}
 12163   ins_pipe( ialu_regL_regL );
 12164 %}
 12166 // Shift Right Long
 12167 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 12168   match(Set dst (RShiftL src shift));
 12169   ins_cost(100);
 12170   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_imm" %}
 12171   ins_encode %{
 12172     Register src_reg = as_Register($src$$reg);
 12173     Register dst_reg = as_Register($dst$$reg);
 12174     int      shamt = ($shift$$constant & 0x3f);
 12175     if (__  is_simm(shamt, 5))
 12176       __ dsra(dst_reg, src_reg, shamt);
 12177     else {
 12178       int sa = Assembler::low(shamt, 6);
 12179       if (sa < 32) {
 12180         __ dsra(dst_reg, src_reg, sa);
 12181       } else {
 12182         __ dsra32(dst_reg, src_reg, sa - 32);
 12185   %}
 12186   ins_pipe( ialu_regL_regL );
 12187 %}
 12189 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
 12190   match(Set dst (ConvL2I (RShiftL src shift)));
 12191   ins_cost(100);
 12192   format %{ "sarL    $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
 12193   ins_encode %{
 12194     Register src_reg = as_Register($src$$reg);
 12195     Register dst_reg = as_Register($dst$$reg);
 12196     int      shamt   = $shift$$constant;
 12198     __ dsra32(dst_reg, src_reg, shamt - 32);
 12199   %}
 12200   ins_pipe( ialu_regL_regL );
 12201 %}
 12203 // Shift Right Long arithmetically
 12204 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12205   //predicate(UseNewLongLShift);
 12206   match(Set dst (RShiftL src shift));
 12207   ins_cost(100);
 12208   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_Reg" %}
 12209   ins_encode %{
 12210     Register src_reg = as_Register($src$$reg);
 12211     Register dst_reg = as_Register($dst$$reg);
 12213     __ dsrav(dst_reg, src_reg, $shift$$Register);
 12214   %}
 12215   ins_pipe( ialu_regL_regL );
 12216 %}
 12218 // Shift Right Long logically
 12219 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12220   match(Set dst (URShiftL src shift));
 12221   ins_cost(100);
 12222   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_Reg" %}
 12223   ins_encode %{
 12224     Register src_reg = as_Register($src$$reg);
 12225     Register dst_reg = as_Register($dst$$reg);
 12227     __ dsrlv(dst_reg, src_reg, $shift$$Register);
 12228   %}
 12229   ins_pipe( ialu_regL_regL );
 12230 %}
 12232 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
 12233   match(Set dst (URShiftL src shift));
 12234   ins_cost(80);
 12235   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
 12236   ins_encode %{
 12237     Register src_reg = as_Register($src$$reg);
 12238     Register dst_reg = as_Register($dst$$reg);
 12239     int        shamt = $shift$$constant;
 12241     __ dsrl(dst_reg, src_reg, shamt);
 12242   %}
 12243   ins_pipe( ialu_regL_regL );
 12244 %}
 12246 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
 12247   match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
 12248   ins_cost(80);
 12249   format %{ "dext    $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
 12250   ins_encode %{
 12251     Register src_reg = as_Register($src$$reg);
 12252     Register dst_reg = as_Register($dst$$reg);
 12253     int        shamt = $shift$$constant;
 12255     __ dext(dst_reg, src_reg, shamt, 31);
 12256   %}
 12257   ins_pipe( ialu_regL_regL );
 12258 %}
 12260 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
 12261   match(Set dst (URShiftL (CastP2X src) shift));
 12262   ins_cost(80);
 12263   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
 12264   ins_encode %{
 12265     Register src_reg = as_Register($src$$reg);
 12266     Register dst_reg = as_Register($dst$$reg);
 12267     int        shamt = $shift$$constant;
 12269     __ dsrl(dst_reg, src_reg, shamt);
 12270   %}
 12271   ins_pipe( ialu_regL_regL );
 12272 %}
 12274 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
 12275   match(Set dst (URShiftL src shift));
 12276   ins_cost(80);
 12277   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
 12278   ins_encode %{
 12279     Register src_reg = as_Register($src$$reg);
 12280     Register dst_reg = as_Register($dst$$reg);
 12281     int        shamt = $shift$$constant;
 12283     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12284   %}
 12285   ins_pipe( ialu_regL_regL );
 12286 %}
 12288 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
 12289   match(Set dst (ConvL2I (URShiftL src shift)));
 12290   predicate(n->in(1)->in(2)->get_int() > 32);
 12291   ins_cost(80);
 12292   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
 12293   ins_encode %{
 12294     Register src_reg = as_Register($src$$reg);
 12295     Register dst_reg = as_Register($dst$$reg);
 12296     int        shamt = $shift$$constant;
 12298     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12299   %}
 12300   ins_pipe( ialu_regL_regL );
 12301 %}
 12303 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
 12304   match(Set dst (URShiftL (CastP2X src) shift));
 12305   ins_cost(80);
 12306   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
 12307   ins_encode %{
 12308     Register src_reg = as_Register($src$$reg);
 12309     Register dst_reg = as_Register($dst$$reg);
 12310     int        shamt = $shift$$constant;
 12312     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12313   %}
 12314   ins_pipe( ialu_regL_regL );
 12315 %}
 12317 // Xor Instructions
 12318 // Xor Register with Register
 12319 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 12320   match(Set dst (XorI src1 src2));
 12322   format %{ "XOR    $dst, $src1, $src2 #@xorI_Reg_Reg" %}
 12324   ins_encode %{
 12325     Register  dst = $dst$$Register;
 12326     Register src1 = $src1$$Register;
 12327     Register src2 = $src2$$Register;
 12328     __ xorr(dst, src1, src2);
 12329     __ sll(dst, dst, 0); /* long -> int */
 12330   %}
 12332   ins_pipe( ialu_regI_regI );
 12333 %}
 12335 // Or Instructions
 12336 // Or Register with Register
 12337 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 12338   match(Set dst (OrI src1 src2));
 12340   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_Reg" %}
 12341   ins_encode %{
 12342     Register  dst = $dst$$Register;
 12343     Register src1 = $src1$$Register;
 12344     Register src2 = $src2$$Register;
 12345     __ orr(dst, src1, src2);
 12346   %}
 12348   ins_pipe( ialu_regI_regI );
 12349 %}
 12351 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
 12352   match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
 12353   predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
 12355   format %{ "rotr     $dst, $src, 1 ...\n\t"
 12356             "srl      $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
 12357   ins_encode %{
 12358     Register   dst = $dst$$Register;
 12359     Register   src = $src$$Register;
 12360     int     rshift = $rshift$$constant;
 12362     __ rotr(dst, src, 1);
 12363     if (rshift - 1) {
 12364       __ srl(dst, dst, rshift - 1);
 12366   %}
 12368   ins_pipe( ialu_regI_regI );
 12369 %}
 12371 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
 12372   match(Set dst (OrI src1 (CastP2X src2)));
 12374   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_castP2X" %}
 12375   ins_encode %{
 12376     Register  dst = $dst$$Register;
 12377     Register src1 = $src1$$Register;
 12378     Register src2 = $src2$$Register;
 12379     __ orr(dst, src1, src2);
 12380   %}
 12382   ins_pipe( ialu_regI_regI );
 12383 %}
 12385 // Logical Shift Right by 8-bit immediate
 12386 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 12387   match(Set dst (URShiftI src shift));
 12388   //effect(KILL cr);
 12390   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_imm" %}
 12391   ins_encode %{
 12392     Register src = $src$$Register;
 12393     Register dst = $dst$$Register;
 12394     int    shift = $shift$$constant;
 12396     __ srl(dst, src, shift);
 12397   %}
 12398   ins_pipe( ialu_regI_regI );
 12399 %}
 12401 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
 12402   match(Set dst (AndI (URShiftI src shift) mask));
 12404   format %{ "ext    $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
 12405   ins_encode %{
 12406     Register src = $src$$Register;
 12407     Register dst = $dst$$Register;
 12408     int      pos = $shift$$constant;
 12409     int     size = Assembler::is_int_mask($mask$$constant);
 12411     __ ext(dst, src, pos, size);
 12412   %}
 12413   ins_pipe( ialu_regI_regI );
 12414 %}
 12416 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
 12417 %{
 12418   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 12419   match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
 12421   ins_cost(100);
 12422   format %{ "rotr    $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
 12423   ins_encode %{
 12424     Register dst = $dst$$Register;
 12425     int      sa  = $rshift$$constant;
 12427     __ rotr(dst, dst, sa);
 12428   %}
 12429   ins_pipe( ialu_regI_regI );
 12430 %}
 12432 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
 12433 %{
 12434   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12435   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 12437   ins_cost(100);
 12438   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
 12439   ins_encode %{
 12440     Register dst = $dst$$Register;
 12441     int      sa  = $rshift$$constant;
 12443     __ drotr(dst, dst, sa);
 12444   %}
 12445   ins_pipe( ialu_regI_regI );
 12446 %}
 12448 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
 12449 %{
 12450   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12451   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 12453   ins_cost(100);
 12454   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
 12455   ins_encode %{
 12456     Register dst = $dst$$Register;
 12457     int      sa  = $rshift$$constant;
 12459     __ drotr32(dst, dst, sa - 32);
 12460   %}
 12461   ins_pipe( ialu_regI_regI );
 12462 %}
 12464 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
 12465 %{
 12466   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 12467   match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
 12469   ins_cost(100);
 12470   format %{ "rotr    $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
 12471   ins_encode %{
 12472     Register dst = $dst$$Register;
 12473     int      sa  = $rshift$$constant;
 12475     __ rotr(dst, dst, sa);
 12476   %}
 12477   ins_pipe( ialu_regI_regI );
 12478 %}
 12480 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
 12481 %{
 12482   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12483   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 12485   ins_cost(100);
 12486   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
 12487   ins_encode %{
 12488     Register dst = $dst$$Register;
 12489     int      sa  = $rshift$$constant;
 12491     __ drotr(dst, dst, sa);
 12492   %}
 12493   ins_pipe( ialu_regI_regI );
 12494 %}
 12496 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
 12497 %{
 12498   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12499   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 12501   ins_cost(100);
 12502   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
 12503   ins_encode %{
 12504     Register dst = $dst$$Register;
 12505     int      sa  = $rshift$$constant;
 12507     __ drotr32(dst, dst, sa - 32);
 12508   %}
 12509   ins_pipe( ialu_regI_regI );
 12510 %}
 12512 // Logical Shift Right
 12513 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12514   match(Set dst (URShiftI src shift));
 12516   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_Reg" %}
 12517   ins_encode %{
 12518     Register src = $src$$Register;
 12519     Register dst = $dst$$Register;
 12520     Register shift = $shift$$Register;
 12521     __ srlv(dst, src, shift);
 12522   %}
 12523   ins_pipe( ialu_regI_regI );
 12524 %}
 12527 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 12528   match(Set dst (RShiftI src shift));
 12529  // effect(KILL cr);
 12531   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_imm" %}
 12532   ins_encode %{
 12533     Register src = $src$$Register;
 12534     Register dst = $dst$$Register;
 12535     int    shift = $shift$$constant;
 12536     __ sra(dst, src, shift);
 12537   %}
 12538   ins_pipe( ialu_regI_regI );
 12539 %}
 12541 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12542   match(Set dst (RShiftI src shift));
 12543  // effect(KILL cr);
 12545   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_Reg" %}
 12546   ins_encode %{
 12547     Register src = $src$$Register;
 12548     Register dst = $dst$$Register;
 12549     Register shift = $shift$$Register;
 12550     __ srav(dst, src, shift);
 12551   %}
 12552   ins_pipe( ialu_regI_regI );
 12553 %}
 12555 //----------Convert Int to Boolean---------------------------------------------
 12557 instruct convI2B(mRegI dst, mRegI src) %{
 12558   match(Set dst (Conv2B src));
 12560   ins_cost(100);
 12561   format %{ "convI2B    $dst, $src @ convI2B"  %}
 12562   ins_encode %{
 12563     Register dst = as_Register($dst$$reg);
 12564     Register src = as_Register($src$$reg);
 12566     if (dst != src) {
 12567       __ daddiu(dst, R0, 1);
 12568       __ movz(dst, R0, src);
 12569     } else {
 12570       __ move(AT, src);
 12571       __ daddiu(dst, R0, 1);
 12572       __ movz(dst, R0, AT);
 12574   %}
 12576   ins_pipe( ialu_regL_regL );
 12577 %}
 12579 instruct convI2L_reg( mRegL dst, mRegI src) %{
 12580   match(Set dst (ConvI2L src));
 12582   ins_cost(100);
 12583   format %{ "SLL    $dst, $src @ convI2L_reg\t"  %}
 12584   ins_encode %{
 12585     Register dst = as_Register($dst$$reg);
 12586     Register src = as_Register($src$$reg);
 12588     if(dst != src) __ sll(dst, src, 0);
 12589   %}
 12590   ins_pipe( ialu_regL_regL );
 12591 %}
 12594 instruct convL2I_reg( mRegI dst, mRegL src ) %{
 12595   match(Set dst (ConvL2I src));
 12597   format %{ "MOV    $dst, $src @ convL2I_reg" %}
 12598   ins_encode %{
 12599     Register dst = as_Register($dst$$reg);
 12600     Register src = as_Register($src$$reg);
 12602     __ sll(dst, src, 0);
 12603   %}
 12605   ins_pipe( ialu_regI_regI );
 12606 %}
 12608 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
 12609   match(Set dst (ConvI2L (ConvL2I src)));
 12611   format %{ "sll    $dst, $src, 0 @ convL2I2L_reg" %}
 12612   ins_encode %{
 12613     Register dst = as_Register($dst$$reg);
 12614     Register src = as_Register($src$$reg);
 12616     __ sll(dst, src, 0);
 12617   %}
 12619   ins_pipe( ialu_regI_regI );
 12620 %}
 12622 instruct convL2D_reg( regD dst, mRegL src ) %{
 12623   match(Set dst (ConvL2D src));
 12624   format %{ "convL2D    $dst, $src @ convL2D_reg" %}
 12625   ins_encode %{
 12626     Register src = as_Register($src$$reg);
 12627     FloatRegister dst = as_FloatRegister($dst$$reg);
 12629     __ dmtc1(src, dst);
 12630     __ cvt_d_l(dst, dst);
 12631   %}
 12633   ins_pipe( pipe_slow );
 12634 %}
 12637 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
 12638   match(Set dst (ConvD2L src));
 12639   ins_cost(150);
 12640   format %{ "convD2L    $dst, $src @ convD2L_reg_fast" %}
 12641   ins_encode %{
 12642     Register dst = as_Register($dst$$reg);
 12643     FloatRegister src = as_FloatRegister($src$$reg);
 12645     Label Done;
 12647     __ trunc_l_d(F30, src);
 12648     // max_long:    0x7fffffffffffffff
 12649     // __ set64(AT, 0x7fffffffffffffff);
 12650     __ daddiu(AT, R0, -1);
 12651     __ dsrl(AT, AT, 1);
 12652     __ dmfc1(dst, F30);
 12654     __ bne(dst, AT, Done);
 12655     __ delayed()->mtc1(R0, F30);
 12657     __ cvt_d_w(F30, F30);
 12658     __ c_ult_d(src, F30);
 12659     __ bc1f(Done);
 12660     __ delayed()->daddiu(T9, R0, -1);
 12662     __ c_un_d(src, src);    //NaN?
 12663     __ subu(dst, T9, AT);
 12664     __ movt(dst, R0);
 12666     __ bind(Done);
 12667   %}
 12669   ins_pipe( pipe_slow );
 12670 %}
 12673 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
 12674   match(Set dst (ConvD2L src));
 12675   ins_cost(250);
 12676   format %{ "convD2L    $dst, $src @ convD2L_reg_slow" %}
 12677   ins_encode %{
 12678     Register dst = as_Register($dst$$reg);
 12679     FloatRegister src = as_FloatRegister($src$$reg);
 12681     Label L;
 12683     __ c_un_d(src, src);    //NaN?
 12684     __ bc1t(L);
 12685     __ delayed();
 12686     __ move(dst, R0);
 12688     __ trunc_l_d(F30, src);
 12689     __ cfc1(AT, 31);
 12690     __ li(T9, 0x10000);
 12691     __ andr(AT, AT, T9);
 12692     __ beq(AT, R0, L);
 12693     __ delayed()->dmfc1(dst, F30);
 12695     __ mov_d(F12, src);
 12696     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
 12697     __ move(dst, V0);
 12698     __ bind(L);
 12699   %}
 12701   ins_pipe( pipe_slow );
 12702 %}
 12705 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
 12706   match(Set dst (ConvF2I src));
 12707   ins_cost(150);
 12708   format %{ "convf2i    $dst, $src @ convF2I_reg_fast" %}
 12709   ins_encode %{
 12710     Register      dreg = $dst$$Register;
 12711     FloatRegister fval = $src$$FloatRegister;
 12712     Label L;
 12714     __ trunc_w_s(F30, fval);
 12715     __ move(AT, 0x7fffffff);
 12716     __ mfc1(dreg, F30);
 12717     __ c_un_s(fval, fval);    //NaN?
 12718     __ movt(dreg, R0);
 12720     __ bne(AT, dreg, L);
 12721     __ delayed()->lui(T9, 0x8000);
 12723     __ mfc1(AT, fval);
 12724     __ andr(AT, AT, T9);
 12726     __ movn(dreg, T9, AT);
 12728     __ bind(L);
 12730   %}
 12732   ins_pipe( pipe_slow );
 12733 %}
 12737 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
 12738   match(Set dst (ConvF2I src));
 12739   ins_cost(250);
 12740   format %{ "convf2i    $dst, $src @ convF2I_reg_slow" %}
 12741   ins_encode %{
 12742     Register      dreg = $dst$$Register;
 12743     FloatRegister fval = $src$$FloatRegister;
 12744     Label L;
 12746     __ c_un_s(fval, fval);    //NaN?
 12747     __ bc1t(L);
 12748     __ delayed();
 12749     __ move(dreg, R0);
 12751     __ trunc_w_s(F30, fval);
 12753     /* Call SharedRuntime:f2i() to do valid convention */
 12754     __ cfc1(AT, 31);
 12755     __ li(T9, 0x10000);
 12756     __ andr(AT, AT, T9);
 12757     __ beq(AT, R0, L);
 12758     __ delayed()->mfc1(dreg, F30);
 12760     __ mov_s(F12, fval);
 12762     //This bug was found when running ezDS's control-panel.
 12763     //    J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
 12764     //
 12765     // An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
 12766     // V0 is corrupted during call_VM_leaf(), and should be preserved.
 12767     //
 12768     __ push(fval);
 12769     if(dreg != V0) {
 12770       __ push(V0);
 12772     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
 12773     if(dreg != V0) {
 12774       __ move(dreg, V0);
 12775       __ pop(V0);
 12777     __ pop(fval);
 12778     __ bind(L);
 12779   %}
 12781   ins_pipe( pipe_slow );
 12782 %}
 12785 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
 12786   match(Set dst (ConvF2L src));
 12787   ins_cost(150);
 12788   format %{ "convf2l    $dst, $src @ convF2L_reg_fast" %}
 12789   ins_encode %{
 12790     Register      dreg = $dst$$Register;
 12791     FloatRegister fval = $src$$FloatRegister;
 12792     Label L;
 12794     __ trunc_l_s(F30, fval);
 12795     __ daddiu(AT, R0, -1);
 12796     __ dsrl(AT, AT, 1);
 12797     __ dmfc1(dreg, F30);
 12798     __ c_un_s(fval, fval);    //NaN?
 12799     __ movt(dreg, R0);
 12801     __ bne(AT, dreg, L);
 12802     __ delayed()->lui(T9, 0x8000);
 12804     __ mfc1(AT, fval);
 12805     __ andr(AT, AT, T9);
 12807     __ dsll32(T9, T9, 0);
 12808     __ movn(dreg, T9, AT);
 12810     __ bind(L);
 12811   %}
 12813   ins_pipe( pipe_slow );
 12814 %}
 12817 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
 12818   match(Set dst (ConvF2L src));
 12819   ins_cost(250);
 12820   format %{ "convf2l    $dst, $src @ convF2L_reg_slow" %}
 12821   ins_encode %{
 12822     Register dst = as_Register($dst$$reg);
 12823     FloatRegister fval = $src$$FloatRegister;
 12824     Label L;
 12826     __ c_un_s(fval, fval);    //NaN?
 12827     __ bc1t(L);
 12828     __ delayed();
 12829     __ move(dst, R0);
 12831     __ trunc_l_s(F30, fval);
 12832     __ cfc1(AT, 31);
 12833     __ li(T9, 0x10000);
 12834     __ andr(AT, AT, T9);
 12835     __ beq(AT, R0, L);
 12836     __ delayed()->dmfc1(dst, F30);
 12838     __ mov_s(F12, fval);
 12839     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
 12840     __ move(dst, V0);
 12841     __ bind(L);
 12842   %}
 12844   ins_pipe( pipe_slow );
 12845 %}
 12847 instruct convL2F_reg( regF dst, mRegL src ) %{
 12848   match(Set dst (ConvL2F src));
 12849   format %{ "convl2f    $dst, $src @ convL2F_reg" %}
 12850   ins_encode %{
 12851     FloatRegister dst = $dst$$FloatRegister;
 12852     Register src = as_Register($src$$reg);
 12853     Label L;
 12855     __ dmtc1(src, dst);
 12856     __ cvt_s_l(dst, dst);
 12857   %}
 12859   ins_pipe( pipe_slow );
 12860 %}
 12862 instruct convI2F_reg( regF dst, mRegI src ) %{
 12863   match(Set dst (ConvI2F src));
 12864   format %{ "convi2f    $dst, $src @ convI2F_reg" %}
 12865   ins_encode %{
 12866     Register      src = $src$$Register;
 12867     FloatRegister dst = $dst$$FloatRegister;
 12869     __ mtc1(src, dst);
 12870     __ cvt_s_w(dst, dst);
 12871   %}
 12873   ins_pipe( fpu_regF_regF );
 12874 %}
 12876 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
 12877   match(Set dst (CmpLTMask p zero));
 12878   ins_cost(100);
 12880   format %{ "sra    $dst, $p, 31 @ cmpLTMask_immI0" %}
 12881     ins_encode %{
 12882        Register src = $p$$Register;
 12883        Register dst = $dst$$Register;
 12885        __ sra(dst, src, 31);
 12886     %}
 12887     ins_pipe( pipe_slow );
 12888 %}
 12891 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
 12892   match(Set dst (CmpLTMask p q));
 12893   ins_cost(400);
 12895   format %{ "cmpLTMask    $dst, $p, $q @ cmpLTMask" %}
 12896   ins_encode %{
 12897     Register p   = $p$$Register;
 12898     Register q   = $q$$Register;
 12899     Register dst = $dst$$Register;
 12901     __ slt(dst, p, q);
 12902     __ subu(dst, R0, dst);
 12903     %}
 12904   ins_pipe( pipe_slow );
 12905 %}
 12907 instruct convP2B(mRegI dst, mRegP src) %{
 12908   match(Set dst (Conv2B src));
 12910   ins_cost(100);
 12911   format %{ "convP2B    $dst, $src @ convP2B"  %}
 12912   ins_encode %{
 12913     Register dst = as_Register($dst$$reg);
 12914     Register src = as_Register($src$$reg);
 12916     if (dst != src) {
 12917       __ daddiu(dst, R0, 1);
 12918       __ movz(dst, R0, src);
 12919     } else {
 12920       __ move(AT, src);
 12921       __ daddiu(dst, R0, 1);
 12922       __ movz(dst, R0, AT);
 12924   %}
 12926   ins_pipe( ialu_regL_regL );
 12927 %}
 12930 instruct convI2D_reg_reg(regD dst, mRegI src) %{
 12931   match(Set dst (ConvI2D src));
 12932   format %{ "conI2D $dst, $src @convI2D_reg" %}
 12933   ins_encode %{
 12934     Register      src = $src$$Register;
 12935     FloatRegister dst = $dst$$FloatRegister;
 12936     __ mtc1(src, dst);
 12937     __ cvt_d_w(dst, dst);
 12938     %}
 12939   ins_pipe( fpu_regF_regF );
 12940 %}
 12942 instruct convF2D_reg_reg(regD dst, regF src) %{
 12943   match(Set dst (ConvF2D src));
 12944   format %{ "convF2D  $dst, $src\t# @convF2D_reg_reg" %}
 12945   ins_encode %{
 12946     FloatRegister dst = $dst$$FloatRegister;
 12947     FloatRegister src = $src$$FloatRegister;
 12949     __ cvt_d_s(dst, src);
 12950   %}
 12951   ins_pipe( fpu_regF_regF );
 12952 %}
 12954 instruct convD2F_reg_reg(regF dst, regD src) %{
 12955   match(Set dst (ConvD2F src));
 12956   format %{ "convD2F  $dst, $src\t# @convD2F_reg_reg" %}
 12957   ins_encode %{
 12958     FloatRegister dst = $dst$$FloatRegister;
 12959     FloatRegister src = $src$$FloatRegister;
 12961     __ cvt_s_d(dst, src);
 12962   %}
 12963   ins_pipe( fpu_regF_regF );
 12964 %}
 12967 // Convert a double to an int.  If the double is a NAN, stuff a zero in instead.
 12968 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
 12969   match(Set dst (ConvD2I src));
 12971   ins_cost(150);
 12972   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
 12974   ins_encode %{
 12975     FloatRegister src = $src$$FloatRegister;
 12976     Register      dst = $dst$$Register;
 12978     Label Done;
 12980     __ trunc_w_d(F30, src);
 12981     // max_int: 2147483647
 12982     __ move(AT, 0x7fffffff);
 12983     __ mfc1(dst, F30);
 12985     __ bne(dst, AT, Done);
 12986     __ delayed()->mtc1(R0, F30);
 12988     __ cvt_d_w(F30, F30);
 12989     __ c_ult_d(src, F30);
 12990     __ bc1f(Done);
 12991     __ delayed()->addiu(T9, R0, -1);
 12993     __ c_un_d(src, src);    //NaN?
 12994     __ subu32(dst, T9, AT);
 12995     __ movt(dst, R0);
 12997     __ bind(Done);
 12998   %}
 12999   ins_pipe( pipe_slow );
 13000 %}
 13003 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
 13004   match(Set dst (ConvD2I src));
 13006   ins_cost(250);
 13007   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
 13009   ins_encode %{
 13010     FloatRegister src = $src$$FloatRegister;
 13011     Register      dst = $dst$$Register;
 13012     Label L;
 13014     __ trunc_w_d(F30, src);
 13015     __ cfc1(AT, 31);
 13016     __ li(T9, 0x10000);
 13017     __ andr(AT, AT, T9);
 13018     __ beq(AT, R0, L);
 13019     __ delayed()->mfc1(dst, F30);
 13021     __ mov_d(F12, src);
 13022     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
 13023     __ move(dst, V0);
 13024     __ bind(L);
 13026   %}
 13027   ins_pipe( pipe_slow );
 13028 %}
 13030 // Convert oop pointer into compressed form
 13031 instruct encodeHeapOop(mRegN dst, mRegP src) %{
 13032   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 13033   match(Set dst (EncodeP src));
 13034   format %{ "encode_heap_oop $dst,$src" %}
 13035   ins_encode %{
 13036     Register src = $src$$Register;
 13037     Register dst = $dst$$Register;
 13039     __ encode_heap_oop(dst, src);
 13040   %}
 13041   ins_pipe( ialu_regL_regL );
 13042 %}
 13044 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
 13045   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
 13046   match(Set dst (EncodeP src));
 13047   format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
 13048   ins_encode %{
 13049     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
 13050   %}
 13051   ins_pipe( ialu_regL_regL );
 13052 %}
 13054 instruct decodeHeapOop(mRegP dst, mRegN src) %{
 13055   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
 13056             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
 13057   match(Set dst (DecodeN src));
 13058   format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
 13059   ins_encode %{
 13060     Register s = $src$$Register;
 13061     Register d = $dst$$Register;
 13063     __ decode_heap_oop(d, s);
 13064   %}
 13065   ins_pipe( ialu_regL_regL );
 13066 %}
 13068 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
 13069   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
 13070             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
 13071   match(Set dst (DecodeN src));
 13072   format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
 13073   ins_encode %{
 13074     Register s = $src$$Register;
 13075     Register d = $dst$$Register;
 13076     if (s != d) {
 13077       __ decode_heap_oop_not_null(d, s);
 13078     } else {
 13079       __ decode_heap_oop_not_null(d);
 13081   %}
 13082   ins_pipe( ialu_regL_regL );
 13083 %}
 13085 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
 13086   match(Set dst (EncodePKlass src));
 13087   format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
 13088   ins_encode %{
 13089     __ encode_klass_not_null($dst$$Register, $src$$Register);
 13090   %}
 13091   ins_pipe( ialu_regL_regL );
 13092 %}
 13094 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
 13095   match(Set dst (DecodeNKlass src));
 13096   format %{ "decode_heap_klass_not_null $dst,$src" %}
 13097   ins_encode %{
 13098     Register s = $src$$Register;
 13099     Register d = $dst$$Register;
 13100     if (s != d) {
 13101       __ decode_klass_not_null(d, s);
 13102     } else {
 13103       __ decode_klass_not_null(d);
 13105   %}
 13106   ins_pipe( ialu_regL_regL );
 13107 %}
 13109 //FIXME
 13110 instruct tlsLoadP(mRegP dst) %{
 13111   match(Set dst (ThreadLocal));
 13113   ins_cost(0);
 13114   format %{ " get_thread in $dst #@tlsLoadP" %}
 13115   ins_encode %{
 13116     Register dst = $dst$$Register;
 13117 #ifdef OPT_THREAD
 13118     __ move(dst, TREG);
 13119 #else
 13120     __ get_thread(dst);
 13121 #endif
 13122   %}
 13124   ins_pipe( ialu_loadI );
 13125 %}
 13128 instruct checkCastPP( mRegP dst ) %{
 13129   match(Set dst (CheckCastPP dst));
 13131   format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
 13132   ins_encode( /*empty encoding*/ );
 13133   ins_pipe( empty );
 13134 %}
 13136 instruct castPP(mRegP dst)
 13137 %{
 13138   match(Set dst (CastPP dst));
 13140   size(0);
 13141   format %{ "# castPP of $dst" %}
 13142   ins_encode(/* empty encoding */);
 13143   ins_pipe(empty);
 13144 %}
 13146 instruct castII( mRegI dst ) %{
 13147   match(Set dst (CastII dst));
 13148   format %{ "#castII of $dst  empty encoding" %}
 13149   ins_encode( /*empty encoding*/ );
 13150   ins_cost(0);
 13151   ins_pipe( empty );
 13152 %}
 13154 // Return Instruction
 13155 // Remove the return address & jump to it.
 13156 instruct Ret() %{
 13157   match(Return);
 13158   format %{ "RET #@Ret" %}
 13160   ins_encode %{
 13161    __ jr(RA);
 13162    __ delayed()->nop();
 13163   %}
 13165   ins_pipe( pipe_jump );
 13166 %}
 13168 /*
 13169 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
 13170 instruct jumpXtnd(mRegL switch_val) %{
 13171   match(Jump switch_val);
 13173   ins_cost(350);
 13175   format %{  "load   T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
 13176              "jr     T9\n\t"
 13177              "nop" %}
 13178   ins_encode %{
 13179     Register table_base = $constanttablebase;
 13180     int      con_offset = $constantoffset;
 13181     Register switch_reg = $switch_val$$Register;
 13183     if (UseLoongsonISA) {
 13184        if (Assembler::is_simm(con_offset, 8)) {
 13185          __ gsldx(T9, table_base, switch_reg, con_offset);
 13186        } else if (Assembler::is_simm16(con_offset)) {
 13187          __ daddu(T9, table_base, switch_reg);
 13188          __ ld(T9, T9, con_offset);
 13189        } else {
 13190          __ move(T9, con_offset);
 13191          __ daddu(AT, table_base, switch_reg);
 13192          __ gsldx(T9, AT, T9, 0);
 13194     } else {
 13195        if (Assembler::is_simm16(con_offset)) {
 13196          __ daddu(T9, table_base, switch_reg);
 13197          __ ld(T9, T9, con_offset);
 13198        } else {
 13199          __ move(T9, con_offset);
 13200          __ daddu(AT, table_base, switch_reg);
 13201          __ daddu(AT, T9, AT);
 13202          __ ld(T9, AT, 0);
 13206     __ jr(T9);
 13207     __ delayed()->nop();
 13209   %}
 13210   ins_pipe(pipe_jump);
 13211 %}
 13212 */
 13215 // Tail Jump; remove the return address; jump to target.
 13216 // TailCall above leaves the return address around.
 13217 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 13218 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 13219 // "restore" before this instruction (in Epilogue), we need to materialize it
 13220 // in %i0.
 13221 //FIXME
 13222 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
 13223   match( TailJump jump_target ex_oop );
 13224   ins_cost(200);
 13225   format %{ "Jmp     $jump_target  ; ex_oop = $ex_oop #@tailjmpInd" %}
 13226   ins_encode %{
 13227     Register target = $jump_target$$Register;
 13229     // V0, V1 are indicated in:
 13230     //     [stubGenerator_mips.cpp] generate_forward_exception()
 13231     //     [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
 13232     //
 13233     Register oop  = $ex_oop$$Register;
 13234     Register exception_oop = V0;
 13235     Register exception_pc = V1;
 13237     __ move(exception_pc, RA);
 13238     __ move(exception_oop, oop);
 13240     __ jr(target);
 13241     __ delayed()->nop();
 13242   %}
 13243   ins_pipe( pipe_jump );
 13244 %}
 13246 // ============================================================================
 13247 // Procedure Call/Return Instructions
 13248 // Call Java Static Instruction
 13249 // Note: If this code changes, the corresponding ret_addr_offset() and
 13250 //       compute_padding() functions will have to be adjusted.
 13251 instruct CallStaticJavaDirect(method meth) %{
 13252   match(CallStaticJava);
 13253   effect(USE meth);
 13255   ins_cost(300);
 13256   format %{ "CALL,static #@CallStaticJavaDirect " %}
 13257   ins_encode( Java_Static_Call( meth ) );
 13258   ins_pipe( pipe_slow );
 13259   ins_pc_relative(1);
 13260 %}
 13262 // Call Java Dynamic Instruction
 13263 // Note: If this code changes, the corresponding ret_addr_offset() and
 13264 //       compute_padding() functions will have to be adjusted.
 13265 instruct CallDynamicJavaDirect(method meth) %{
 13266   match(CallDynamicJava);
 13267   effect(USE meth);
 13269   ins_cost(300);
 13270   format %{"MOV IC_Klass, #Universe::non_oop_word()\n\t"
 13271            "CallDynamic @ CallDynamicJavaDirect" %}
 13272   ins_encode( Java_Dynamic_Call( meth ) );
 13273   ins_pipe( pipe_slow );
 13274   ins_pc_relative(1);
 13275 %}
 13277 instruct CallLeafNoFPDirect(method meth) %{
 13278   match(CallLeafNoFP);
 13279   effect(USE meth);
 13281   ins_cost(300);
 13282   format %{ "CALL_LEAF_NOFP,runtime " %}
 13283   ins_encode(Java_To_Runtime(meth));
 13284   ins_pipe( pipe_slow );
 13285   ins_pc_relative(1);
 13286   ins_alignment(16);
 13287 %}
 13289 // Prefetch instructions.
 13291 instruct prefetchrNTA( memory mem ) %{
 13292   match(PrefetchRead mem);
 13293   ins_cost(125);
 13295   format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
 13296   ins_encode %{
 13297     int  base = $mem$$base;
 13298     int  index = $mem$$index;
 13299     int  scale = $mem$$scale;
 13300     int  disp = $mem$$disp;
 13302     if( index != 0 ) {
 13303       if (scale == 0) {
 13304         __ daddu(AT, as_Register(base), as_Register(index));
 13305       } else {
 13306         __ dsll(AT, as_Register(index), scale);
 13307         __ daddu(AT, as_Register(base), AT);
 13309     } else {
 13310       __ move(AT, as_Register(base));
 13312     if( Assembler::is_simm16(disp) ) {
 13313       __ daddiu(AT, as_Register(base), disp);
 13314       __ daddiu(AT, AT, disp);
 13315     } else {
 13316       __ move(T9, disp);
 13317       __ daddu(AT, as_Register(base), T9);
 13319     __ pref(0, AT, 0); //hint: 0:load
 13320   %}
 13321   ins_pipe(pipe_slow);
 13322 %}
 13324 instruct prefetchwNTA( memory mem ) %{
 13325   match(PrefetchWrite mem);
 13326   ins_cost(125);
 13327   format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
 13328   ins_encode %{
 13329     int  base = $mem$$base;
 13330     int  index = $mem$$index;
 13331     int  scale = $mem$$scale;
 13332     int  disp = $mem$$disp;
 13334     if( index != 0 ) {
 13335       if (scale == 0) {
 13336         __ daddu(AT, as_Register(base), as_Register(index));
 13337       } else {
 13338         __ dsll(AT, as_Register(index), scale);
 13339         __ daddu(AT, as_Register(base), AT);
 13341     } else {
 13342       __ move(AT, as_Register(base));
 13344     if( Assembler::is_simm16(disp) ) {
 13345       __ daddiu(AT, as_Register(base), disp);
 13346       __ daddiu(AT, AT, disp);
 13347     } else {
 13348       __ move(T9, disp);
 13349       __ daddu(AT, as_Register(base), T9);
 13351      __ pref(1, AT, 0); //hint: 1:store
 13352   %}
 13353   ins_pipe(pipe_slow);
 13354 %}
 13356 // Prefetch instructions for allocation.
 13358 instruct prefetchAllocNTA( memory mem ) %{
 13359   match(PrefetchAllocation mem);
 13360   ins_cost(125);
 13361   format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
 13362   ins_encode %{
 13363     int  base = $mem$$base;
 13364     int  index = $mem$$index;
 13365     int  scale = $mem$$scale;
 13366     int  disp = $mem$$disp;
 13368     Register dst = R0;
 13370     if( index != 0 ) {
 13371       if( Assembler::is_simm16(disp) ) {
 13372         if( UseLoongsonISA ) {
 13373           if (scale == 0) {
 13374             __ gslbx(dst, as_Register(base), as_Register(index), disp);
 13375           } else {
 13376             __ dsll(AT, as_Register(index), scale);
 13377             __ gslbx(dst, as_Register(base), AT, disp);
 13379         } else {
 13380           if (scale == 0) {
 13381             __ addu(AT, as_Register(base), as_Register(index));
 13382           } else {
 13383             __ dsll(AT, as_Register(index), scale);
 13384             __ addu(AT, as_Register(base), AT);
 13386           __ lb(dst, AT, disp);
 13388       } else {
 13389         if (scale == 0) {
 13390           __ addu(AT, as_Register(base), as_Register(index));
 13391         } else {
 13392           __ dsll(AT, as_Register(index), scale);
 13393           __ addu(AT, as_Register(base), AT);
 13395         __ move(T9, disp);
 13396         if( UseLoongsonISA ) {
 13397           __ gslbx(dst, AT, T9, 0);
 13398         } else {
 13399           __ addu(AT, AT, T9);
 13400           __ lb(dst, AT, 0);
 13403     } else {
 13404       if( Assembler::is_simm16(disp) ) {
 13405         __ lb(dst, as_Register(base), disp);
 13406       } else {
 13407         __ move(T9, disp);
 13408         if( UseLoongsonISA ) {
 13409           __ gslbx(dst, as_Register(base), T9, 0);
 13410         } else {
 13411           __ addu(AT, as_Register(base), T9);
 13412           __ lb(dst, AT, 0);
 13416   %}
 13417   ins_pipe(pipe_slow);
 13418 %}
 13421 // Call runtime without safepoint
 13422 instruct CallLeafDirect(method meth) %{
 13423   match(CallLeaf);
 13424   effect(USE meth);
 13426   ins_cost(300);
 13427   format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
 13428   ins_encode(Java_To_Runtime(meth));
 13429   ins_pipe( pipe_slow );
 13430   ins_pc_relative(1);
 13431   ins_alignment(16);
 13432 %}
 13434 // Load Char (16bit unsigned)
 13435 instruct loadUS(mRegI dst, memory mem) %{
 13436   match(Set dst (LoadUS mem));
 13438   ins_cost(125);
 13439   format %{ "loadUS  $dst,$mem @ loadC" %}
 13440   ins_encode(load_C_enc(dst, mem));
 13441   ins_pipe( ialu_loadI );
 13442 %}
 13444 instruct loadUS_convI2L(mRegL dst, memory mem) %{
 13445   match(Set dst (ConvI2L (LoadUS mem)));
 13447   ins_cost(125);
 13448   format %{ "loadUS  $dst,$mem @ loadUS_convI2L" %}
 13449   ins_encode(load_C_enc(dst, mem));
 13450   ins_pipe( ialu_loadI );
 13451 %}
 13453 // Store Char (16bit unsigned)
 13454 instruct storeC(memory mem, mRegI src) %{
 13455   match(Set mem (StoreC mem src));
 13457   ins_cost(125);
 13458   format %{ "storeC  $src, $mem @ storeC" %}
 13459   ins_encode(store_C_reg_enc(mem, src));
 13460   ins_pipe( ialu_loadI );
 13461 %}
 13463 instruct storeC0(memory mem, immI0 zero) %{
 13464   match(Set mem (StoreC mem zero));
 13466   ins_cost(125);
 13467   format %{ "storeC  $zero, $mem @ storeC0" %}
 13468   ins_encode(store_C0_enc(mem));
 13469   ins_pipe( ialu_loadI );
 13470 %}
 13473 instruct loadConF0(regF dst, immF0 zero) %{
 13474   match(Set dst zero);
 13475   ins_cost(100);
 13477   format %{ "mov  $dst, zero @ loadConF0\n"%}
 13478   ins_encode %{
 13479     FloatRegister dst = $dst$$FloatRegister;
 13481     __ mtc1(R0, dst);
 13482   %}
 13483   ins_pipe( fpu_loadF );
 13484 %}
 13487 instruct loadConF(regF dst, immF src) %{
 13488   match(Set dst src);
 13489   ins_cost(125);
 13491   format %{ "lwc1  $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
 13492   ins_encode %{
 13493     int con_offset = $constantoffset($src);
 13495     if (Assembler::is_simm16(con_offset)) {
 13496       __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
 13497     } else {
 13498       __ set64(AT, con_offset);
 13499       if (UseLoongsonISA) {
 13500         __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 13501       } else {
 13502         __ daddu(AT, $constanttablebase, AT);
 13503         __ lwc1($dst$$FloatRegister, AT, 0);
 13506   %}
 13507   ins_pipe( fpu_loadF );
 13508 %}
 13511 instruct loadConD0(regD dst, immD0 zero) %{
 13512   match(Set dst zero);
 13513   ins_cost(100);
 13515   format %{ "mov  $dst, zero @ loadConD0"%}
 13516   ins_encode %{
 13517     FloatRegister dst = as_FloatRegister($dst$$reg);
 13519     __ dmtc1(R0, dst);
 13520   %}
 13521   ins_pipe( fpu_loadF );
 13522 %}
 13524 instruct loadConD(regD dst, immD src) %{
 13525   match(Set dst src);
 13526   ins_cost(125);
 13528   format %{ "ldc1  $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
 13529   ins_encode %{
 13530     int con_offset = $constantoffset($src);
 13532     if (Assembler::is_simm16(con_offset)) {
 13533       __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
 13534     } else {
 13535       __ set64(AT, con_offset);
 13536       if (UseLoongsonISA) {
 13537         __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 13538       } else {
 13539         __ daddu(AT, $constanttablebase, AT);
 13540         __ ldc1($dst$$FloatRegister, AT, 0);
 13543   %}
 13544   ins_pipe( fpu_loadF );
 13545 %}
 13547 // Store register Float value (it is faster than store from FPU register)
 13548 instruct storeF_reg( memory mem, regF src) %{
 13549   match(Set mem (StoreF mem src));
 13551   ins_cost(50);
 13552   format %{ "store   $mem, $src\t# store float @ storeF_reg" %}
 13553   ins_encode(store_F_reg_enc(mem, src));
 13554   ins_pipe( fpu_storeF );
 13555 %}
 13557 instruct storeF_imm0( memory mem, immF0 zero) %{
 13558   match(Set mem (StoreF mem zero));
 13560   ins_cost(40);
 13561   format %{ "store   $mem, zero\t# store float @ storeF_imm0" %}
 13562   ins_encode %{
 13563     int      base = $mem$$base;
 13564     int     index = $mem$$index;
 13565     int     scale = $mem$$scale;
 13566     int      disp = $mem$$disp;
 13568     if( index != 0 ) {
 13569       if ( UseLoongsonISA ) {
 13570         if ( Assembler::is_simm(disp, 8) ) {
 13571           if ( scale == 0 ) {
 13572             __ gsswx(R0, as_Register(base), as_Register(index), disp);
 13573           } else {
 13574             __ dsll(T9, as_Register(index), scale);
 13575             __ gsswx(R0, as_Register(base), T9, disp);
 13577         } else if ( Assembler::is_simm16(disp) ) {
 13578           if ( scale == 0 ) {
 13579             __ daddu(AT, as_Register(base), as_Register(index));
 13580           } else {
 13581             __ dsll(T9, as_Register(index), scale);
 13582             __ daddu(AT, as_Register(base), T9);
 13584           __ sw(R0, AT, disp);
 13585         } else {
 13586           if ( scale == 0 ) {
 13587             __ move(T9, disp);
 13588             __ daddu(AT, as_Register(index), T9);
 13589             __ gsswx(R0, as_Register(base), AT, 0);
 13590           } else {
 13591             __ dsll(T9, as_Register(index), scale);
 13592             __ move(AT, disp);
 13593             __ daddu(AT, AT, T9);
 13594             __ gsswx(R0, as_Register(base), AT, 0);
 13597       } else { //not use loongson isa
 13598         if(scale != 0) {
 13599           __ dsll(T9, as_Register(index), scale);
 13600           __ daddu(AT, as_Register(base), T9);
 13601         } else {
 13602           __ daddu(AT, as_Register(base), as_Register(index));
 13604         if( Assembler::is_simm16(disp) ) {
 13605           __ sw(R0, AT, disp);
 13606         } else {
 13607           __ move(T9, disp);
 13608           __ daddu(AT, AT, T9);
 13609           __ sw(R0, AT, 0);
 13612     } else { //index is 0
 13613       if ( UseLoongsonISA ) {
 13614         if ( Assembler::is_simm16(disp) ) {
 13615           __ sw(R0, as_Register(base), disp);
 13616         } else {
 13617           __ move(T9, disp);
 13618           __ gsswx(R0, as_Register(base), T9, 0);
 13620       } else {
 13621         if( Assembler::is_simm16(disp) ) {
 13622           __ sw(R0, as_Register(base), disp);
 13623         } else {
 13624           __ move(T9, disp);
 13625           __ daddu(AT, as_Register(base), T9);
 13626           __ sw(R0, AT, 0);
 13630   %}
 13631   ins_pipe( ialu_storeI );
 13632 %}
 13634 // Load Double
 13635 instruct loadD(regD dst, memory mem) %{
 13636   match(Set dst (LoadD mem));
 13638   ins_cost(150);
 13639   format %{ "loadD   $dst, $mem #@loadD" %}
 13640   ins_encode(load_D_enc(dst, mem));
 13641   ins_pipe( ialu_loadI );
 13642 %}
 13644 // Load Double - UNaligned
 13645 instruct loadD_unaligned(regD dst, memory mem ) %{
 13646   match(Set dst (LoadD_unaligned mem));
 13647   ins_cost(250);
 13648   // FIXME: Need more effective ldl/ldr
 13649   format %{ "loadD_unaligned   $dst, $mem #@loadD_unaligned" %}
 13650   ins_encode(load_D_enc(dst, mem));
 13651   ins_pipe( ialu_loadI );
 13652 %}
 13654 instruct storeD_reg( memory mem, regD src) %{
 13655   match(Set mem (StoreD mem src));
 13657   ins_cost(50);
 13658   format %{ "store   $mem, $src\t# store float @ storeD_reg" %}
 13659   ins_encode(store_D_reg_enc(mem, src));
 13660   ins_pipe( fpu_storeF );
 13661 %}
 13663 instruct storeD_imm0( memory mem, immD0 zero) %{
 13664   match(Set mem (StoreD mem zero));
 13666   ins_cost(40);
 13667   format %{ "store   $mem, zero\t# store float @ storeD_imm0" %}
 13668   ins_encode %{
 13669     int      base = $mem$$base;
 13670     int     index = $mem$$index;
 13671     int     scale = $mem$$scale;
 13672     int      disp = $mem$$disp;
 13674     __ mtc1(R0, F30);
 13675     __ cvt_d_w(F30, F30);
 13677     if( index != 0 ) {
 13678     if ( UseLoongsonISA ) {
 13679       if ( Assembler::is_simm(disp, 8) ) {
 13680         if (scale == 0) {
 13681           __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
 13682         } else {
 13683           __ dsll(T9, as_Register(index), scale);
 13684           __ gssdxc1(F30, as_Register(base), T9, disp);
 13686       } else if ( Assembler::is_simm16(disp) ) {
 13687         if (scale == 0) {
 13688           __ daddu(AT, as_Register(base), as_Register(index));
 13689           __ sdc1(F30, AT, disp);
 13690         } else {
 13691           __ dsll(T9, as_Register(index), scale);
 13692           __ daddu(AT, as_Register(base), T9);
 13693           __ sdc1(F30, AT, disp);
 13695       } else {
 13696         if (scale == 0) {
 13697           __ move(T9, disp);
 13698           __ daddu(AT, as_Register(index), T9);
 13699           __ gssdxc1(F30, as_Register(base), AT, 0);
 13700         } else {
 13701           __ move(T9, disp);
 13702           __ dsll(AT, as_Register(index), scale);
 13703           __ daddu(AT, AT, T9);
 13704           __ gssdxc1(F30, as_Register(base), AT, 0);
 13707     } else { // not use loongson isa
 13708         if(scale != 0) {
 13709            __ dsll(T9, as_Register(index), scale);
 13710            __ daddu(AT, as_Register(base), T9);
 13711         } else {
 13712            __ daddu(AT, as_Register(base), as_Register(index));
 13714        if( Assembler::is_simm16(disp) ) {
 13715           __ sdc1(F30, AT, disp);
 13716        } else {
 13717           __ move(T9, disp);
 13718           __ daddu(AT, AT, T9);
 13719           __ sdc1(F30, AT, 0);
 13722     } else {// index is 0
 13723     if ( UseLoongsonISA ) {
 13724       if ( Assembler::is_simm16(disp) ) {
 13725         __ sdc1(F30, as_Register(base), disp);
 13726       } else {
 13727         __ move(T9, disp);
 13728         __ gssdxc1(F30, as_Register(base), T9, 0);
 13730     } else {
 13731        if( Assembler::is_simm16(disp) ) {
 13732           __ sdc1(F30, as_Register(base), disp);
 13733        } else {
 13734           __ move(T9, disp);
 13735           __ daddu(AT, as_Register(base), T9);
 13736           __ sdc1(F30, AT, 0);
 13740   %}
 13741   ins_pipe( ialu_storeI );
 13742 %}
 13744 instruct loadSSI(mRegI dst, stackSlotI src)
 13745 %{
 13746   match(Set dst src);
 13748   ins_cost(125);
 13749   format %{ "lw    $dst, $src\t# int stk @ loadSSI" %}
 13750   ins_encode %{
 13751     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
 13752     __ lw($dst$$Register, SP, $src$$disp);
 13753   %}
 13754   ins_pipe(ialu_loadI);
 13755 %}
 13757 instruct storeSSI(stackSlotI dst, mRegI src)
 13758 %{
 13759   match(Set dst src);
 13761   ins_cost(100);
 13762   format %{ "sw    $dst, $src\t# int stk @ storeSSI" %}
 13763   ins_encode %{
 13764     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
 13765     __ sw($src$$Register, SP, $dst$$disp);
 13766   %}
 13767   ins_pipe(ialu_storeI);
 13768 %}
 13770 instruct loadSSL(mRegL dst, stackSlotL src)
 13771 %{
 13772   match(Set dst src);
 13774   ins_cost(125);
 13775   format %{ "ld    $dst, $src\t# long stk @ loadSSL" %}
 13776   ins_encode %{
 13777     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
 13778     __ ld($dst$$Register, SP, $src$$disp);
 13779   %}
 13780   ins_pipe(ialu_loadI);
 13781 %}
 13783 instruct storeSSL(stackSlotL dst, mRegL src)
 13784 %{
 13785   match(Set dst src);
 13787   ins_cost(100);
 13788   format %{ "sd    $dst, $src\t# long stk @ storeSSL" %}
 13789   ins_encode %{
 13790     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
 13791     __ sd($src$$Register, SP, $dst$$disp);
 13792   %}
 13793   ins_pipe(ialu_storeI);
 13794 %}
 13796 instruct loadSSP(mRegP dst, stackSlotP src)
 13797 %{
 13798   match(Set dst src);
 13800   ins_cost(125);
 13801   format %{ "ld    $dst, $src\t# ptr stk @ loadSSP" %}
 13802   ins_encode %{
 13803     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
 13804     __ ld($dst$$Register, SP, $src$$disp);
 13805   %}
 13806   ins_pipe(ialu_loadI);
 13807 %}
 13809 instruct storeSSP(stackSlotP dst, mRegP src)
 13810 %{
 13811   match(Set dst src);
 13813   ins_cost(100);
 13814   format %{ "sd    $dst, $src\t# ptr stk @ storeSSP" %}
 13815   ins_encode %{
 13816     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
 13817     __ sd($src$$Register, SP, $dst$$disp);
 13818   %}
 13819   ins_pipe(ialu_storeI);
 13820 %}
 13822 instruct loadSSF(regF dst, stackSlotF src)
 13823 %{
 13824   match(Set dst src);
 13826   ins_cost(125);
 13827   format %{ "lwc1   $dst, $src\t# float stk @ loadSSF" %}
 13828   ins_encode %{
 13829     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
 13830     __ lwc1($dst$$FloatRegister, SP, $src$$disp);
 13831   %}
 13832   ins_pipe(ialu_loadI);
 13833 %}
 13835 instruct storeSSF(stackSlotF dst, regF src)
 13836 %{
 13837   match(Set dst src);
 13839   ins_cost(100);
 13840   format %{ "swc1    $dst, $src\t# float stk @ storeSSF" %}
 13841   ins_encode %{
 13842     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
 13843     __ swc1($src$$FloatRegister, SP, $dst$$disp);
 13844   %}
 13845   ins_pipe(fpu_storeF);
 13846 %}
 13848 // Use the same format since predicate() can not be used here.
 13849 instruct loadSSD(regD dst, stackSlotD src)
 13850 %{
 13851   match(Set dst src);
 13853   ins_cost(125);
 13854   format %{ "ldc1   $dst, $src\t# double stk @ loadSSD" %}
 13855   ins_encode %{
 13856     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
 13857     __ ldc1($dst$$FloatRegister, SP, $src$$disp);
 13858   %}
 13859   ins_pipe(ialu_loadI);
 13860 %}
 13862 instruct storeSSD(stackSlotD dst, regD src)
 13863 %{
 13864   match(Set dst src);
 13866   ins_cost(100);
 13867   format %{ "sdc1    $dst, $src\t# double stk @ storeSSD" %}
 13868   ins_encode %{
 13869     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
 13870     __ sdc1($src$$FloatRegister, SP, $dst$$disp);
 13871   %}
 13872   ins_pipe(fpu_storeF);
 13873 %}
 13875 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
 13876   match( Set cr (FastLock object box) );
 13877   effect( TEMP tmp, TEMP scr, USE_KILL box );
 13878   ins_cost(300);
 13879   format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
 13880   ins_encode %{
 13881     __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
 13882   %}
 13884   ins_pipe( pipe_slow );
 13885   ins_pc_relative(1);
 13886 %}
 13888 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
 13889   match( Set cr (FastUnlock object box) );
 13890   effect( TEMP tmp, USE_KILL box );
 13891   ins_cost(300);
 13892   format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
 13893   ins_encode %{
 13894     __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
 13895   %}
 13897   ins_pipe( pipe_slow );
 13898   ins_pc_relative(1);
 13899 %}
 13901 // Store CMS card-mark Immediate
 13902 instruct storeImmCM(memory mem, immI8 src) %{
 13903   match(Set mem (StoreCM mem src));
 13905   ins_cost(150);
 13906   format %{ "MOV8   $mem,$src\t! CMS card-mark imm0" %}
 13907 //  opcode(0xC6);
 13908   ins_encode(store_B_immI_enc_sync(mem, src));
 13909   ins_pipe( ialu_storeI );
 13910 %}
 13912 // Die now
 13913 instruct ShouldNotReachHere( )
 13914 %{
 13915   match(Halt);
 13916   ins_cost(300);
 13918   // Use the following format syntax
 13919   format %{ "ILLTRAP   ;#@ShouldNotReachHere" %}
 13920   ins_encode %{
 13921     // Here we should emit illtrap !
 13923     __ stop("in ShoudNotReachHere");
 13925   %}
 13926   ins_pipe( pipe_jump );
 13927 %}
 13929 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
 13930 %{
 13931   predicate(Universe::narrow_oop_shift() == 0);
 13932   match(Set dst mem);
 13934   ins_cost(110);
 13935   format %{ "leaq    $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
 13936   ins_encode %{
 13937     Register  dst  = $dst$$Register;
 13938     Register  base = as_Register($mem$$base);
 13939     int       disp = $mem$$disp;
 13941     __ daddiu(dst, base, disp);
 13942   %}
 13943   ins_pipe( ialu_regI_imm16 );
 13944 %}
 13946 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
 13947 %{
 13948   match(Set dst mem);
 13950   ins_cost(110);
 13951   format %{ "leaq    $dst, $mem\t# @ PosIdxScaleOff8" %}
 13952   ins_encode %{
 13953     Register  dst   = $dst$$Register;
 13954     Register  base  = as_Register($mem$$base);
 13955     Register  index = as_Register($mem$$index);
 13956     int       scale = $mem$$scale;
 13957     int       disp  = $mem$$disp;
 13959     if (scale == 0) {
 13960       __ daddu(AT, base, index);
 13961       __ daddiu(dst, AT, disp);
 13962     } else {
 13963       __ dsll(AT, index, scale);
 13964       __ daddu(AT, base, AT);
 13965       __ daddiu(dst, AT, disp);
 13967  %}
 13969   ins_pipe( ialu_regI_imm16 );
 13970 %}
 13972 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
 13973 %{
 13974   match(Set dst mem);
 13976   ins_cost(110);
 13977   format %{ "leaq    $dst, $mem\t# @ leaPIdxScale" %}
 13978   ins_encode %{
 13979     Register  dst   = $dst$$Register;
 13980     Register  base  = as_Register($mem$$base);
 13981     Register  index = as_Register($mem$$index);
 13982     int       scale = $mem$$scale;
 13984     if (scale == 0) {
 13985        __ daddu(dst, base, index);
 13986     } else {
 13987        __ dsll(AT, index, scale);
 13988        __ daddu(dst, base, AT);
 13990  %}
 13992   ins_pipe( ialu_regI_imm16 );
 13993 %}
 13996 // ============================================================================
 13997 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 13998 // array for an instance of the superklass.  Set a hidden internal cache on a
 13999 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 14000 // NZ for a miss or zero for a hit.  The encoding ALSO sets flags.
 14001 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
 14002   match(Set result (PartialSubtypeCheck sub super));
 14003   effect(KILL tmp);
 14004   ins_cost(1100);  // slightly larger than the next version
 14005   format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
 14007   ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
 14008   ins_pipe( pipe_slow );
 14009 %}
 14012 // Conditional-store of an int value.
 14013 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
 14014 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
 14015   match(Set cr (StoreIConditional mem (Binary oldval newval)));
 14016 //  effect(KILL oldval);
 14017   format %{ "CMPXCHG  $newval, $mem, $oldval \t# @storeIConditional" %}
 14019   ins_encode %{
 14020     Register oldval = $oldval$$Register;
 14021     Register newval = $newval$$Register;
 14022     Address  addr(as_Register($mem$$base), $mem$$disp);
 14023     Label    again, failure;
 14025     int     index = $mem$$index;
 14026     int     scale = $mem$$scale;
 14027     int      disp = $mem$$disp;
 14029     guarantee(Assembler::is_simm16(disp), "");
 14031     if( index != 0 ) {
 14032       __ stop("in storeIConditional: index != 0");
 14033     } else {
 14034       __ bind(again);
 14035       if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
 14036       __ ll(AT, addr);
 14037       __ bne(AT, oldval, failure);
 14038       __ delayed()->addu(AT, R0, R0);
 14040       __ addu(AT, newval, R0);
 14041       __ sc(AT, addr);
 14042       __ beq(AT, R0, again);
 14043       __ delayed()->addiu(AT, R0, 0xFF);
 14044       __ bind(failure);
 14045       __ sync();
 14047 %}
 14049   ins_pipe( long_memory_op );
 14050 %}
 14052 // Conditional-store of a long value.
 14053 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
 14054 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
 14055 %{
 14056   match(Set cr (StoreLConditional mem (Binary oldval newval)));
 14057   effect(KILL oldval);
 14059   format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
 14060   ins_encode%{
 14061     Register oldval = $oldval$$Register;
 14062     Register newval = $newval$$Register;
 14063     Address addr(as_Register($mem$$base), $mem$$disp);
 14065     int     index = $mem$$index;
 14066     int     scale = $mem$$scale;
 14067     int      disp = $mem$$disp;
 14069     guarantee(Assembler::is_simm16(disp), "");
 14071     if( index != 0 ) {
 14072       __ stop("in storeIConditional: index != 0");
 14073     } else {
 14074       __ cmpxchg(newval, addr, oldval);
 14076   %}
 14077   ins_pipe( long_memory_op );
 14078 %}
 14081 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
 14082   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
 14083   effect(KILL oldval);
 14084 //  match(CompareAndSwapI mem_ptr (Binary oldval newval));
 14085   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
 14086             "MOV    $res, 1 @ compareAndSwapI\n\t"
 14087             "BNE    AT, R0 @ compareAndSwapI\n\t"
 14088             "MOV    $res, 0 @ compareAndSwapI\n"
 14089           "L:" %}
 14090   ins_encode %{
 14091     Register newval = $newval$$Register;
 14092     Register oldval = $oldval$$Register;
 14093     Register res    = $res$$Register;
 14094     Address  addr($mem_ptr$$Register, 0);
 14095     Label L;
 14097     __ cmpxchg32(newval, addr, oldval);
 14098     __ move(res, AT);
 14099   %}
 14100   ins_pipe( long_memory_op );
 14101 %}
 14103 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
 14104   predicate(VM_Version::supports_cx8());
 14105   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
 14106   effect(KILL oldval);
 14107   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
 14108             "MOV    $res, 1 @ compareAndSwapI\n\t"
 14109             "BNE    AT, R0 @ compareAndSwapI\n\t"
 14110             "MOV    $res, 0 @ compareAndSwapI\n"
 14111           "L:" %}
 14112   ins_encode %{
 14113     Register newval = $newval$$Register;
 14114     Register oldval = $oldval$$Register;
 14115     Register res    = $res$$Register;
 14116     Address  addr($mem_ptr$$Register, 0);
 14117     Label L;
 14119     __ cmpxchg(newval, addr, oldval);
 14120     __ move(res, AT);
 14121   %}
 14122   ins_pipe( long_memory_op );
 14123 %}
 14125 //FIXME:
 14126 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
 14127   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
 14128   effect(KILL oldval);
 14129   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
 14130             "MOV    $res, AT @ compareAndSwapP\n\t"
 14131           "L:" %}
 14132   ins_encode %{
 14133     Register newval = $newval$$Register;
 14134     Register oldval = $oldval$$Register;
 14135     Register res    = $res$$Register;
 14136     Address  addr($mem_ptr$$Register, 0);
 14137     Label L;
 14139     __ cmpxchg(newval, addr, oldval);
 14140     __ move(res, AT);
 14141   %}
 14142   ins_pipe( long_memory_op );
 14143 %}
 14145 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
 14146   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
 14147   effect(KILL oldval);
 14148   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
 14149             "MOV    $res, AT @ compareAndSwapN\n\t"
 14150           "L:" %}
 14151   ins_encode %{
 14152     Register newval = $newval$$Register;
 14153     Register oldval = $oldval$$Register;
 14154     Register res    = $res$$Register;
 14155     Address  addr($mem_ptr$$Register, 0);
 14156     Label L;
 14158     // cmpxchg32 is implemented with ll/sc, which will do sign extension.
 14159     //      Thus, we should extend oldval's sign for correct comparision.
 14160     //
 14161     __ sll(oldval, oldval, 0);
 14163     __ cmpxchg32(newval, addr, oldval);
 14164     __ move(res, AT);
 14165   %}
 14166   ins_pipe( long_memory_op );
 14167 %}
 14169 //----------Max and Min--------------------------------------------------------
 14170 // Min Instructions
 14171 ////
 14172 //   *** Min and Max using the conditional move are slower than the
 14173 //   *** branch version on a Pentium III.
 14174 // // Conditional move for min
 14175 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 14176 //  effect( USE_DEF op2, USE op1, USE cr );
 14177 //  format %{ "CMOVlt $op2,$op1\t! min" %}
 14178 //  opcode(0x4C,0x0F);
 14179 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 14180 //  ins_pipe( pipe_cmov_reg );
 14181 //%}
 14182 //
 14183 //// Min Register with Register (P6 version)
 14184 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
 14185 //  predicate(VM_Version::supports_cmov() );
 14186 //  match(Set op2 (MinI op1 op2));
 14187 //  ins_cost(200);
 14188 //  expand %{
 14189 //    eFlagsReg cr;
 14190 //    compI_eReg(cr,op1,op2);
 14191 //    cmovI_reg_lt(op2,op1,cr);
 14192 //  %}
 14193 //%}
 14195 // Min Register with Register (generic version)
 14196 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
 14197   match(Set dst (MinI dst src));
 14198   //effect(KILL flags);
 14199   ins_cost(80);
 14201   format %{ "MIN    $dst, $src @minI_Reg_Reg" %}
 14202   ins_encode %{
 14203     Register dst   = $dst$$Register;
 14204     Register src   = $src$$Register;
 14206     __ slt(AT, src, dst);
 14207     __ movn(dst, src, AT);
 14209   %}
 14211   ins_pipe( pipe_slow );
 14212 %}
 14214 // Max Register with Register
 14215 //   *** Min and Max using the conditional move are slower than the
 14216 //   *** branch version on a Pentium III.
 14217 // // Conditional move for max
 14218 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 14219 //  effect( USE_DEF op2, USE op1, USE cr );
 14220 //  format %{ "CMOVgt $op2,$op1\t! max" %}
 14221 //  opcode(0x4F,0x0F);
 14222 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 14223 //  ins_pipe( pipe_cmov_reg );
 14224 //%}
 14225 //
 14226 // // Max Register with Register (P6 version)
 14227 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
 14228 //  predicate(VM_Version::supports_cmov() );
 14229 //  match(Set op2 (MaxI op1 op2));
 14230 //  ins_cost(200);
 14231 //  expand %{
 14232 //    eFlagsReg cr;
 14233 //    compI_eReg(cr,op1,op2);
 14234 //    cmovI_reg_gt(op2,op1,cr);
 14235 //  %}
 14236 //%}
 14238 // Max Register with Register (generic version)
 14239 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
 14240   match(Set dst (MaxI dst src));
 14241   ins_cost(80);
 14243   format %{ "MAX    $dst, $src @maxI_Reg_Reg" %}
 14245   ins_encode %{
 14246     Register dst   = $dst$$Register;
 14247     Register src   = $src$$Register;
 14249     __ slt(AT, dst, src);
 14250     __ movn(dst, src, AT);
 14252   %}
 14254   ins_pipe( pipe_slow );
 14255 %}
 14257 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
 14258   match(Set dst (MaxI dst zero));
 14259   ins_cost(50);
 14261   format %{ "MAX    $dst, 0 @maxI_Reg_zero" %}
 14263   ins_encode %{
 14264     Register dst   = $dst$$Register;
 14266     __ slt(AT, dst, R0);
 14267     __ movn(dst, R0, AT);
 14269   %}
 14271   ins_pipe( pipe_slow );
 14272 %}
 14274 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
 14275 %{
 14276   match(Set dst (AndL src mask));
 14278   format %{ "movl    $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
 14279   ins_encode %{
 14280     Register dst = $dst$$Register;
 14281     Register src = $src$$Register;
 14283     __ dext(dst, src, 0, 32);
 14284   %}
 14285   ins_pipe(ialu_regI_regI);
 14286 %}
 14288 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
 14289 %{
 14290   match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
 14292   format %{ "combine_i2l    $dst, $src2(H), $src1(L) @ combine_i2l" %}
 14293   ins_encode %{
 14294     Register dst  = $dst$$Register;
 14295     Register src1 = $src1$$Register;
 14296     Register src2 = $src2$$Register;
 14298     if (src1 == dst) {
 14299        __ dinsu(dst, src2, 32, 32);
 14300     } else if (src2 == dst) {
 14301        __ dsll32(dst, dst, 0);
 14302        __ dins(dst, src1, 0, 32);
 14303     } else {
 14304        __ dext(dst, src1, 0, 32);
 14305        __ dinsu(dst, src2, 32, 32);
 14307   %}
 14308   ins_pipe(ialu_regI_regI);
 14309 %}
 14311 // Zero-extend convert int to long
 14312 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
 14313 %{
 14314   match(Set dst (AndL (ConvI2L src) mask));
 14316   format %{ "movl    $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
 14317   ins_encode %{
 14318     Register dst = $dst$$Register;
 14319     Register src = $src$$Register;
 14321     __ dext(dst, src, 0, 32);
 14322   %}
 14323   ins_pipe(ialu_regI_regI);
 14324 %}
 14326 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
 14327 %{
 14328   match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
 14330   format %{ "movl    $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
 14331   ins_encode %{
 14332     Register dst = $dst$$Register;
 14333     Register src = $src$$Register;
 14335     __ dext(dst, src, 0, 32);
 14336   %}
 14337   ins_pipe(ialu_regI_regI);
 14338 %}
 14340 // Match loading integer and casting it to unsigned int in long register.
 14341 // LoadI + ConvI2L + AndL 0xffffffff.
 14342 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
 14343   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 14345   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
 14346   ins_encode (load_N_enc(dst, mem));
 14347   ins_pipe(ialu_loadI);
 14348 %}
 14350 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
 14351   match(Set dst (AndL mask (ConvI2L (LoadI mem))));
 14353   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
 14354   ins_encode (load_N_enc(dst, mem));
 14355   ins_pipe(ialu_loadI);
 14356 %}
 14359 // ============================================================================
 14360 // Safepoint Instruction
 14361 instruct safePoint_poll_reg(mRegP poll) %{
 14362   match(SafePoint poll);
 14363   predicate(false);
 14364   effect(USE poll);
 14366   ins_cost(125);
 14367   format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
 14369   ins_encode %{
 14370     Register poll_reg = $poll$$Register;
 14372     __ block_comment("Safepoint:");
 14373     __ relocate(relocInfo::poll_type);
 14374     __ lw(AT, poll_reg, 0);
 14375   %}
 14377   ins_pipe( ialu_storeI );
 14378 %}
 14380 instruct safePoint_poll() %{
 14381   match(SafePoint);
 14383   ins_cost(105);
 14384   format %{ "poll for GC @ safePoint_poll" %}
 14386   ins_encode %{
 14387     __ block_comment("Safepoint:");
 14388     __ set64(T9, (long)os::get_polling_page());
 14389     __ relocate(relocInfo::poll_type);
 14390     __ lw(AT, T9, 0);
 14391   %}
 14393   ins_pipe( ialu_storeI );
 14394 %}
 14396 //----------Arithmetic Conversion Instructions---------------------------------
 14398 instruct roundFloat_nop(regF dst)
 14399 %{
 14400   match(Set dst (RoundFloat dst));
 14402   ins_cost(0);
 14403   ins_encode();
 14404   ins_pipe(empty);
 14405 %}
 14407 instruct roundDouble_nop(regD dst)
 14408 %{
 14409   match(Set dst (RoundDouble dst));
 14411   ins_cost(0);
 14412   ins_encode();
 14413   ins_pipe(empty);
 14414 %}
 14416 //---------- Zeros Count Instructions ------------------------------------------
 14417 // CountLeadingZerosINode CountTrailingZerosINode
 14418 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
 14419   predicate(UseCountLeadingZerosInstructionMIPS64);
 14420   match(Set dst (CountLeadingZerosI src));
 14422   format %{ "clz  $dst, $src\t# count leading zeros (int)" %}
 14423   ins_encode %{
 14424     __ clz($dst$$Register, $src$$Register);
 14425   %}
 14426   ins_pipe( ialu_regL_regL );
 14427 %}
 14429 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
 14430   predicate(UseCountLeadingZerosInstructionMIPS64);
 14431   match(Set dst (CountLeadingZerosL src));
 14433   format %{ "dclz  $dst, $src\t# count leading zeros (long)" %}
 14434   ins_encode %{
 14435     __ dclz($dst$$Register, $src$$Register);
 14436   %}
 14437   ins_pipe( ialu_regL_regL );
 14438 %}
 14440 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
 14441   predicate(UseCountTrailingZerosInstructionMIPS64);
 14442   match(Set dst (CountTrailingZerosI src));
 14444   format %{ "ctz    $dst, $src\t# count trailing zeros (int)" %}
 14445   ins_encode %{
 14446     // ctz and dctz is gs instructions.
 14447     __ ctz($dst$$Register, $src$$Register);
 14448   %}
 14449   ins_pipe( ialu_regL_regL );
 14450 %}
 14452 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
 14453   predicate(UseCountTrailingZerosInstructionMIPS64);
 14454   match(Set dst (CountTrailingZerosL src));
 14456   format %{ "dcto    $dst, $src\t# count trailing zeros (long)" %}
 14457   ins_encode %{
 14458     __ dctz($dst$$Register, $src$$Register);
 14459   %}
 14460   ins_pipe( ialu_regL_regL );
 14461 %}
 14463 // ====================VECTOR INSTRUCTIONS=====================================
 14465 // Load vectors (8 bytes long)
 14466 instruct loadV8(vecD dst, memory mem) %{
 14467   predicate(n->as_LoadVector()->memory_size() == 8);
 14468   match(Set dst (LoadVector mem));
 14469   ins_cost(125);
 14470   format %{ "load    $dst, $mem\t! load vector (8 bytes)" %}
 14471   ins_encode(load_D_enc(dst, mem));
 14472   ins_pipe( fpu_loadF );
 14473 %}
 14475 // Store vectors (8 bytes long)
 14476 instruct storeV8(memory mem, vecD src) %{
 14477   predicate(n->as_StoreVector()->memory_size() == 8);
 14478   match(Set mem (StoreVector mem src));
 14479   ins_cost(145);
 14480   format %{ "store    $mem, $src\t! store vector (8 bytes)" %}
 14481   ins_encode(store_D_reg_enc(mem, src));
 14482   ins_pipe( fpu_storeF );
 14483 %}
 14485 instruct Repl8B_DSP(vecD dst, mRegI src) %{
 14486   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 14487   match(Set dst (ReplicateB src));
 14488   ins_cost(100);
 14489   format %{ "replv_ob    AT, $src\n\t"
 14490             "dmtc1 AT, $dst\t! replicate8B" %}
 14491   ins_encode %{
 14492     __ replv_ob(AT, $src$$Register);
 14493     __ dmtc1(AT, $dst$$FloatRegister);
 14494   %}
 14495   ins_pipe( pipe_mtc1 );
 14496 %}
 14498 instruct Repl8B(vecD dst, mRegI src) %{
 14499   predicate(n->as_Vector()->length() == 8);
 14500   match(Set dst (ReplicateB src));
 14501   ins_cost(140);
 14502   format %{ "move       AT,  $src\n\t"
 14503             "dins  AT, AT,  8,  8\n\t"
 14504             "dins  AT, AT, 16, 16\n\t"
 14505             "dinsu AT, AT, 32, 32\n\t"
 14506             "dmtc1 AT, $dst\t! replicate8B" %}
 14507   ins_encode %{
 14508     __ move(AT, $src$$Register);
 14509     __ dins(AT, AT, 8, 8);
 14510     __ dins(AT, AT, 16, 16);
 14511     __ dinsu(AT, AT, 32, 32);
 14512     __ dmtc1(AT, $dst$$FloatRegister);
 14513   %}
 14514   ins_pipe( pipe_mtc1 );
 14515 %}
 14517 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
 14518   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 14519   match(Set dst (ReplicateB con));
 14520   ins_cost(110);
 14521   format %{ "repl_ob    AT, [$con]\n\t"
 14522             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 14523   ins_encode %{
 14524     int      val = $con$$constant;
 14525     __ repl_ob(AT, val);
 14526     __ dmtc1(AT, $dst$$FloatRegister);
 14527   %}
 14528   ins_pipe( pipe_mtc1 );
 14529 %}
 14531 instruct Repl8B_imm(vecD dst, immI con) %{
 14532   predicate(n->as_Vector()->length() == 8);
 14533   match(Set dst (ReplicateB con));
 14534   ins_cost(150);
 14535   format %{ "move      AT, [$con]\n\t"
 14536             "dins  AT, AT,  8,  8\n\t"
 14537             "dins  AT, AT, 16, 16\n\t"
 14538             "dinsu AT, AT, 32, 32\n\t"
 14539             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 14540   ins_encode %{
 14541     __ move(AT, $con$$constant);
 14542     __ dins(AT, AT, 8, 8);
 14543     __ dins(AT, AT, 16, 16);
 14544     __ dinsu(AT, AT, 32, 32);
 14545     __ dmtc1(AT, $dst$$FloatRegister);
 14546   %}
 14547   ins_pipe( pipe_mtc1 );
 14548 %}
 14550 instruct Repl8B_zero(vecD dst, immI0 zero) %{
 14551   predicate(n->as_Vector()->length() == 8);
 14552   match(Set dst (ReplicateB zero));
 14553   ins_cost(90);
 14554   format %{ "dmtc1    R0, $dst\t! replicate8B zero" %}
 14555   ins_encode %{
 14556     __ dmtc1(R0, $dst$$FloatRegister);
 14557   %}
 14558   ins_pipe( pipe_mtc1 );
 14559 %}
 14561 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
 14562   predicate(n->as_Vector()->length() == 8);
 14563   match(Set dst (ReplicateB M1));
 14564   ins_cost(80);
 14565   format %{ "dmtc1    -1, $dst\t! replicate8B -1" %}
 14566   ins_encode %{
 14567     __ nor(AT, R0, R0);
 14568     __ dmtc1(AT, $dst$$FloatRegister);
 14569   %}
 14570   ins_pipe( pipe_mtc1 );
 14571 %}
 14573 instruct Repl4S_DSP(vecD dst, mRegI src) %{
 14574   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 14575   match(Set dst (ReplicateS src));
 14576   ins_cost(100);
 14577   format %{ "replv_qh    AT, $src\n\t"
 14578             "dmtc1 AT, $dst\t! replicate4S" %}
 14579   ins_encode %{
 14580     __ replv_qh(AT, $src$$Register);
 14581     __ dmtc1(AT, $dst$$FloatRegister);
 14582   %}
 14583   ins_pipe( pipe_mtc1 );
 14584 %}
 14586 instruct Repl4S(vecD dst, mRegI src) %{
 14587   predicate(n->as_Vector()->length() == 4);
 14588   match(Set dst (ReplicateS src));
 14589   ins_cost(120);
 14590   format %{ "move    AT,     $src  \n\t"
 14591             "dins    AT, AT, 16, 16\n\t"
 14592             "dinsu   AT, AT, 32, 32\n\t"
 14593             "dmtc1 AT, $dst\t! replicate4S" %}
 14594   ins_encode %{
 14595     __ move(AT, $src$$Register);
 14596     __ dins(AT, AT, 16, 16);
 14597     __ dinsu(AT, AT, 32, 32);
 14598     __ dmtc1(AT, $dst$$FloatRegister);
 14599   %}
 14600   ins_pipe( pipe_mtc1 );
 14601 %}
 14603 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
 14604   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 14605   match(Set dst (ReplicateS con));
 14606   ins_cost(100);
 14607   format %{ "repl_qh    AT, [$con]\n\t"
 14608             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 14609   ins_encode %{
 14610     int      val = $con$$constant;
 14611     if ( Assembler::is_simm(val, 10)) {
 14612       //repl_qh supports 10 bits immediate
 14613       __ repl_qh(AT, val);
 14614     } else {
 14615       __ li32(AT, val);
 14616       __ replv_qh(AT, AT);
 14618     __ dmtc1(AT, $dst$$FloatRegister);
 14619   %}
 14620   ins_pipe( pipe_mtc1 );
 14621 %}
 14623 instruct Repl4S_imm(vecD dst, immI con) %{
 14624   predicate(n->as_Vector()->length() == 4);
 14625   match(Set dst (ReplicateS con));
 14626   ins_cost(110);
 14627   format %{ "move    AT,   [$con]\n\t"
 14628             "dins  AT, AT, 16, 16\n\t"
 14629             "dinsu AT, AT, 32, 32\n\t"
 14630             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 14631   ins_encode %{
 14632     __ move(AT, $con$$constant);
 14633     __ dins(AT, AT, 16, 16);
 14634     __ dinsu(AT, AT, 32, 32);
 14635     __ dmtc1(AT, $dst$$FloatRegister);
 14636   %}
 14637   ins_pipe( pipe_mtc1 );
 14638 %}
 14640 instruct Repl4S_zero(vecD dst, immI0 zero) %{
 14641   predicate(n->as_Vector()->length() == 4);
 14642   match(Set dst (ReplicateS zero));
 14643   format %{ "dmtc1    R0, $dst\t! replicate4S zero" %}
 14644   ins_encode %{
 14645     __ dmtc1(R0, $dst$$FloatRegister);
 14646   %}
 14647   ins_pipe( pipe_mtc1 );
 14648 %}
 14650 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
 14651   predicate(n->as_Vector()->length() == 4);
 14652   match(Set dst (ReplicateS M1));
 14653   format %{ "dmtc1    -1, $dst\t! replicate4S -1" %}
 14654   ins_encode %{
 14655     __ nor(AT, R0, R0);
 14656     __ dmtc1(AT, $dst$$FloatRegister);
 14657   %}
 14658   ins_pipe( pipe_mtc1 );
 14659 %}
 14661 // Replicate integer (4 byte) scalar to be vector
 14662 instruct Repl2I(vecD dst, mRegI src) %{
 14663   predicate(n->as_Vector()->length() == 2);
 14664   match(Set dst (ReplicateI src));
 14665   format %{ "dins    AT, $src, 0, 32\n\t"
 14666             "dinsu   AT, $src, 32, 32\n\t"
 14667             "dmtc1   AT, $dst\t! replicate2I" %}
 14668   ins_encode %{
 14669     __ dins(AT, $src$$Register, 0, 32);
 14670     __ dinsu(AT, $src$$Register, 32, 32);
 14671     __ dmtc1(AT, $dst$$FloatRegister);
 14672   %}
 14673   ins_pipe( pipe_mtc1 );
 14674 %}
 14676 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
 14677 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
 14678   predicate(n->as_Vector()->length() == 2);
 14679   match(Set dst (ReplicateI con));
 14680   effect(KILL tmp);
 14681   format %{ "li32    AT, [$con], 32\n\t"
 14682             "dinsu   AT,         AT\n\t"
 14683             "dmtc1   AT, $dst\t! replicate2I($con)" %}
 14684   ins_encode %{
 14685     int      val = $con$$constant;
 14686     __ li32(AT, val);
 14687     __ dinsu(AT, AT, 32, 32);
 14688     __ dmtc1(AT, $dst$$FloatRegister);
 14689   %}
 14690   ins_pipe( pipe_mtc1 );
 14691 %}
 14693 // Replicate integer (4 byte) scalar zero to be vector
 14694 instruct Repl2I_zero(vecD dst, immI0 zero) %{
 14695   predicate(n->as_Vector()->length() == 2);
 14696   match(Set dst (ReplicateI zero));
 14697   format %{ "dmtc1    R0, $dst\t! replicate2I zero" %}
 14698   ins_encode %{
 14699     __ dmtc1(R0, $dst$$FloatRegister);
 14700   %}
 14701   ins_pipe( pipe_mtc1 );
 14702 %}
 14704 // Replicate integer (4 byte) scalar -1 to be vector
 14705 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
 14706   predicate(n->as_Vector()->length() == 2);
 14707   match(Set dst (ReplicateI M1));
 14708   format %{ "dmtc1    -1, $dst\t! replicate2I -1, use AT" %}
 14709   ins_encode %{
 14710     __ nor(AT, R0, R0);
 14711     __ dmtc1(AT, $dst$$FloatRegister);
 14712   %}
 14713   ins_pipe( pipe_mtc1 );
 14714 %}
 14716 // Replicate float (4 byte) scalar to be vector
 14717 instruct Repl2F(vecD dst, regF src) %{
 14718   predicate(n->as_Vector()->length() == 2);
 14719   match(Set dst (ReplicateF src));
 14720   format %{ "cvt.ps  $dst, $src, $src\t! replicate2F" %}
 14721   ins_encode %{
 14722     __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
 14723   %}
 14724   ins_pipe( pipe_slow );
 14725 %}
 14727 // Replicate float (4 byte) scalar zero to be vector
 14728 instruct Repl2F_zero(vecD dst, immF0 zero) %{
 14729   predicate(n->as_Vector()->length() == 2);
 14730   match(Set dst (ReplicateF zero));
 14731   format %{ "dmtc1   R0, $dst\t! replicate2F zero" %}
 14732   ins_encode %{
 14733     __ dmtc1(R0, $dst$$FloatRegister);
 14734   %}
 14735   ins_pipe( pipe_mtc1 );
 14736 %}
 14739 // ====================VECTOR ARITHMETIC=======================================
 14741 // --------------------------------- ADD --------------------------------------
 14743 // Floats vector add
 14744 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
 14745 instruct vadd2F(vecD dst, vecD src) %{
 14746   predicate(n->as_Vector()->length() == 2);
 14747   match(Set dst (AddVF dst src));
 14748   format %{ "add.ps   $dst,$src\t! add packed2F" %}
 14749   ins_encode %{
 14750     __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14751   %}
 14752   ins_pipe( pipe_slow );
 14753 %}
 14755 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
 14756   predicate(n->as_Vector()->length() == 2);
 14757   match(Set dst (AddVF src1 src2));
 14758   format %{ "add.ps   $dst,$src1,$src2\t! add packed2F" %}
 14759   ins_encode %{
 14760     __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14761   %}
 14762   ins_pipe( fpu_regF_regF );
 14763 %}
 14765 // --------------------------------- SUB --------------------------------------
 14767 // Floats vector sub
 14768 instruct vsub2F(vecD dst, vecD src) %{
 14769   predicate(n->as_Vector()->length() == 2);
 14770   match(Set dst (SubVF dst src));
 14771   format %{ "sub.ps   $dst,$src\t! sub packed2F" %}
 14772   ins_encode %{
 14773     __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14774   %}
 14775   ins_pipe( fpu_regF_regF );
 14776 %}
 14778 // --------------------------------- MUL --------------------------------------
 14780 // Floats vector mul
 14781 instruct vmul2F(vecD dst, vecD src) %{
 14782   predicate(n->as_Vector()->length() == 2);
 14783   match(Set dst (MulVF dst src));
 14784   format %{ "mul.ps   $dst, $src\t! mul packed2F" %}
 14785   ins_encode %{
 14786     __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14787   %}
 14788   ins_pipe( fpu_regF_regF );
 14789 %}
 14791 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
 14792   predicate(n->as_Vector()->length() == 2);
 14793   match(Set dst (MulVF src1 src2));
 14794   format %{ "mul.ps   $dst, $src1, $src2\t! mul packed2F" %}
 14795   ins_encode %{
 14796     __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14797   %}
 14798   ins_pipe( fpu_regF_regF );
 14799 %}
 14801 // --------------------------------- DIV --------------------------------------
 14802 // MIPS do not have div.ps
 14804 // --------------------------------- MADD --------------------------------------
 14805 // Floats vector madd
 14806 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
 14807 //  predicate(n->as_Vector()->length() == 2);
 14808 //  match(Set dst (AddVF (MulVF src1 src2) src3));
 14809 //  ins_cost(50);
 14810 //  format %{ "madd.ps   $dst, $src3, $src1, $src2\t! madd packed2F" %}
 14811 //  ins_encode %{
 14812 //    __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14813 //  %}
 14814 //  ins_pipe( fpu_regF_regF );
 14815 //%}
 14818 //----------PEEPHOLE RULES-----------------------------------------------------
 14819 // These must follow all instruction definitions as they use the names
 14820 // defined in the instructions definitions.
 14821 //
 14822 // peepmatch ( root_instr_name [preceeding_instruction]* );
 14823 //
 14824 // peepconstraint %{
 14825 // (instruction_number.operand_name relational_op instruction_number.operand_name
 14826 //  [, ...] );
 14827 // // instruction numbers are zero-based using left to right order in peepmatch
 14828 //
 14829 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
 14830 // // provide an instruction_number.operand_name for each operand that appears
 14831 // // in the replacement instruction's match rule
 14832 //
 14833 // ---------VM FLAGS---------------------------------------------------------
 14834 //
 14835 // All peephole optimizations can be turned off using -XX:-OptoPeephole
 14836 //
 14837 // Each peephole rule is given an identifying number starting with zero and
 14838 // increasing by one in the order seen by the parser.  An individual peephole
 14839 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
 14840 // on the command-line.
 14841 //
 14842 // ---------CURRENT LIMITATIONS----------------------------------------------
 14843 //
 14844 // Only match adjacent instructions in same basic block
 14845 // Only equality constraints
 14846 // Only constraints between operands, not (0.dest_reg == EAX_enc)
 14847 // Only one replacement instruction
 14848 //
 14849 // ---------EXAMPLE----------------------------------------------------------
 14850 //
 14851 // // pertinent parts of existing instructions in architecture description
 14852 // instruct movI(eRegI dst, eRegI src) %{
 14853 //   match(Set dst (CopyI src));
 14854 // %}
 14855 //
 14856 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
 14857 //   match(Set dst (AddI dst src));
 14858 //   effect(KILL cr);
 14859 // %}
 14860 //
 14861 // // Change (inc mov) to lea
 14862 // peephole %{
 14863 //   // increment preceeded by register-register move
 14864 //   peepmatch ( incI_eReg movI );
 14865 //   // require that the destination register of the increment
 14866 //   // match the destination register of the move
 14867 //   peepconstraint ( 0.dst == 1.dst );
 14868 //   // construct a replacement instruction that sets
 14869 //   // the destination to ( move's source register + one )
 14870 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14871 // %}
 14872 //
 14873 // Implementation no longer uses movX instructions since
 14874 // machine-independent system no longer uses CopyX nodes.
 14875 //
 14876 // peephole %{
 14877 //   peepmatch ( incI_eReg movI );
 14878 //   peepconstraint ( 0.dst == 1.dst );
 14879 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14880 // %}
 14881 //
 14882 // peephole %{
 14883 //   peepmatch ( decI_eReg movI );
 14884 //   peepconstraint ( 0.dst == 1.dst );
 14885 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14886 // %}
 14887 //
 14888 // peephole %{
 14889 //   peepmatch ( addI_eReg_imm movI );
 14890 //   peepconstraint ( 0.dst == 1.dst );
 14891 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14892 // %}
 14893 //
 14894 // peephole %{
 14895 //   peepmatch ( addP_eReg_imm movP );
 14896 //   peepconstraint ( 0.dst == 1.dst );
 14897 //   peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
 14898 // %}
 14900 // // Change load of spilled value to only a spill
 14901 // instruct storeI(memory mem, eRegI src) %{
 14902 //   match(Set mem (StoreI mem src));
 14903 // %}
 14904 //
 14905 // instruct loadI(eRegI dst, memory mem) %{
 14906 //   match(Set dst (LoadI mem));
 14907 // %}
 14908 //
 14909 //peephole %{
 14910 //  peepmatch ( loadI storeI );
 14911 //  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
 14912 //  peepreplace ( storeI( 1.mem 1.mem 1.src ) );
 14913 //%}
 14915 //----------SMARTSPILL RULES---------------------------------------------------
 14916 // These must follow all instruction definitions as they use the names
 14917 // defined in the instructions definitions.

mercurial