src/cpu/mips/vm/mips_64.ad

Tue, 22 May 2018 20:04:19 +0800

author
fujie
date
Tue, 22 May 2018 20:04:19 +0800
changeset 8866
67d25ceaf28b
parent 8865
ffcdff41a92f
child 9136
7ed87d5663da
permissions
-rw-r--r--

Follows 23334f570d7f, fix a typo.

     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 // 2012/8/23 Fu: F30/F31 are used as temporary registers in D2I
   384 // 2016/12/1 aoqi: F31 are not used as temporary registers in D2I
   385 reg_class flt_reg( F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17 F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F31);
   386 reg_class dbl_reg( F0, F0_H,
   387                    F1, F1_H,
   388                    F2, F2_H,
   389                    F3, F3_H,
   390                    F4, F4_H,
   391                    F5, F5_H,
   392                    F6, F6_H,
   393                    F7, F7_H,
   394                    F8, F8_H,
   395                    F9, F9_H,
   396                    F10, F10_H,
   397                    F11, F11_H,
   398                    F12, F12_H,
   399                    F13, F13_H,
   400                    F14, F14_H,
   401                    F15, F15_H,
   402                    F16, F16_H,
   403                    F17, F17_H,
   404                    F18, F18_H,
   405                    F19, F19_H,
   406                    F20, F20_H,
   407                    F21, F21_H,
   408                    F22, F22_H,
   409                    F23, F23_H,
   410                    F24, F24_H,
   411                    F25, F25_H,
   412                    F26, F26_H,
   413                    F27, F27_H,
   414                    F28, F28_H,
   415                    F29, F29_H,
   416                    F31, F31_H);
   418 reg_class flt_arg0( F12 );
   419 reg_class dbl_arg0( F12, F12_H );
   420 reg_class dbl_arg1( F14, F14_H );
   422 %}
   424 //----------DEFINITION BLOCK---------------------------------------------------
   425 // Define name --> value mappings to inform the ADLC of an integer valued name
   426 // Current support includes integer values in the range [0, 0x7FFFFFFF]
   427 // Format:
   428 //        int_def  <name>         ( <int_value>, <expression>);
   429 // Generated Code in ad_<arch>.hpp
   430 //        #define  <name>   (<expression>)
   431 //        // value == <int_value>
   432 // Generated code in ad_<arch>.cpp adlc_verification()
   433 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
   434 //
   435 definitions %{
   436   int_def DEFAULT_COST      (    100,     100);
   437   int_def HUGE_COST         (1000000, 1000000);
   439   // Memory refs are twice as expensive as run-of-the-mill.
   440   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
   442   // Branches are even more expensive.
   443   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
   444   // we use jr instruction to construct call, so more expensive
   445   // by yjl 2/28/2006
   446   int_def CALL_COST         (    500, DEFAULT_COST * 5);
   447 /*
   448         int_def EQUAL             (   1, 1  );
   449         int_def NOT_EQUAL         (   2, 2  );
   450         int_def GREATER           (   3, 3  );
   451         int_def GREATER_EQUAL     (   4, 4  );
   452         int_def LESS              (   5, 5  );
   453         int_def LESS_EQUAL        (   6, 6  );
   454 */
   455 %}
   459 //----------SOURCE BLOCK-------------------------------------------------------
   460 // This is a block of C++ code which provides values, functions, and
   461 // definitions necessary in the rest of the architecture description
   463 source_hpp %{
   464 // Header information of the source block.
   465 // Method declarations/definitions which are used outside
   466 // the ad-scope can conveniently be defined here.
   467 //
   468 // To keep related declarations/definitions/uses close together,
   469 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
   471 class CallStubImpl {
   473   //--------------------------------------------------------------
   474   //---<  Used for optimization in Compile::shorten_branches  >---
   475   //--------------------------------------------------------------
   477  public:
   478   // Size of call trampoline stub.
   479   static uint size_call_trampoline() {
   480     return 0; // no call trampolines on this platform
   481   }
   483   // number of relocations needed by a call trampoline stub
   484   static uint reloc_call_trampoline() {
   485     return 0; // no call trampolines on this platform
   486   }
   487 };
   489 class HandlerImpl {
   491  public:
   493   static int emit_exception_handler(CodeBuffer &cbuf);
   494   static int emit_deopt_handler(CodeBuffer& cbuf);
   496   static uint size_exception_handler() {
   497     // NativeCall instruction size is the same as NativeJump.
   498     // exception handler starts out as jump and can be patched to
   499     // a call be deoptimization.  (4932387)
   500     // Note that this value is also credited (in output.cpp) to
   501     // the size of the code section.
   502     int size = NativeCall::instruction_size;
   503     return round_to(size, 16);
   504   }
   506 #ifdef _LP64
   507   static uint size_deopt_handler() {
   508     int size = NativeCall::instruction_size;
   509     return round_to(size, 16);
   510   }
   511 #else
   512   static uint size_deopt_handler() {
   513     // NativeCall instruction size is the same as NativeJump.
   514     // exception handler starts out as jump and can be patched to
   515     // a call be deoptimization.  (4932387)
   516     // Note that this value is also credited (in output.cpp) to
   517     // the size of the code section.
   518     return 5 + NativeJump::instruction_size; // pushl(); jmp;
   519   }
   520 #endif
   521 };
   523 %} // end source_hpp
   525 source %{
   527 #define   NO_INDEX    0
   528 #define   RELOC_IMM64    Assembler::imm_operand
   529 #define   RELOC_DISP32   Assembler::disp32_operand
   532 #define __ _masm.
   535 // Emit exception handler code.
   536 // Stuff framesize into a register and call a VM stub routine.
   537 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
   538   // Note that the code buffer's insts_mark is always relative to insts.
   539   // That's why we must use the macroassembler to generate a handler.
   540   MacroAssembler _masm(&cbuf);
   541   address base = __ start_a_stub(size_exception_handler());
   542   if (base == NULL) {
   543     ciEnv::current()->record_failure("CodeCache is full");
   544     return 0;  // CodeBuffer::expand failed
   545   }
   547   int offset = __ offset();
   549   __ block_comment("; emit_exception_handler");
   551   cbuf.set_insts_mark();
   552   __ relocate(relocInfo::runtime_call_type);
   553   __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
   554   __ align(16);
   555   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
   556   __ end_a_stub();
   557   return offset;
   558 }
   560 // Emit deopt handler code.
   561 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
   562   // Note that the code buffer's insts_mark is always relative to insts.
   563   // That's why we must use the macroassembler to generate a handler.
   564   MacroAssembler _masm(&cbuf);
   565   address base = __ start_a_stub(size_deopt_handler());
   566   if (base == NULL) {
   567     ciEnv::current()->record_failure("CodeCache is full");
   568     return 0;  // CodeBuffer::expand failed
   569   }
   571   int offset = __ offset();
   573   __ block_comment("; emit_deopt_handler");
   575   cbuf.set_insts_mark();
   576   __ relocate(relocInfo::runtime_call_type);
   577   __ patchable_call(SharedRuntime::deopt_blob()->unpack());
   578   __ align(16);
   579   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
   580   __ end_a_stub();
   581   return offset;
   582 }
   585 const bool Matcher::match_rule_supported(int opcode) {
   586   if (!has_match_rule(opcode))
   587     return false;
   589   switch (opcode) {
   590     //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
   591     case Op_CountLeadingZerosI:
   592     case Op_CountLeadingZerosL:
   593       if (!UseCountLeadingZerosInstruction)
   594         return false;
   595       break;
   596     case Op_CountTrailingZerosI:
   597     case Op_CountTrailingZerosL:
   598       if (!UseCountTrailingZerosInstruction)
   599         return false;
   600       break;
   601   }
   603   return true;  // Per default match rules are supported.
   604 }
   606 //FIXME
   607 // emit call stub, compiled java to interpreter
   608 void emit_java_to_interp(CodeBuffer &cbuf ) {
   609   // Stub is fixed up when the corresponding call is converted from calling
   610   // compiled code to calling interpreted code.
   611   // mov rbx,0
   612   // jmp -1
   614   address mark = cbuf.insts_mark();  // get mark within main instrs section
   616   // Note that the code buffer's insts_mark is always relative to insts.
   617   // That's why we must use the macroassembler to generate a stub.
   618   MacroAssembler _masm(&cbuf);
   620   address base = __ start_a_stub(Compile::MAX_stubs_size);
   621   if (base == NULL) { // CodeBuffer::expand failed
   622     ciEnv::current()->record_failure("CodeCache is full");
   623   }
   625   // static stub relocation stores the instruction address of the call
   627   __ relocate(static_stub_Relocation::spec(mark), 0);
   629   // static stub relocation also tags the methodOop in the code-stream.
   630   __ patchable_set48(S3, (long)0);
   631   // This is recognized as unresolved by relocs/nativeInst/ic code
   633   __ relocate(relocInfo::runtime_call_type);
   635   cbuf.set_insts_mark();
   636   address call_pc = (address)-1;
   637   __ patchable_jump(call_pc);
   638   __ align(16);
   639   __ end_a_stub();
   640   // Update current stubs pointer and restore code_end.
   641 }
   643 // size of call stub, compiled java to interpretor
   644 uint size_java_to_interp() {
   645   int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
   646   return round_to(size, 16);
   647 }
   649 // relocation entries for call stub, compiled java to interpreter
   650 uint reloc_java_to_interp() {
   651   return 16;  //  in emit_java_to_interp +  in Java_Static_Call
   652 }
   654 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
   655   int offs = offset - br_size + 4;
   656   // To be conservative on MIPS
   657   const int safety_zone = 3 * BytesPerInstWord;
   658   return Assembler::is_simm16((offs<0 ? offs-safety_zone : offs+safety_zone) >> 2);
   659 }
   662 // No additional cost for CMOVL.
   663 const int Matcher::long_cmove_cost() { return 0; }
   665 // No CMOVF/CMOVD with SSE2
   666 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
   668 // Does the CPU require late expand (see block.cpp for description of late expand)?
   669 const bool Matcher::require_postalloc_expand = false;
   671 // Should the Matcher clone shifts on addressing modes, expecting them
   672 // to be subsumed into complex addressing expressions or compute them
   673 // into registers?  True for Intel but false for most RISCs
   674 const bool Matcher::clone_shift_expressions = false;
   676 // Do we need to mask the count passed to shift instructions or does
   677 // the cpu only look at the lower 5/6 bits anyway?
   678 const bool Matcher::need_masked_shift_count = false;
   680 bool Matcher::narrow_oop_use_complex_address() {
   681   NOT_LP64(ShouldNotCallThis());
   682   assert(UseCompressedOops, "only for compressed oops code");
   683   return false;
   684 }
   686 bool Matcher::narrow_klass_use_complex_address() {
   687   NOT_LP64(ShouldNotCallThis());
   688   assert(UseCompressedClassPointers, "only for compressed klass code");
   689   return false;
   690 }
   692 // This is UltraSparc specific, true just means we have fast l2f conversion
   693 const bool Matcher::convL2FSupported(void) {
   694   return true;
   695 }
   697 // Max vector size in bytes. 0 if not supported.
   698 const int Matcher::vector_width_in_bytes(BasicType bt) {
   699   if (MaxVectorSize == 0)
   700     return 0;
   701   assert(MaxVectorSize == 8, "");
   702   return 8;
   703 }
   705 // Vector ideal reg
   706 const int Matcher::vector_ideal_reg(int size) {
   707   assert(MaxVectorSize == 8, "");
   708   switch(size) {
   709     case  8: return Op_VecD;
   710   }
   711   ShouldNotReachHere();
   712   return 0;
   713 }
   715 // Only lowest bits of xmm reg are used for vector shift count.
   716 const int Matcher::vector_shift_count_ideal_reg(int size) {
   717   fatal("vector shift is not supported");
   718   return Node::NotAMachineReg;
   719 }
   721 // Limits on vector size (number of elements) loaded into vector.
   722 const int Matcher::max_vector_size(const BasicType bt) {
   723   assert(is_java_primitive(bt), "only primitive type vectors");
   724   return vector_width_in_bytes(bt)/type2aelembytes(bt);
   725 }
   727 const int Matcher::min_vector_size(const BasicType bt) {
   728   return max_vector_size(bt); // Same as max.
   729 }
   731 // MIPS supports misaligned vectors store/load? FIXME
   732 const bool Matcher::misaligned_vectors_ok() {
   733   return false;
   734   //return !AlignVector; // can be changed by flag
   735 }
   737 // Register for DIVI projection of divmodI
   738 RegMask Matcher::divI_proj_mask() {
   739   ShouldNotReachHere();
   740   return RegMask();
   741 }
   743 // Register for MODI projection of divmodI
   744 RegMask Matcher::modI_proj_mask() {
   745   ShouldNotReachHere();
   746   return RegMask();
   747 }
   749 // Register for DIVL projection of divmodL
   750 RegMask Matcher::divL_proj_mask() {
   751   ShouldNotReachHere();
   752   return RegMask();
   753 }
   755 int Matcher::regnum_to_fpu_offset(int regnum) {
   756   return regnum - 32; // The FP registers are in the second chunk
   757 }
   760 const bool Matcher::isSimpleConstant64(jlong value) {
   761   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
   762   return true;
   763 }
   766 // Return whether or not this register is ever used as an argument.  This
   767 // function is used on startup to build the trampoline stubs in generateOptoStub.
   768 // Registers not mentioned will be killed by the VM call in the trampoline, and
   769 // arguments in those registers not be available to the callee.
   770 bool Matcher::can_be_java_arg( int reg ) {
   771   /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
   772   if (    reg == T0_num || reg == T0_H_num
   773        || reg == A0_num || reg == A0_H_num
   774        || reg == A1_num || reg == A1_H_num
   775        || reg == A2_num || reg == A2_H_num
   776        || reg == A3_num || reg == A3_H_num
   777        || reg == A4_num || reg == A4_H_num
   778        || reg == A5_num || reg == A5_H_num
   779        || reg == A6_num || reg == A6_H_num
   780        || reg == A7_num || reg == A7_H_num )
   781     return true;
   783   if (    reg == F12_num || reg == F12_H_num
   784        || reg == F13_num || reg == F13_H_num
   785        || reg == F14_num || reg == F14_H_num
   786        || reg == F15_num || reg == F15_H_num
   787        || reg == F16_num || reg == F16_H_num
   788        || reg == F17_num || reg == F17_H_num
   789        || reg == F18_num || reg == F18_H_num
   790        || reg == F19_num || reg == F19_H_num )
   791     return true;
   793   return false;
   794 }
   796 bool Matcher::is_spillable_arg( int reg ) {
   797   return can_be_java_arg(reg);
   798 }
   800 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
   801   return false;
   802 }
   804 // Register for MODL projection of divmodL
   805 RegMask Matcher::modL_proj_mask() {
   806   ShouldNotReachHere();
   807   return RegMask();
   808 }
   810 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
   811   return FP_REG_mask();
   812 }
   814 // MIPS doesn't support AES intrinsics
   815 const bool Matcher::pass_original_key_for_aes() {
   816   return false;
   817 }
   819 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
   820   //lui
   821   //ori
   822   //dsll
   823   //ori
   825   //jalr
   826   //nop
   828   return round_to(current_offset, alignment_required()) - current_offset;
   829 }
   831 int CallLeafDirectNode::compute_padding(int current_offset) const {
   832   //lui
   833   //ori
   834   //dsll
   835   //ori
   837   //jalr
   838   //nop
   840   return round_to(current_offset, alignment_required()) - current_offset;
   841 }
   843 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
   844   //lui
   845   //ori
   846   //dsll
   847   //ori
   849   //jalr
   850   //nop
   852   return round_to(current_offset, alignment_required()) - current_offset;
   853 }
   855 // If CPU can load and store mis-aligned doubles directly then no fixup is
   856 // needed.  Else we split the double into 2 integer pieces and move it
   857 // piece-by-piece.  Only happens when passing doubles into C code as the
   858 // Java calling convention forces doubles to be aligned.
   859 const bool Matcher::misaligned_doubles_ok = false;
   860 // Do floats take an entire double register or just half?
   861 //const bool Matcher::float_in_double = true;
   862 bool Matcher::float_in_double() { return false; }
   863 // Threshold size for cleararray.
   864 const int Matcher::init_array_short_size = 8 * BytesPerLong;
   865 // Do ints take an entire long register or just half?
   866 const bool Matcher::int_in_long = true;
   867 // Is it better to copy float constants, or load them directly from memory?
   868 // Intel can load a float constant from a direct address, requiring no
   869 // extra registers.  Most RISCs will have to materialize an address into a
   870 // register first, so they would do better to copy the constant from stack.
   871 const bool Matcher::rematerialize_float_constants = false;
   872 // Advertise here if the CPU requires explicit rounding operations
   873 // to implement the UseStrictFP mode.
   874 const bool Matcher::strict_fp_requires_explicit_rounding = false;
   875 // The ecx parameter to rep stos for the ClearArray node is in dwords.
   876 const bool Matcher::init_array_count_is_in_bytes = false;
   879 // Indicate if the safepoint node needs the polling page as an input.
   880 // Since MIPS doesn't have absolute addressing, it needs.
   881 bool SafePointNode::needs_polling_address_input() {
   882   return false;
   883 }
   885 // !!!!! Special hack to get all type of calls to specify the byte offset
   886 //       from the start of the call to the point where the return address
   887 //       will point.
   888 int MachCallStaticJavaNode::ret_addr_offset() {
   889   //lui
   890   //ori
   891   //nop
   892   //nop
   893   //jalr
   894   //nop
   895   return 24;
   896 }
   898 int MachCallDynamicJavaNode::ret_addr_offset() {
   899   //lui IC_Klass,
   900   //ori IC_Klass,
   901   //dsll IC_Klass
   902   //ori IC_Klass
   904   //lui T9
   905   //ori T9
   906   //nop
   907   //nop
   908   //jalr T9
   909   //nop
   910   return 4 * 4 + 4 * 6;
   911 }
   913 //=============================================================================
   915 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
   916 enum RC { rc_bad, rc_int, rc_float, rc_stack };
   917 static enum RC rc_class( OptoReg::Name reg ) {
   918   if( !OptoReg::is_valid(reg)  ) return rc_bad;
   919   if (OptoReg::is_stack(reg)) return rc_stack;
   920   VMReg r = OptoReg::as_VMReg(reg);
   921   if (r->is_Register()) return rc_int;
   922   assert(r->is_FloatRegister(), "must be");
   923   return rc_float;
   924 }
   926 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
   927   // Get registers to move
   928   OptoReg::Name src_second = ra_->get_reg_second(in(1));
   929   OptoReg::Name src_first = ra_->get_reg_first(in(1));
   930   OptoReg::Name dst_second = ra_->get_reg_second(this );
   931   OptoReg::Name dst_first = ra_->get_reg_first(this );
   933   enum RC src_second_rc = rc_class(src_second);
   934   enum RC src_first_rc = rc_class(src_first);
   935   enum RC dst_second_rc = rc_class(dst_second);
   936   enum RC dst_first_rc = rc_class(dst_first);
   938   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
   940   // Generate spill code!
   941   int size = 0;
   943   if( src_first == dst_first && src_second == dst_second )
   944     return 0;            // Self copy, no move
   946   if (src_first_rc == rc_stack) {
   947     // mem ->
   948     if (dst_first_rc == rc_stack) {
   949       // mem -> mem
   950       assert(src_second != dst_first, "overlap");
   951       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   952           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   953         // 64-bit
   954         int src_offset = ra_->reg2offset(src_first);
   955         int dst_offset = ra_->reg2offset(dst_first);
   956         if (cbuf) {
   957           MacroAssembler _masm(cbuf);
   958           __ ld(AT, Address(SP, src_offset));
   959           __ sd(AT, Address(SP, dst_offset));
   960 #ifndef PRODUCT
   961         } else {
   962           if(!do_size){
   963             if (size != 0) st->print("\n\t");
   964               st->print("ld    AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
   965                         "sd    AT, [SP + #%d]",
   966                         src_offset, dst_offset);
   967           }
   968 #endif
   969         }
   970         size += 8;
   971       } else {
   972         // 32-bit
   973         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
   974         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
   975         // No pushl/popl, so:
   976         int src_offset = ra_->reg2offset(src_first);
   977         int dst_offset = ra_->reg2offset(dst_first);
   978         if (cbuf) {
   979           MacroAssembler _masm(cbuf);
   980           __ lw(AT, Address(SP, src_offset));
   981           __ sw(AT, Address(SP, dst_offset));
   982 #ifndef PRODUCT
   983         } else {
   984           if(!do_size){
   985             if (size != 0) st->print("\n\t");
   986               st->print("lw    AT, [SP + #%d] spill 2\n\t"
   987                         "sw    AT, [SP + #%d]\n\t",
   988                         src_offset, dst_offset);
   989           }
   990 #endif
   991         }
   992         size += 8;
   993       }
   994       return size;
   995     } else if (dst_first_rc == rc_int) {
   996       // mem -> gpr
   997       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   998           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   999         // 64-bit
  1000         int offset = ra_->reg2offset(src_first);
  1001         if (cbuf) {
  1002           MacroAssembler _masm(cbuf);
  1003           __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1004 #ifndef PRODUCT
  1005         } else {
  1006           if(!do_size){
  1007             if (size != 0) st->print("\n\t");
  1008               st->print("ld    %s, [SP + #%d]\t# spill 3",
  1009                         Matcher::regName[dst_first],
  1010                         offset);
  1012 #endif
  1014         size += 4;
  1015       } else {
  1016         // 32-bit
  1017         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1018         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1019         int offset = ra_->reg2offset(src_first);
  1020         if (cbuf) {
  1021           MacroAssembler _masm(cbuf);
  1022           if (this->ideal_reg() == Op_RegI)
  1023             __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1024           else
  1025             __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1026 #ifndef PRODUCT
  1027           } else {
  1028             if(!do_size){
  1029               if (size != 0) st->print("\n\t");
  1030               if (this->ideal_reg() == Op_RegI)
  1031                 st->print("lw    %s, [SP + #%d]\t# spill 4",
  1032                           Matcher::regName[dst_first],
  1033                           offset);
  1034               else
  1035                 st->print("lwu    %s, [SP + #%d]\t# spill 5",
  1036                           Matcher::regName[dst_first],
  1037                           offset);
  1039 #endif
  1041           size += 4;
  1043       return size;
  1044     } else if (dst_first_rc == rc_float) {
  1045       // mem-> xmm
  1046       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1047           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1048         // 64-bit
  1049         int offset = ra_->reg2offset(src_first);
  1050         if (cbuf) {
  1051           MacroAssembler _masm(cbuf);
  1052           __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1053 #ifndef PRODUCT
  1054         } else {
  1055           if (!do_size) {
  1056             if (size != 0) st->print("\n\t");
  1057             st->print("ldc1  %s, [SP + #%d]\t# spill 6",
  1058                       Matcher::regName[dst_first],
  1059                       offset);
  1061 #endif
  1063         size += 4;
  1064       } else {
  1065         // 32-bit
  1066         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1067         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1068         int offset = ra_->reg2offset(src_first);
  1069         if (cbuf) {
  1070           MacroAssembler _masm(cbuf);
  1071           __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1072 #ifndef PRODUCT
  1073         } else {
  1074           if(!do_size){
  1075             if (size != 0) st->print("\n\t");
  1076             st->print("lwc1   %s, [SP + #%d]\t# spill 7",
  1077                       Matcher::regName[dst_first],
  1078                       offset);
  1080 #endif
  1082         size += 4;
  1084       return size;
  1086   } else if (src_first_rc == rc_int) {
  1087     // gpr ->
  1088     if (dst_first_rc == rc_stack) {
  1089       // gpr -> mem
  1090       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1091           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1092         // 64-bit
  1093         int offset = ra_->reg2offset(dst_first);
  1094         if (cbuf) {
  1095           MacroAssembler _masm(cbuf);
  1096           __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1097 #ifndef PRODUCT
  1098         } else {
  1099           if(!do_size){
  1100             if (size != 0) st->print("\n\t");
  1101             st->print("sd    %s, [SP + #%d] # spill 8",
  1102                       Matcher::regName[src_first],
  1103                       offset);
  1105 #endif
  1107         size += 4;
  1108       } else {
  1109         // 32-bit
  1110         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1111         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1112         int offset = ra_->reg2offset(dst_first);
  1113         if (cbuf) {
  1114           MacroAssembler _masm(cbuf);
  1115           __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1116 #ifndef PRODUCT
  1117         } else {
  1118           if (!do_size) {
  1119             if (size != 0) st->print("\n\t");
  1120             st->print("sw    %s, [SP + #%d]\t# spill 9",
  1121                       Matcher::regName[src_first], offset);
  1123 #endif
  1125         size += 4;
  1127       return size;
  1128     } else if (dst_first_rc == rc_int) {
  1129       // gpr -> gpr
  1130       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1131           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1132         // 64-bit
  1133         if (cbuf) {
  1134           MacroAssembler _masm(cbuf);
  1135           __ move(as_Register(Matcher::_regEncode[dst_first]),
  1136                   as_Register(Matcher::_regEncode[src_first]));
  1137 #ifndef PRODUCT
  1138         } else {
  1139           if(!do_size){
  1140             if (size != 0) st->print("\n\t");
  1141             st->print("move(64bit)    %s <-- %s\t# spill 10",
  1142                       Matcher::regName[dst_first],
  1143                       Matcher::regName[src_first]);
  1145 #endif
  1147         size += 4;
  1148         return size;
  1149       } else {
  1150         // 32-bit
  1151         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1152         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1153         if (cbuf) {
  1154           MacroAssembler _masm(cbuf);
  1155           if (this->ideal_reg() == Op_RegI)
  1156               __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
  1157           else
  1158               __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
  1159 #ifndef PRODUCT
  1160         } else {
  1161           if (!do_size) {
  1162             if (size != 0) st->print("\n\t");
  1163             st->print("move(32-bit)    %s <-- %s\t# spill 11",
  1164                       Matcher::regName[dst_first],
  1165                       Matcher::regName[src_first]);
  1167 #endif
  1169         size += 4;
  1170         return size;
  1172     } else if (dst_first_rc == rc_float) {
  1173       // gpr -> xmm
  1174       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1175           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1176         // 64-bit
  1177         if (cbuf) {
  1178           MacroAssembler _masm(cbuf);
  1179           __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
  1180 #ifndef PRODUCT
  1181         } else {
  1182           if(!do_size){
  1183             if (size != 0) st->print("\n\t");
  1184             st->print("dmtc1   %s, %s\t# spill 12",
  1185                       Matcher::regName[dst_first],
  1186                       Matcher::regName[src_first]);
  1188 #endif
  1190         size += 4;
  1191       } else {
  1192         // 32-bit
  1193         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1194         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1195         if (cbuf) {
  1196           MacroAssembler _masm(cbuf);
  1197           __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
  1198 #ifndef PRODUCT
  1199         } else {
  1200           if(!do_size){
  1201             if (size != 0) st->print("\n\t");
  1202             st->print("mtc1   %s, %s\t# spill 13",
  1203                       Matcher::regName[dst_first],
  1204                       Matcher::regName[src_first]);
  1206 #endif
  1208         size += 4;
  1210       return size;
  1212   } else if (src_first_rc == rc_float) {
  1213     // xmm ->
  1214     if (dst_first_rc == rc_stack) {
  1215       // xmm -> mem
  1216       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1217           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1218         // 64-bit
  1219         int offset = ra_->reg2offset(dst_first);
  1220         if (cbuf) {
  1221           MacroAssembler _masm(cbuf);
  1222           __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
  1223 #ifndef PRODUCT
  1224         } else {
  1225           if(!do_size){
  1226             if (size != 0) st->print("\n\t");
  1227             st->print("sdc1   %s, [SP + #%d]\t# spill 14",
  1228                       Matcher::regName[src_first],
  1229                       offset);
  1231 #endif
  1233         size += 4;
  1234       } else {
  1235         // 32-bit
  1236         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1237         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1238         int offset = ra_->reg2offset(dst_first);
  1239         if (cbuf) {
  1240           MacroAssembler _masm(cbuf);
  1241           __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
  1242 #ifndef PRODUCT
  1243         } else {
  1244           if(!do_size){
  1245             if (size != 0) st->print("\n\t");
  1246             st->print("swc1   %s, [SP + #%d]\t# spill 15",
  1247                       Matcher::regName[src_first],
  1248                       offset);
  1250 #endif
  1252         size += 4;
  1254       return size;
  1255     } else if (dst_first_rc == rc_int) {
  1256       // xmm -> gpr
  1257       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1258           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1259         // 64-bit
  1260         if (cbuf) {
  1261           MacroAssembler _masm(cbuf);
  1262           __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1263 #ifndef PRODUCT
  1264         } else {
  1265           if(!do_size){
  1266             if (size != 0) st->print("\n\t");
  1267             st->print("dmfc1   %s, %s\t# spill 16",
  1268                       Matcher::regName[dst_first],
  1269                       Matcher::regName[src_first]);
  1271 #endif
  1273         size += 4;
  1274       } else {
  1275         // 32-bit
  1276         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1277         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1278         if (cbuf) {
  1279           MacroAssembler _masm(cbuf);
  1280           __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1281 #ifndef PRODUCT
  1282         } else {
  1283       if(!do_size){
  1284             if (size != 0) st->print("\n\t");
  1285             st->print("mfc1   %s, %s\t# spill 17",
  1286                       Matcher::regName[dst_first],
  1287                       Matcher::regName[src_first]);
  1289 #endif
  1291         size += 4;
  1293       return size;
  1294     } else if (dst_first_rc == rc_float) {
  1295       // xmm -> xmm
  1296       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1297           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1298         // 64-bit
  1299         if (cbuf) {
  1300           MacroAssembler _masm(cbuf);
  1301           __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1302 #ifndef PRODUCT
  1303         } else {
  1304           if(!do_size){
  1305             if (size != 0) st->print("\n\t");
  1306             st->print("mov_d  %s <-- %s\t# spill 18",
  1307                       Matcher::regName[dst_first],
  1308                       Matcher::regName[src_first]);
  1310 #endif
  1312         size += 4;
  1313       } else {
  1314         // 32-bit
  1315         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1316         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1317         if (cbuf) {
  1318           MacroAssembler _masm(cbuf);
  1319           __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1320 #ifndef PRODUCT
  1321         } else {
  1322           if(!do_size){
  1323             if (size != 0) st->print("\n\t");
  1324             st->print("mov_s  %s <-- %s\t# spill 19",
  1325                       Matcher::regName[dst_first],
  1326                       Matcher::regName[src_first]);
  1328 #endif
  1330         size += 4;
  1332       return size;
  1336   assert(0," foo ");
  1337   Unimplemented();
  1338   return size;
  1342 #ifndef PRODUCT
  1343 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1344   implementation( NULL, ra_, false, st );
  1346 #endif
  1348 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1349   implementation( &cbuf, ra_, false, NULL );
  1352 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  1353   return implementation( NULL, ra_, true, NULL );
  1356 //=============================================================================
  1359 #ifndef PRODUCT
  1360 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1361   st->print("INT3");
  1363 #endif
  1365 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
  1366   MacroAssembler _masm(&cbuf);
  1367   __ int3();
  1370 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
  1371   return MachNode::size(ra_);
  1375 //=============================================================================
  1376 #ifndef PRODUCT
  1377 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1378   Compile *C = ra_->C;
  1379   int framesize = C->frame_size_in_bytes();
  1381   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1383   st->print("daddiu   SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
  1384   st->cr(); st->print("\t");
  1385   if (UseLoongsonISA) {
  1386     st->print("gslq  RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
  1387   } else {
  1388     st->print("ld    RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
  1389     st->cr(); st->print("\t");
  1390     st->print("ld    FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
  1393   if( do_polling() && C->is_method_compilation() ) {
  1394     st->print("Poll Safepoint # MachEpilogNode");
  1397 #endif
  1399 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1400   Compile *C = ra_->C;
  1401   MacroAssembler _masm(&cbuf);
  1402   int framesize = C->frame_size_in_bytes();
  1404   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1406   __ daddiu(SP, SP, framesize);
  1408   if (UseLoongsonISA) {
  1409     __ gslq(RA, FP, SP, -wordSize*2);
  1410   } else {
  1411     __ ld(RA, SP, -wordSize );
  1412     __ ld(FP, SP, -wordSize*2 );
  1415   if( do_polling() && C->is_method_compilation() ) {
  1416     __ set64(AT, (long)os::get_polling_page());
  1417     __ relocate(relocInfo::poll_return_type);
  1418     __ lw(AT, AT, 0);
  1422 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  1423   return MachNode::size(ra_); // too many variables; just compute it the hard way  fujie debug
  1426 int MachEpilogNode::reloc() const {
  1427   return 0; // a large enough number
  1430 const Pipeline * MachEpilogNode::pipeline() const {
  1431   return MachNode::pipeline_class();
  1434 int MachEpilogNode::safepoint_offset() const { return 0; }
  1436 //=============================================================================
  1438 #ifndef PRODUCT
  1439 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1440   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1441   int reg = ra_->get_reg_first(this);
  1442   st->print("ADDI %s, SP, %d   @BoxLockNode",Matcher::regName[reg],offset);
  1444 #endif
  1447 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  1448   return 4;
  1451 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1452   MacroAssembler _masm(&cbuf);
  1453   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1454   int reg = ra_->get_encode(this);
  1456   __ addi(as_Register(reg), SP, offset);
  1460 //static int sizeof_FFree_Float_Stack_All = -1;
  1462 int MachCallRuntimeNode::ret_addr_offset() {
  1463   //lui
  1464   //ori
  1465   //dsll
  1466   //ori
  1467   //jalr
  1468   //nop
  1469   assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
  1470   return NativeCall::instruction_size;
  1474 //=============================================================================
  1475 #ifndef PRODUCT
  1476 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1477   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  1479 #endif
  1481 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  1482   MacroAssembler _masm(&cbuf);
  1483   int i = 0;
  1484   for(i = 0; i < _count; i++)
  1485      __ nop();
  1488 uint MachNopNode::size(PhaseRegAlloc *) const {
  1489   return 4 * _count;
  1491 const Pipeline* MachNopNode::pipeline() const {
  1492   return MachNode::pipeline_class();
  1495 //=============================================================================
  1497 //=============================================================================
  1498 #ifndef PRODUCT
  1499 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1500   st->print_cr("load_klass(T9, T0)");
  1501   st->print_cr("\tbeq(T9, iCache, L)");
  1502   st->print_cr("\tnop");
  1503   st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
  1504   st->print_cr("\tnop");
  1505   st->print_cr("\tnop");
  1506   st->print_cr("    L:");
  1508 #endif
  1511 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1512   MacroAssembler _masm(&cbuf);
  1513 #ifdef ASSERT
  1514   //uint code_size = cbuf.code_size();
  1515 #endif
  1516   int  ic_reg = Matcher::inline_cache_reg_encode();
  1517   Label L;
  1518   Register receiver = T0;
  1519   Register   iCache = as_Register(ic_reg);
  1520   __ load_klass(T9, receiver);
  1521   __ beq(T9, iCache, L);
  1522   __ nop();
  1524   __ relocate(relocInfo::runtime_call_type);
  1525   __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
  1527   /* WARNING these NOPs are critical so that verified entry point is properly
  1528    *      8 bytes aligned for patching by NativeJump::patch_verified_entry() */
  1529   __ align(CodeEntryAlignment);
  1530   __ bind(L);
  1533 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  1534   return MachNode::size(ra_);
  1539 //=============================================================================
  1541 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
  1543 int Compile::ConstantTable::calculate_table_base_offset() const {
  1544   return 0;  // absolute addressing, no offset
  1547 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  1548 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  1549   ShouldNotReachHere();
  1552 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  1553   Compile* C = ra_->C;
  1554   Compile::ConstantTable& constant_table = C->constant_table();
  1555   MacroAssembler _masm(&cbuf);
  1557   Register Rtoc = as_Register(ra_->get_encode(this));
  1558   CodeSection* consts_section = __ code()->consts();
  1559   int consts_size = consts_section->align_at_start(consts_section->size());
  1560   assert(constant_table.size() == consts_size, "must be equal");
  1562   if (consts_section->size()) {
  1563     // Materialize the constant table base.
  1564     address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  1565     // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  1566     __ relocate(relocInfo::internal_word_type);
  1567     __ patchable_set48(Rtoc, (long)baseaddr);
  1571 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
  1572   // patchable_set48 (4 insts)
  1573   return 4 * 4;
  1576 #ifndef PRODUCT
  1577 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  1578   Register r = as_Register(ra_->get_encode(this));
  1579   st->print("patchable_set48    %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
  1581 #endif
  1584 //=============================================================================
  1585 #ifndef PRODUCT
  1586 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1587   Compile* C = ra_->C;
  1589   int framesize = C->frame_size_in_bytes();
  1590   int bangsize = C->bang_size_in_bytes();
  1591   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1593   // Calls to C2R adapters often do not accept exceptional returns.
  1594   // We require that their callers must bang for them.  But be careful, because
  1595   // some VM calls (such as call site linkage) can use several kilobytes of
  1596   // stack.  But the stack safety zone should account for that.
  1597   // See bugs 4446381, 4468289, 4497237.
  1598   if (C->need_stack_bang(bangsize)) {
  1599     st->print_cr("# stack bang"); st->print("\t");
  1601   if (UseLoongsonISA) {
  1602     st->print("gssq     RA, FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1603   } else {
  1604     st->print("sd       RA, %d(SP)  @ MachPrologNode\n\t", -wordSize);
  1605     st->print("sd       FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1607   st->print("daddiu   FP, SP, -%d \n\t", wordSize*2);
  1608   st->print("daddiu   SP, SP, -%d \t",framesize);
  1610 #endif
  1613 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1614   Compile* C = ra_->C;
  1615   MacroAssembler _masm(&cbuf);
  1617   int framesize = C->frame_size_in_bytes();
  1618   int bangsize = C->bang_size_in_bytes();
  1620   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1622   if (C->need_stack_bang(bangsize)) {
  1623     __ generate_stack_overflow_check(bangsize);
  1626   if (UseLoongsonISA) {
  1627     __ gssq(RA, FP, SP, -wordSize*2);
  1628   } else {
  1629     __ sd(RA, SP, -wordSize);
  1630     __ sd(FP, SP, -wordSize*2);
  1632   __ daddiu(FP, SP, -wordSize*2);
  1633   __ daddiu(SP, SP, -framesize);
  1634   __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
  1635   __ nop();
  1637   C->set_frame_complete(cbuf.insts_size());
  1638   if (C->has_mach_constant_base_node()) {
  1639     // NOTE: We set the table base offset here because users might be
  1640     // emitted before MachConstantBaseNode.
  1641     Compile::ConstantTable& constant_table = C->constant_table();
  1642     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  1648 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  1649   return MachNode::size(ra_); // too many variables; just compute it the hard way
  1652 int MachPrologNode::reloc() const {
  1653   return 0; // a large enough number
  1656 %}
  1658 //----------ENCODING BLOCK-----------------------------------------------------
  1659 // This block specifies the encoding classes used by the compiler to output
  1660 // byte streams.  Encoding classes generate functions which are called by
  1661 // Machine Instruction Nodes in order to generate the bit encoding of the
  1662 // instruction.  Operands specify their base encoding interface with the
  1663 // interface keyword.  There are currently supported four interfaces,
  1664 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
  1665 // operand to generate a function which returns its register number when
  1666 // queried.   CONST_INTER causes an operand to generate a function which
  1667 // returns the value of the constant when queried.  MEMORY_INTER causes an
  1668 // operand to generate four functions which return the Base Register, the
  1669 // Index Register, the Scale Value, and the Offset Value of the operand when
  1670 // queried.  COND_INTER causes an operand to generate six functions which
  1671 // return the encoding code (ie - encoding bits for the instruction)
  1672 // associated with each basic boolean condition for a conditional instruction.
  1673 // Instructions specify two basic values for encoding.  They use the
  1674 // ins_encode keyword to specify their encoding class (which must be one of
  1675 // the class names specified in the encoding block), and they use the
  1676 // opcode keyword to specify, in order, their primary, secondary, and
  1677 // tertiary opcode.  Only the opcode sections which a particular instruction
  1678 // needs for encoding need to be specified.
  1679 encode %{
  1681   //Load byte signed
  1682   enc_class load_B_enc (mRegI dst, memory mem) %{
  1683     MacroAssembler _masm(&cbuf);
  1684     int  dst = $dst$$reg;
  1685     int  base = $mem$$base;
  1686     int  index = $mem$$index;
  1687     int  scale = $mem$$scale;
  1688     int  disp = $mem$$disp;
  1690     if( index != 0 ) {
  1691       if( Assembler::is_simm16(disp) ) {
  1692         if( UseLoongsonISA ) {
  1693           if (scale == 0) {
  1694             __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1695           } else {
  1696             __ dsll(AT, as_Register(index), scale);
  1697             __ gslbx(as_Register(dst), as_Register(base), AT, disp);
  1699         } else {
  1700           if (scale == 0) {
  1701             __ addu(AT, as_Register(base), as_Register(index));
  1702           } else {
  1703             __ dsll(AT, as_Register(index), scale);
  1704             __ addu(AT, as_Register(base), AT);
  1706           __ lb(as_Register(dst), AT, disp);
  1708       } else {
  1709         if (scale == 0) {
  1710           __ addu(AT, as_Register(base), as_Register(index));
  1711         } else {
  1712           __ dsll(AT, as_Register(index), scale);
  1713           __ addu(AT, as_Register(base), AT);
  1715         __ move(T9, disp);
  1716         if( UseLoongsonISA ) {
  1717           __ gslbx(as_Register(dst), AT, T9, 0);
  1718         } else {
  1719           __ addu(AT, AT, T9);
  1720           __ lb(as_Register(dst), AT, 0);
  1723     } else {
  1724       if( Assembler::is_simm16(disp) ) {
  1725         __ lb(as_Register(dst), as_Register(base), disp);
  1726       } else {
  1727         __ move(T9, disp);
  1728         if( UseLoongsonISA ) {
  1729           __ gslbx(as_Register(dst), as_Register(base), T9, 0);
  1730         } else {
  1731           __ addu(AT, as_Register(base), T9);
  1732           __ lb(as_Register(dst), AT, 0);
  1736   %}
  1738   //Load byte unsigned
  1739   enc_class load_UB_enc (mRegI dst, memory mem) %{
  1740     MacroAssembler _masm(&cbuf);
  1741     int  dst = $dst$$reg;
  1742     int  base = $mem$$base;
  1743     int  index = $mem$$index;
  1744     int  scale = $mem$$scale;
  1745     int  disp = $mem$$disp;
  1747     if( index != 0 ) {
  1748       if (scale == 0) {
  1749         __ daddu(AT, as_Register(base), as_Register(index));
  1750       } else {
  1751         __ dsll(AT, as_Register(index), scale);
  1752         __ daddu(AT, as_Register(base), AT);
  1754       if( Assembler::is_simm16(disp) ) {
  1755         __ lbu(as_Register(dst), AT, disp);
  1756       } else {
  1757         __ move(T9, disp);
  1758         __ daddu(AT, AT, T9);
  1759         __ lbu(as_Register(dst), AT, 0);
  1761     } else {
  1762       if( Assembler::is_simm16(disp) ) {
  1763         __ lbu(as_Register(dst), as_Register(base), disp);
  1764       } else {
  1765         __ move(T9, disp);
  1766         __ daddu(AT, as_Register(base), T9);
  1767         __ lbu(as_Register(dst), AT, 0);
  1770   %}
  1772   enc_class store_B_reg_enc (memory mem, mRegI src) %{
  1773     MacroAssembler _masm(&cbuf);
  1774     int  src = $src$$reg;
  1775     int  base = $mem$$base;
  1776     int  index = $mem$$index;
  1777     int  scale = $mem$$scale;
  1778     int  disp = $mem$$disp;
  1780     if( index != 0 ) {
  1781       if (scale == 0) {
  1782         if( Assembler::is_simm(disp, 8) ) {
  1783           if (UseLoongsonISA) {
  1784             __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
  1785           } else {
  1786             __ addu(AT, as_Register(base), as_Register(index));
  1787             __ sb(as_Register(src), AT, disp);
  1789         } else if( Assembler::is_simm16(disp) ) {
  1790           __ addu(AT, as_Register(base), as_Register(index));
  1791           __ sb(as_Register(src), AT, disp);
  1792         } else {
  1793           __ addu(AT, as_Register(base), as_Register(index));
  1794           __ move(T9, disp);
  1795           if (UseLoongsonISA) {
  1796             __ gssbx(as_Register(src), AT, T9, 0);
  1797           } else {
  1798             __ addu(AT, AT, T9);
  1799             __ sb(as_Register(src), AT, 0);
  1802       } else {
  1803         __ dsll(AT, as_Register(index), scale);
  1804         if( Assembler::is_simm(disp, 8) ) {
  1805           if (UseLoongsonISA) {
  1806             __ gssbx(as_Register(src), AT, as_Register(base), disp);
  1807           } else {
  1808             __ addu(AT, as_Register(base), AT);
  1809             __ sb(as_Register(src), AT, disp);
  1811         } else if( Assembler::is_simm16(disp) ) {
  1812           __ addu(AT, as_Register(base), AT);
  1813           __ sb(as_Register(src), AT, disp);
  1814         } else {
  1815           __ addu(AT, as_Register(base), AT);
  1816           __ move(T9, disp);
  1817           if (UseLoongsonISA) {
  1818             __ gssbx(as_Register(src), AT, T9, 0);
  1819           } else {
  1820             __ addu(AT, AT, T9);
  1821             __ sb(as_Register(src), AT, 0);
  1825     } else {
  1826       if( Assembler::is_simm16(disp) ) {
  1827         __ sb(as_Register(src), as_Register(base), disp);
  1828       } else {
  1829         __ move(T9, disp);
  1830         if (UseLoongsonISA) {
  1831           __ gssbx(as_Register(src), as_Register(base), T9, 0);
  1832         } else {
  1833           __ addu(AT, as_Register(base), T9);
  1834           __ sb(as_Register(src), AT, 0);
  1838   %}
  1840   enc_class store_B_immI_enc (memory mem, immI8 src) %{
  1841     MacroAssembler _masm(&cbuf);
  1842     int  base = $mem$$base;
  1843     int  index = $mem$$index;
  1844     int  scale = $mem$$scale;
  1845     int  disp = $mem$$disp;
  1846     int value = $src$$constant;
  1848     if( index != 0 ) {
  1849       if (!UseLoongsonISA) {
  1850         if (scale == 0) {
  1851           __ daddu(AT, as_Register(base), as_Register(index));
  1852         } else {
  1853           __ dsll(AT, as_Register(index), scale);
  1854           __ daddu(AT, as_Register(base), AT);
  1856         if( Assembler::is_simm16(disp) ) {
  1857           if (value == 0) {
  1858             __ sb(R0, AT, disp);
  1859           } else {
  1860             __ move(T9, value);
  1861             __ sb(T9, AT, disp);
  1863         } else {
  1864           if (value == 0) {
  1865             __ move(T9, disp);
  1866             __ daddu(AT, AT, T9);
  1867             __ sb(R0, AT, 0);
  1868           } else {
  1869             __ move(T9, disp);
  1870             __ daddu(AT, AT, T9);
  1871             __ move(T9, value);
  1872             __ sb(T9, AT, 0);
  1875       } else {
  1877         if (scale == 0) {
  1878           if( Assembler::is_simm(disp, 8) ) {
  1879             if (value == 0) {
  1880               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1881             } else {
  1882               __ move(T9, value);
  1883               __ gssbx(T9, as_Register(base), as_Register(index), disp);
  1885           } else if( Assembler::is_simm16(disp) ) {
  1886             __ daddu(AT, as_Register(base), as_Register(index));
  1887             if (value == 0) {
  1888               __ sb(R0, AT, disp);
  1889             } else {
  1890               __ move(T9, value);
  1891               __ sb(T9, AT, disp);
  1893           } else {
  1894             if (value == 0) {
  1895               __ daddu(AT, as_Register(base), as_Register(index));
  1896               __ move(T9, disp);
  1897               __ gssbx(R0, AT, T9, 0);
  1898             } else {
  1899               __ move(AT, disp);
  1900               __ move(T9, value);
  1901               __ daddu(AT, as_Register(base), AT);
  1902               __ gssbx(T9, AT, as_Register(index), 0);
  1906         } else {
  1908           if( Assembler::is_simm(disp, 8) ) {
  1909             __ dsll(AT, as_Register(index), scale);
  1910             if (value == 0) {
  1911               __ gssbx(R0, as_Register(base), AT, disp);
  1912             } else {
  1913               __ move(T9, value);
  1914               __ gssbx(T9, as_Register(base), AT, disp);
  1916           } else if( Assembler::is_simm16(disp) ) {
  1917             __ dsll(AT, as_Register(index), scale);
  1918             __ daddu(AT, as_Register(base), AT);
  1919             if (value == 0) {
  1920               __ sb(R0, AT, disp);
  1921             } else {
  1922               __ move(T9, value);
  1923               __ sb(T9, AT, disp);
  1925           } else {
  1926             __ dsll(AT, as_Register(index), scale);
  1927             if (value == 0) {
  1928               __ daddu(AT, as_Register(base), AT);
  1929               __ move(T9, disp);
  1930               __ gssbx(R0, AT, T9, 0);
  1931             } else {
  1932               __ move(T9, disp);
  1933               __ daddu(AT, AT, T9);
  1934               __ move(T9, value);
  1935               __ gssbx(T9, as_Register(base), AT, 0);
  1940     } else {
  1941       if( Assembler::is_simm16(disp) ) {
  1942         if (value == 0) {
  1943           __ sb(R0, as_Register(base), disp);
  1944         } else {
  1945           __ move(AT, value);
  1946           __ sb(AT, as_Register(base), disp);
  1948       } else {
  1949         if (value == 0) {
  1950           __ move(T9, disp);
  1951           if (UseLoongsonISA) {
  1952             __ gssbx(R0, as_Register(base), T9, 0);
  1953           } else {
  1954             __ daddu(AT, as_Register(base), T9);
  1955             __ sb(R0, AT, 0);
  1957         } else {
  1958           __ move(T9, disp);
  1959           if (UseLoongsonISA) {
  1960             __ move(AT, value);
  1961             __ gssbx(AT, as_Register(base), T9, 0);
  1962           } else {
  1963             __ daddu(AT, as_Register(base), T9);
  1964             __ move(T9, value);
  1965             __ sb(T9, AT, 0);
  1970   %}
  1973   enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
  1974     MacroAssembler _masm(&cbuf);
  1975     int  base = $mem$$base;
  1976     int  index = $mem$$index;
  1977     int  scale = $mem$$scale;
  1978     int  disp = $mem$$disp;
  1979     int value = $src$$constant;
  1981     if( index != 0 ) {
  1982       if ( UseLoongsonISA ) {
  1983         if ( Assembler::is_simm(disp,8) ) {
  1984           if ( scale == 0 ) {
  1985             if ( value == 0 ) {
  1986               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1987             } else {
  1988               __ move(AT, value);
  1989               __ gssbx(AT, as_Register(base), as_Register(index), disp);
  1991           } else {
  1992             __ dsll(AT, as_Register(index), scale);
  1993             if ( value == 0 ) {
  1994               __ gssbx(R0, as_Register(base), AT, disp);
  1995             } else {
  1996               __ move(T9, value);
  1997               __ gssbx(T9, as_Register(base), AT, disp);
  2000         } else if ( Assembler::is_simm16(disp) ) {
  2001           if ( scale == 0 ) {
  2002             __ daddu(AT, as_Register(base), as_Register(index));
  2003             if ( value == 0 ){
  2004               __ sb(R0, AT, disp);
  2005             } else {
  2006               __ move(T9, value);
  2007               __ sb(T9, AT, disp);
  2009           } else {
  2010             __ dsll(AT, as_Register(index), scale);
  2011             __ daddu(AT, as_Register(base), AT);
  2012             if ( value == 0 ) {
  2013               __ sb(R0, AT, disp);
  2014             } else {
  2015               __ move(T9, value);
  2016               __ sb(T9, AT, disp);
  2019         } else {
  2020           if ( scale == 0 ) {
  2021             __ move(AT, disp);
  2022             __ daddu(AT, as_Register(index), AT);
  2023             if ( value == 0 ) {
  2024               __ gssbx(R0, as_Register(base), AT, 0);
  2025             } else {
  2026               __ move(T9, value);
  2027               __ gssbx(T9, as_Register(base), AT, 0);
  2029           } else {
  2030             __ dsll(AT, as_Register(index), scale);
  2031             __ move(T9, disp);
  2032             __ daddu(AT, AT, T9);
  2033             if ( value == 0 ) {
  2034               __ gssbx(R0, as_Register(base), AT, 0);
  2035             } else {
  2036               __ move(T9, value);
  2037               __ gssbx(T9, as_Register(base), AT, 0);
  2041       } else { //not use loongson isa
  2042         if (scale == 0) {
  2043           __ daddu(AT, as_Register(base), as_Register(index));
  2044         } else {
  2045           __ dsll(AT, as_Register(index), scale);
  2046           __ daddu(AT, as_Register(base), AT);
  2048         if( Assembler::is_simm16(disp) ) {
  2049           if (value == 0) {
  2050             __ sb(R0, AT, disp);
  2051           } else {
  2052             __ move(T9, value);
  2053             __ sb(T9, AT, disp);
  2055         } else {
  2056           if (value == 0) {
  2057             __ move(T9, disp);
  2058             __ daddu(AT, AT, T9);
  2059             __ sb(R0, AT, 0);
  2060           } else {
  2061             __ move(T9, disp);
  2062             __ daddu(AT, AT, T9);
  2063             __ move(T9, value);
  2064             __ sb(T9, AT, 0);
  2068     } else {
  2069       if ( UseLoongsonISA ){
  2070         if ( Assembler::is_simm16(disp) ){
  2071           if ( value == 0 ) {
  2072             __ sb(R0, as_Register(base), disp);
  2073           } else {
  2074             __ move(AT, value);
  2075             __ sb(AT, as_Register(base), disp);
  2077         } else {
  2078           __ move(AT, disp);
  2079           if ( value == 0 ) {
  2080             __ gssbx(R0, as_Register(base), AT, 0);
  2081           } else {
  2082             __ move(T9, value);
  2083             __ gssbx(T9, as_Register(base), AT, 0);
  2086       } else {
  2087         if( Assembler::is_simm16(disp) ) {
  2088           if (value == 0) {
  2089             __ sb(R0, as_Register(base), disp);
  2090           } else {
  2091             __ move(AT, value);
  2092             __ sb(AT, as_Register(base), disp);
  2094         } else {
  2095           if (value == 0) {
  2096             __ move(T9, disp);
  2097             __ daddu(AT, as_Register(base), T9);
  2098             __ sb(R0, AT, 0);
  2099           } else {
  2100             __ move(T9, disp);
  2101             __ daddu(AT, as_Register(base), T9);
  2102             __ move(T9, value);
  2103             __ sb(T9, AT, 0);
  2109     __ sync();
  2110   %}
  2112   // Load Short (16bit signed)
  2113   enc_class load_S_enc (mRegI dst, memory mem) %{
  2114     MacroAssembler _masm(&cbuf);
  2115     int  dst = $dst$$reg;
  2116     int  base = $mem$$base;
  2117     int  index = $mem$$index;
  2118     int  scale = $mem$$scale;
  2119     int  disp = $mem$$disp;
  2121     if( index != 0 ) {
  2122       if ( UseLoongsonISA ) {
  2123         if ( Assembler::is_simm(disp, 8) ) {
  2124           if (scale == 0) {
  2125             __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2126           } else {
  2127             __ dsll(AT, as_Register(index), scale);
  2128             __ gslhx(as_Register(dst), as_Register(base), AT, disp);
  2130         } else if ( Assembler::is_simm16(disp) ) {
  2131           if (scale == 0) {
  2132             __ daddu(AT, as_Register(base), as_Register(index));
  2133             __ lh(as_Register(dst), AT, disp);
  2134           } else {
  2135             __ dsll(AT, as_Register(index), scale);
  2136             __ daddu(AT, as_Register(base), AT);
  2137             __ lh(as_Register(dst), AT, disp);
  2139         } else {
  2140           if (scale == 0) {
  2141             __ move(AT, disp);
  2142             __ daddu(AT, as_Register(index), AT);
  2143             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2144           } else {
  2145             __ dsll(AT, as_Register(index), scale);
  2146             __ move(T9, disp);
  2147             __ daddu(AT, AT, T9);
  2148             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2151       } else { // not use loongson isa
  2152         if (scale == 0) {
  2153           __ daddu(AT, as_Register(base), as_Register(index));
  2154         } else {
  2155           __ dsll(AT, as_Register(index), scale);
  2156           __ daddu(AT, as_Register(base), AT);
  2158         if( Assembler::is_simm16(disp) ) {
  2159           __ lh(as_Register(dst), AT, disp);
  2160         } else {
  2161           __ move(T9, disp);
  2162           __ daddu(AT, AT, T9);
  2163           __ lh(as_Register(dst), AT, 0);
  2166     } else { // index is 0
  2167       if ( UseLoongsonISA ) {
  2168         if ( Assembler::is_simm16(disp) ) {
  2169           __ lh(as_Register(dst), as_Register(base), disp);
  2170         } else {
  2171           __ move(T9, disp);
  2172           __ gslhx(as_Register(dst), as_Register(base), T9, 0);
  2174       } else { //not use loongson isa
  2175         if( Assembler::is_simm16(disp) ) {
  2176           __ lh(as_Register(dst), as_Register(base), disp);
  2177         } else {
  2178           __ move(T9, disp);
  2179           __ daddu(AT, as_Register(base), T9);
  2180           __ lh(as_Register(dst), AT, 0);
  2184   %}
  2186   // Load Char (16bit unsigned)
  2187   enc_class load_C_enc (mRegI dst, memory mem) %{
  2188     MacroAssembler _masm(&cbuf);
  2189     int  dst = $dst$$reg;
  2190     int  base = $mem$$base;
  2191     int  index = $mem$$index;
  2192     int  scale = $mem$$scale;
  2193     int  disp = $mem$$disp;
  2195     if( index != 0 ) {
  2196       if (scale == 0) {
  2197         __ daddu(AT, as_Register(base), as_Register(index));
  2198       } else {
  2199         __ dsll(AT, as_Register(index), scale);
  2200         __ daddu(AT, as_Register(base), AT);
  2202       if( Assembler::is_simm16(disp) ) {
  2203         __ lhu(as_Register(dst), AT, disp);
  2204       } else {
  2205         __ move(T9, disp);
  2206         __ addu(AT, AT, T9);
  2207         __ lhu(as_Register(dst), AT, 0);
  2209     } else {
  2210       if( Assembler::is_simm16(disp) ) {
  2211         __ lhu(as_Register(dst), as_Register(base), disp);
  2212       } else {
  2213         __ move(T9, disp);
  2214         __ daddu(AT, as_Register(base), T9);
  2215         __ lhu(as_Register(dst), AT, 0);
  2218   %}
  2220   // Store Char (16bit unsigned)
  2221   enc_class store_C_reg_enc (memory mem, mRegI src) %{
  2222     MacroAssembler _masm(&cbuf);
  2223     int  src = $src$$reg;
  2224     int  base = $mem$$base;
  2225     int  index = $mem$$index;
  2226     int  scale = $mem$$scale;
  2227     int  disp = $mem$$disp;
  2229     if( index != 0 ) {
  2230       if( Assembler::is_simm16(disp) ) {
  2231         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2232           if (scale == 0) {
  2233             __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
  2234           } else {
  2235             __ dsll(AT, as_Register(index), scale);
  2236             __ gsshx(as_Register(src), as_Register(base), AT, disp);
  2238         } else {
  2239           if (scale == 0) {
  2240             __ addu(AT, as_Register(base), as_Register(index));
  2241           } else {
  2242             __ dsll(AT, as_Register(index), scale);
  2243             __ addu(AT, as_Register(base), AT);
  2245           __ sh(as_Register(src), AT, disp);
  2247       } else {
  2248         if (scale == 0) {
  2249           __ addu(AT, as_Register(base), as_Register(index));
  2250         } else {
  2251           __ dsll(AT, as_Register(index), scale);
  2252           __ addu(AT, as_Register(base), AT);
  2254         __ move(T9, disp);
  2255         if( UseLoongsonISA ) {
  2256           __ gsshx(as_Register(src), AT, T9, 0);
  2257         } else {
  2258           __ addu(AT, AT, T9);
  2259           __ sh(as_Register(src), AT, 0);
  2262     } else {
  2263       if( Assembler::is_simm16(disp) ) {
  2264         __ sh(as_Register(src), as_Register(base), disp);
  2265       } else {
  2266         __ move(T9, disp);
  2267         if( UseLoongsonISA ) {
  2268           __ gsshx(as_Register(src), as_Register(base), T9, 0);
  2269         } else {
  2270           __ addu(AT, as_Register(base), T9);
  2271           __ sh(as_Register(src), AT, 0);
  2275   %}
  2277   enc_class store_C0_enc (memory mem) %{
  2278     MacroAssembler _masm(&cbuf);
  2279     int  base = $mem$$base;
  2280     int  index = $mem$$index;
  2281     int  scale = $mem$$scale;
  2282     int  disp = $mem$$disp;
  2284     if( index != 0 ) {
  2285       if( Assembler::is_simm16(disp) ) {
  2286         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2287           if (scale == 0) {
  2288             __ gsshx(R0, as_Register(base), as_Register(index), disp);
  2289           } else {
  2290             __ dsll(AT, as_Register(index), scale);
  2291             __ gsshx(R0, as_Register(base), AT, disp);
  2293         } else {
  2294           if (scale == 0) {
  2295             __ addu(AT, as_Register(base), as_Register(index));
  2296           } else {
  2297             __ dsll(AT, as_Register(index), scale);
  2298             __ addu(AT, as_Register(base), AT);
  2300           __ sh(R0, AT, disp);
  2302       } else {
  2303         if (scale == 0) {
  2304           __ addu(AT, as_Register(base), as_Register(index));
  2305         } else {
  2306           __ dsll(AT, as_Register(index), scale);
  2307           __ addu(AT, as_Register(base), AT);
  2309         __ move(T9, disp);
  2310         if( UseLoongsonISA ) {
  2311           __ gsshx(R0, AT, T9, 0);
  2312         } else {
  2313           __ addu(AT, AT, T9);
  2314           __ sh(R0, AT, 0);
  2317     } else {
  2318       if( Assembler::is_simm16(disp) ) {
  2319         __ sh(R0, as_Register(base), disp);
  2320       } else {
  2321         __ move(T9, disp);
  2322         if( UseLoongsonISA ) {
  2323           __ gsshx(R0, as_Register(base), T9, 0);
  2324         } else {
  2325           __ addu(AT, as_Register(base), T9);
  2326           __ sh(R0, AT, 0);
  2330   %}
  2332   enc_class load_I_enc (mRegI dst, memory mem) %{
  2333     MacroAssembler _masm(&cbuf);
  2334     int  dst = $dst$$reg;
  2335     int  base = $mem$$base;
  2336     int  index = $mem$$index;
  2337     int  scale = $mem$$scale;
  2338     int  disp = $mem$$disp;
  2340     if( index != 0 ) {
  2341       if( Assembler::is_simm16(disp) ) {
  2342         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2343           if (scale == 0) {
  2344             __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2345           } else {
  2346             __ dsll(AT, as_Register(index), scale);
  2347             __ gslwx(as_Register(dst), as_Register(base), AT, disp);
  2349         } else {
  2350           if (scale == 0) {
  2351             __ addu(AT, as_Register(base), as_Register(index));
  2352           } else {
  2353             __ dsll(AT, as_Register(index), scale);
  2354             __ addu(AT, as_Register(base), AT);
  2356           __ lw(as_Register(dst), AT, disp);
  2358       } else {
  2359         if (scale == 0) {
  2360           __ addu(AT, as_Register(base), as_Register(index));
  2361         } else {
  2362           __ dsll(AT, as_Register(index), scale);
  2363           __ addu(AT, as_Register(base), AT);
  2365         __ move(T9, disp);
  2366         if( UseLoongsonISA ) {
  2367           __ gslwx(as_Register(dst), AT, T9, 0);
  2368         } else {
  2369           __ addu(AT, AT, T9);
  2370           __ lw(as_Register(dst), AT, 0);
  2373     } else {
  2374       if( Assembler::is_simm16(disp) ) {
  2375         __ lw(as_Register(dst), as_Register(base), disp);
  2376       } else {
  2377         __ move(T9, disp);
  2378         if( UseLoongsonISA ) {
  2379           __ gslwx(as_Register(dst), as_Register(base), T9, 0);
  2380         } else {
  2381           __ addu(AT, as_Register(base), T9);
  2382           __ lw(as_Register(dst), AT, 0);
  2386   %}
  2388   enc_class store_I_reg_enc (memory mem, mRegI src) %{
  2389     MacroAssembler _masm(&cbuf);
  2390     int  src = $src$$reg;
  2391     int  base = $mem$$base;
  2392     int  index = $mem$$index;
  2393     int  scale = $mem$$scale;
  2394     int  disp = $mem$$disp;
  2396     if( index != 0 ) {
  2397       if( Assembler::is_simm16(disp) ) {
  2398         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2399           if (scale == 0) {
  2400             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2401           } else {
  2402             __ dsll(AT, as_Register(index), scale);
  2403             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2405         } else {
  2406           if (scale == 0) {
  2407             __ addu(AT, as_Register(base), as_Register(index));
  2408           } else {
  2409             __ dsll(AT, as_Register(index), scale);
  2410             __ addu(AT, as_Register(base), AT);
  2412           __ sw(as_Register(src), AT, disp);
  2414       } else {
  2415         if (scale == 0) {
  2416           __ addu(AT, as_Register(base), as_Register(index));
  2417         } else {
  2418           __ dsll(AT, as_Register(index), scale);
  2419           __ addu(AT, as_Register(base), AT);
  2421         __ move(T9, disp);
  2422         if( UseLoongsonISA ) {
  2423           __ gsswx(as_Register(src), AT, T9, 0);
  2424         } else {
  2425           __ addu(AT, AT, T9);
  2426           __ sw(as_Register(src), AT, 0);
  2429     } else {
  2430       if( Assembler::is_simm16(disp) ) {
  2431         __ sw(as_Register(src), as_Register(base), disp);
  2432       } else {
  2433         __ move(T9, disp);
  2434         if( UseLoongsonISA ) {
  2435           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2436         } else {
  2437           __ addu(AT, as_Register(base), T9);
  2438           __ sw(as_Register(src), AT, 0);
  2442   %}
  2444   enc_class store_I_immI_enc (memory mem, immI src) %{
  2445     MacroAssembler _masm(&cbuf);
  2446     int  base = $mem$$base;
  2447     int  index = $mem$$index;
  2448     int  scale = $mem$$scale;
  2449     int  disp = $mem$$disp;
  2450     int value = $src$$constant;
  2452     if( index != 0 ) {
  2453       if ( UseLoongsonISA ) {
  2454         if ( Assembler::is_simm(disp, 8) ) {
  2455           if ( scale == 0 ) {
  2456             if ( value == 0 ) {
  2457               __ gsswx(R0, as_Register(base), as_Register(index), disp);
  2458             } else {
  2459               __ move(T9, value);
  2460               __ gsswx(T9, as_Register(base), as_Register(index), disp);
  2462           } else {
  2463             __ dsll(AT, as_Register(index), scale);
  2464             if ( value == 0 ) {
  2465               __ gsswx(R0, as_Register(base), AT, disp);
  2466             } else {
  2467               __ move(T9, value);
  2468               __ gsswx(T9, as_Register(base), AT, disp);
  2471         } else if ( Assembler::is_simm16(disp) ) {
  2472           if ( scale == 0 ) {
  2473             __ daddu(AT, as_Register(base), as_Register(index));
  2474             if ( value == 0 ) {
  2475               __ sw(R0, AT, disp);
  2476             } else {
  2477               __ move(T9, value);
  2478               __ sw(T9, AT, disp);
  2480           } else {
  2481             __ dsll(AT, as_Register(index), scale);
  2482             __ daddu(AT, as_Register(base), AT);
  2483             if ( value == 0 ) {
  2484               __ sw(R0, AT, disp);
  2485             } else {
  2486               __ move(T9, value);
  2487               __ sw(T9, AT, disp);
  2490         } else {
  2491           if ( scale == 0 ) {
  2492             __ move(T9, disp);
  2493             __ daddu(AT, as_Register(index), T9);
  2494             if ( value ==0 ) {
  2495               __ gsswx(R0, as_Register(base), AT, 0);
  2496             } else {
  2497               __ move(T9, value);
  2498               __ gsswx(T9, as_Register(base), AT, 0);
  2500           } else {
  2501             __ dsll(AT, as_Register(index), scale);
  2502             __ move(T9, disp);
  2503             __ daddu(AT, AT, T9);
  2504             if ( value == 0 ) {
  2505               __ gsswx(R0, as_Register(base), AT, 0);
  2506             } else {
  2507               __ move(T9, value);
  2508               __ gsswx(T9, as_Register(base), AT, 0);
  2512       } else { //not use loongson isa
  2513         if (scale == 0) {
  2514           __ daddu(AT, as_Register(base), as_Register(index));
  2515         } else {
  2516           __ dsll(AT, as_Register(index), scale);
  2517           __ daddu(AT, as_Register(base), AT);
  2519         if( Assembler::is_simm16(disp) ) {
  2520           if (value == 0) {
  2521             __ sw(R0, AT, disp);
  2522           } else {
  2523             __ move(T9, value);
  2524             __ sw(T9, AT, disp);
  2526         } else {
  2527           if (value == 0) {
  2528             __ move(T9, disp);
  2529             __ daddu(AT, AT, T9);
  2530             __ sw(R0, AT, 0);
  2531           } else {
  2532             __ move(T9, disp);
  2533             __ daddu(AT, AT, T9);
  2534             __ move(T9, value);
  2535             __ sw(T9, AT, 0);
  2539     } else {
  2540       if ( UseLoongsonISA ) {
  2541         if ( Assembler::is_simm16(disp) ) {
  2542           if ( value == 0 ) {
  2543             __ sw(R0, as_Register(base), disp);
  2544           } else {
  2545             __ move(AT, value);
  2546             __ sw(AT, as_Register(base), disp);
  2548         } else {
  2549           __ move(T9, disp);
  2550           if ( value == 0 ) {
  2551             __ gsswx(R0, as_Register(base), T9, 0);
  2552           } else {
  2553             __ move(AT, value);
  2554             __ gsswx(AT, as_Register(base), T9, 0);
  2557       } else {
  2558         if( Assembler::is_simm16(disp) ) {
  2559           if (value == 0) {
  2560             __ sw(R0, as_Register(base), disp);
  2561           } else {
  2562             __ move(AT, value);
  2563             __ sw(AT, as_Register(base), disp);
  2565         } else {
  2566           if (value == 0) {
  2567             __ move(T9, disp);
  2568             __ daddu(AT, as_Register(base), T9);
  2569             __ sw(R0, AT, 0);
  2570           } else {
  2571             __ move(T9, disp);
  2572             __ daddu(AT, as_Register(base), T9);
  2573             __ move(T9, value);
  2574             __ sw(T9, AT, 0);
  2579   %}
  2581   enc_class load_N_enc (mRegN dst, memory mem) %{
  2582     MacroAssembler _masm(&cbuf);
  2583     int  dst = $dst$$reg;
  2584     int  base = $mem$$base;
  2585     int  index = $mem$$index;
  2586     int  scale = $mem$$scale;
  2587     int  disp = $mem$$disp;
  2588     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2589     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2591     if( index != 0 ) {
  2592       if (scale == 0) {
  2593         __ daddu(AT, as_Register(base), as_Register(index));
  2594       } else {
  2595         __ dsll(AT, as_Register(index), scale);
  2596         __ daddu(AT, as_Register(base), AT);
  2598       if( Assembler::is_simm16(disp) ) {
  2599         __ lwu(as_Register(dst), AT, disp);
  2600       } else {
  2601         __ set64(T9, disp);
  2602         __ daddu(AT, AT, T9);
  2603         __ lwu(as_Register(dst), AT, 0);
  2605     } else {
  2606       if( Assembler::is_simm16(disp) ) {
  2607         __ lwu(as_Register(dst), as_Register(base), disp);
  2608       } else {
  2609         __ set64(T9, disp);
  2610         __ daddu(AT, as_Register(base), T9);
  2611         __ lwu(as_Register(dst), AT, 0);
  2614   %}
  2617   enc_class load_P_enc (mRegP dst, memory mem) %{
  2618     MacroAssembler _masm(&cbuf);
  2619     int  dst = $dst$$reg;
  2620     int  base = $mem$$base;
  2621     int  index = $mem$$index;
  2622     int  scale = $mem$$scale;
  2623     int  disp = $mem$$disp;
  2624     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2625     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2627     if( index != 0 ) {
  2628       if ( UseLoongsonISA ) {
  2629         if ( Assembler::is_simm(disp, 8) ) {
  2630           if ( scale != 0 ) {
  2631             __ dsll(AT, as_Register(index), scale);
  2632             __ gsldx(as_Register(dst), as_Register(base), AT, disp);
  2633           } else {
  2634             __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2636         } else if ( Assembler::is_simm16(disp) ){
  2637           if ( scale != 0 ) {
  2638             __ dsll(AT, as_Register(index), scale);
  2639             __ daddu(AT, AT, as_Register(base));
  2640           } else {
  2641             __ daddu(AT, as_Register(index), as_Register(base));
  2643           __ ld(as_Register(dst), AT, disp);
  2644         } else {
  2645           if ( scale != 0 ) {
  2646             __ dsll(AT, as_Register(index), scale);
  2647             __ move(T9, disp);
  2648             __ daddu(AT, AT, T9);
  2649           } else {
  2650             __ move(T9, disp);
  2651             __ daddu(AT, as_Register(index), T9);
  2653           __ gsldx(as_Register(dst), as_Register(base), AT, 0);
  2655       } else { //not use loongson isa
  2656         if (scale == 0) {
  2657           __ daddu(AT, as_Register(base), as_Register(index));
  2658         } else {
  2659           __ dsll(AT, as_Register(index), scale);
  2660           __ daddu(AT, as_Register(base), AT);
  2662         if( Assembler::is_simm16(disp) ) {
  2663           __ ld(as_Register(dst), AT, disp);
  2664         } else {
  2665           __ set64(T9, disp);
  2666           __ daddu(AT, AT, T9);
  2667           __ ld(as_Register(dst), AT, 0);
  2670     } else {
  2671       if ( UseLoongsonISA ) {
  2672         if ( Assembler::is_simm16(disp) ){
  2673           __ ld(as_Register(dst), as_Register(base), disp);
  2674         } else {
  2675           __ set64(T9, disp);
  2676           __ gsldx(as_Register(dst), as_Register(base), T9, 0);
  2678       } else { //not use loongson isa
  2679         if( Assembler::is_simm16(disp) ) {
  2680           __ ld(as_Register(dst), as_Register(base), disp);
  2681         } else {
  2682           __ set64(T9, disp);
  2683           __ daddu(AT, as_Register(base), T9);
  2684           __ ld(as_Register(dst), AT, 0);
  2688   %}
  2690   enc_class store_P_reg_enc (memory mem, mRegP src) %{
  2691     MacroAssembler _masm(&cbuf);
  2692     int  src = $src$$reg;
  2693     int  base = $mem$$base;
  2694     int  index = $mem$$index;
  2695     int  scale = $mem$$scale;
  2696     int  disp = $mem$$disp;
  2698     if( index != 0 ) {
  2699       if ( UseLoongsonISA ){
  2700         if ( Assembler::is_simm(disp, 8) ) {
  2701           if ( scale == 0 ) {
  2702             __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
  2703           } else {
  2704             __ dsll(AT, as_Register(index), scale);
  2705             __ gssdx(as_Register(src), as_Register(base), AT, disp);
  2707         } else if ( Assembler::is_simm16(disp) ) {
  2708           if ( scale == 0 ) {
  2709             __ daddu(AT, as_Register(base), as_Register(index));
  2710           } else {
  2711             __ dsll(AT, as_Register(index), scale);
  2712             __ daddu(AT, as_Register(base), AT);
  2714           __ sd(as_Register(src), AT, disp);
  2715         } else {
  2716           if ( scale == 0 ) {
  2717             __ move(T9, disp);
  2718             __ daddu(AT, as_Register(index), T9);
  2719           } else {
  2720             __ dsll(AT, as_Register(index), scale);
  2721             __ move(T9, disp);
  2722             __ daddu(AT, AT, T9);
  2724           __ gssdx(as_Register(src), as_Register(base), AT, 0);
  2726       } else { //not use loongson isa
  2727         if (scale == 0) {
  2728           __ daddu(AT, as_Register(base), as_Register(index));
  2729         } else {
  2730           __ dsll(AT, as_Register(index), scale);
  2731           __ daddu(AT, as_Register(base), AT);
  2733         if( Assembler::is_simm16(disp) ) {
  2734           __ sd(as_Register(src), AT, disp);
  2735         } else {
  2736           __ move(T9, disp);
  2737           __ daddu(AT, AT, T9);
  2738           __ sd(as_Register(src), AT, 0);
  2741     } else {
  2742       if ( UseLoongsonISA ) {
  2743         if ( Assembler::is_simm16(disp) ) {
  2744           __ sd(as_Register(src), as_Register(base), disp);
  2745         } else {
  2746           __ move(T9, disp);
  2747           __ gssdx(as_Register(src), as_Register(base), T9, 0);
  2749       } else {
  2750         if( Assembler::is_simm16(disp) ) {
  2751           __ sd(as_Register(src), as_Register(base), disp);
  2752         } else {
  2753           __ move(T9, disp);
  2754           __ daddu(AT, as_Register(base), T9);
  2755           __ sd(as_Register(src), AT, 0);
  2759   %}
  2761   enc_class store_N_reg_enc (memory mem, mRegN src) %{
  2762     MacroAssembler _masm(&cbuf);
  2763     int  src = $src$$reg;
  2764     int  base = $mem$$base;
  2765     int  index = $mem$$index;
  2766     int  scale = $mem$$scale;
  2767     int  disp = $mem$$disp;
  2769     if( index != 0 ) {
  2770       if ( UseLoongsonISA ){
  2771         if ( Assembler::is_simm(disp, 8) ) {
  2772           if ( scale == 0 ) {
  2773             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2774           } else {
  2775             __ dsll(AT, as_Register(index), scale);
  2776             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2778         } else if ( Assembler::is_simm16(disp) ) {
  2779           if ( scale == 0 ) {
  2780             __ daddu(AT, as_Register(base), as_Register(index));
  2781           } else {
  2782             __ dsll(AT, as_Register(index), scale);
  2783             __ daddu(AT, as_Register(base), AT);
  2785           __ sw(as_Register(src), AT, disp);
  2786         } else {
  2787           if ( scale == 0 ) {
  2788             __ move(T9, disp);
  2789             __ daddu(AT, as_Register(index), T9);
  2790           } else {
  2791             __ dsll(AT, as_Register(index), scale);
  2792             __ move(T9, disp);
  2793             __ daddu(AT, AT, T9);
  2795           __ gsswx(as_Register(src), as_Register(base), AT, 0);
  2797       } else { //not use loongson isa
  2798         if (scale == 0) {
  2799           __ daddu(AT, as_Register(base), as_Register(index));
  2800         } else {
  2801           __ dsll(AT, as_Register(index), scale);
  2802           __ daddu(AT, as_Register(base), AT);
  2804         if( Assembler::is_simm16(disp) ) {
  2805           __ sw(as_Register(src), AT, disp);
  2806         } else {
  2807           __ move(T9, disp);
  2808           __ daddu(AT, AT, T9);
  2809           __ sw(as_Register(src), AT, 0);
  2812     } else {
  2813       if ( UseLoongsonISA ) {
  2814         if ( Assembler::is_simm16(disp) ) {
  2815           __ sw(as_Register(src), as_Register(base), disp);
  2816         } else {
  2817           __ move(T9, disp);
  2818           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2820       } else {
  2821         if( Assembler::is_simm16(disp) ) {
  2822           __ sw(as_Register(src), as_Register(base), disp);
  2823         } else {
  2824           __ move(T9, disp);
  2825           __ daddu(AT, as_Register(base), T9);
  2826           __ sw(as_Register(src), AT, 0);
  2830   %}
  2832   enc_class store_P_immP0_enc (memory mem) %{
  2833     MacroAssembler _masm(&cbuf);
  2834     int  base = $mem$$base;
  2835     int  index = $mem$$index;
  2836     int  scale = $mem$$scale;
  2837     int  disp = $mem$$disp;
  2839     if( index != 0 ) {
  2840       if (scale == 0) {
  2841         if( Assembler::is_simm16(disp) ) {
  2842           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2843             __ gssdx(R0, as_Register(base), as_Register(index), disp);
  2844           } else {
  2845             __ daddu(AT, as_Register(base), as_Register(index));
  2846             __ sd(R0, AT, disp);
  2848         } else {
  2849           __ daddu(AT, as_Register(base), as_Register(index));
  2850           __ move(T9, disp);
  2851           if(UseLoongsonISA) {
  2852             __ gssdx(R0, AT, T9, 0);
  2853           } else {
  2854             __ daddu(AT, AT, T9);
  2855             __ sd(R0, AT, 0);
  2858       } else {
  2859         __ dsll(AT, as_Register(index), scale);
  2860         if( Assembler::is_simm16(disp) ) {
  2861           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2862             __ gssdx(R0, as_Register(base), AT, disp);
  2863           } else {
  2864             __ daddu(AT, as_Register(base), AT);
  2865             __ sd(R0, AT, disp);
  2867         } else {
  2868           __ daddu(AT, as_Register(base), AT);
  2869           __ move(T9, disp);
  2870           if (UseLoongsonISA) {
  2871             __ gssdx(R0, AT, T9, 0);
  2872           } else {
  2873             __ daddu(AT, AT, T9);
  2874             __ sd(R0, AT, 0);
  2878     } else {
  2879       if( Assembler::is_simm16(disp) ) {
  2880         __ sd(R0, as_Register(base), disp);
  2881       } else {
  2882         __ move(T9, disp);
  2883         if (UseLoongsonISA) {
  2884           __ gssdx(R0, as_Register(base), T9, 0);
  2885         } else {
  2886           __ daddu(AT, as_Register(base), T9);
  2887           __ sd(R0, AT, 0);
  2891   %}
  2893   enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
  2894     MacroAssembler _masm(&cbuf);
  2895     int  base = $mem$$base;
  2896     int  index = $mem$$index;
  2897     int  scale = $mem$$scale;
  2898     int  disp = $mem$$disp;
  2900     if(index!=0){
  2901       if (scale == 0) {
  2902         __ daddu(AT, as_Register(base), as_Register(index));
  2903       } else {
  2904         __ dsll(AT, as_Register(index), scale);
  2905         __ daddu(AT, as_Register(base), AT);
  2908       if( Assembler::is_simm16(disp) ) {
  2909         __ sw(R0, AT, disp);
  2910       } else {
  2911         __ move(T9, disp);
  2912         __ daddu(AT, AT, T9);
  2913         __ sw(R0, AT, 0);
  2915     } else {
  2916       if( Assembler::is_simm16(disp) ) {
  2917         __ sw(R0, as_Register(base), disp);
  2918       } else {
  2919         __ move(T9, disp);
  2920         __ daddu(AT, as_Register(base), T9);
  2921         __ sw(R0, AT, 0);
  2924   %}
  2926   enc_class load_L_enc (mRegL dst, memory mem) %{
  2927     MacroAssembler _masm(&cbuf);
  2928     int  base = $mem$$base;
  2929     int  index = $mem$$index;
  2930     int  scale = $mem$$scale;
  2931     int  disp = $mem$$disp;
  2932     Register  dst_reg = as_Register($dst$$reg);
  2934     if( index != 0 ) {
  2935       if (scale == 0) {
  2936         __ daddu(AT, as_Register(base), as_Register(index));
  2937       } else {
  2938         __ dsll(AT, as_Register(index), scale);
  2939         __ daddu(AT, as_Register(base), AT);
  2941       if( Assembler::is_simm16(disp) ) {
  2942         __ ld(dst_reg, AT, disp);
  2943       } else {
  2944         __ move(T9, disp);
  2945         __ daddu(AT, AT, T9);
  2946         __ ld(dst_reg, AT, 0);
  2948     } else {
  2949       if( Assembler::is_simm16(disp) ) {
  2950         __ ld(dst_reg, as_Register(base), disp);
  2951       } else {
  2952         __ move(T9, disp);
  2953         __ daddu(AT, as_Register(base), T9);
  2954         __ ld(dst_reg, AT, 0);
  2957   %}
  2959   enc_class store_L_reg_enc (memory mem, mRegL src) %{
  2960     MacroAssembler _masm(&cbuf);
  2961     int  base = $mem$$base;
  2962     int  index = $mem$$index;
  2963     int  scale = $mem$$scale;
  2964     int  disp = $mem$$disp;
  2965     Register  src_reg = as_Register($src$$reg);
  2967     if( index != 0 ) {
  2968       if (scale == 0) {
  2969         __ daddu(AT, as_Register(base), as_Register(index));
  2970       } else {
  2971         __ dsll(AT, as_Register(index), scale);
  2972         __ daddu(AT, as_Register(base), AT);
  2974       if( Assembler::is_simm16(disp) ) {
  2975         __ sd(src_reg, AT, disp);
  2976       } else {
  2977         __ move(T9, disp);
  2978         __ daddu(AT, AT, T9);
  2979         __ sd(src_reg, AT, 0);
  2981     } else {
  2982       if( Assembler::is_simm16(disp) ) {
  2983         __ sd(src_reg, as_Register(base), disp);
  2984       } else {
  2985         __ move(T9, disp);
  2986         __ daddu(AT, as_Register(base), T9);
  2987         __ sd(src_reg, AT, 0);
  2990   %}
  2992   enc_class store_L_immL0_enc (memory mem, immL0 src) %{
  2993     MacroAssembler _masm(&cbuf);
  2994     int  base = $mem$$base;
  2995     int  index = $mem$$index;
  2996     int  scale = $mem$$scale;
  2997     int  disp = $mem$$disp;
  2999     if( index != 0 ) {
  3000       if (scale == 0) {
  3001         __ daddu(AT, as_Register(base), as_Register(index));
  3002       } else {
  3003         __ dsll(AT, as_Register(index), scale);
  3004         __ daddu(AT, as_Register(base), AT);
  3006       if( Assembler::is_simm16(disp) ) {
  3007         __ sd(R0, AT, disp);
  3008       } else {
  3009         __ move(T9, disp);
  3010         __ addu(AT, AT, T9);
  3011         __ sd(R0, AT, 0);
  3013     } else {
  3014       if( Assembler::is_simm16(disp) ) {
  3015         __ sd(R0, as_Register(base), disp);
  3016       } else {
  3017         __ move(T9, disp);
  3018         __ addu(AT, as_Register(base), T9);
  3019         __ sd(R0, AT, 0);
  3022   %}
  3024   enc_class store_L_immL_enc (memory mem, immL src) %{
  3025     MacroAssembler _masm(&cbuf);
  3026     int  base = $mem$$base;
  3027     int  index = $mem$$index;
  3028     int  scale = $mem$$scale;
  3029     int  disp = $mem$$disp;
  3030     long  imm = $src$$constant;
  3032     if( index != 0 ) {
  3033       if (scale == 0) {
  3034         __ daddu(AT, as_Register(base), as_Register(index));
  3035       } else {
  3036         __ dsll(AT, as_Register(index), scale);
  3037         __ daddu(AT, as_Register(base), AT);
  3039       if( Assembler::is_simm16(disp) ) {
  3040         __ set64(T9, imm);
  3041         __ sd(T9, AT, disp);
  3042       } else {
  3043         __ move(T9, disp);
  3044         __ addu(AT, AT, T9);
  3045         __ set64(T9, imm);
  3046         __ sd(T9, AT, 0);
  3048     } else {
  3049       if( Assembler::is_simm16(disp) ) {
  3050         __ move(AT, as_Register(base));
  3051         __ set64(T9, imm);
  3052         __ sd(T9, AT, disp);
  3053       } else {
  3054         __ move(T9, disp);
  3055         __ addu(AT, as_Register(base), T9);
  3056         __ set64(T9, imm);
  3057         __ sd(T9, AT, 0);
  3060   %}
  3062   enc_class load_F_enc (regF dst, memory mem) %{
  3063     MacroAssembler _masm(&cbuf);
  3064     int  base = $mem$$base;
  3065     int  index = $mem$$index;
  3066     int  scale = $mem$$scale;
  3067     int  disp = $mem$$disp;
  3068     FloatRegister dst = $dst$$FloatRegister;
  3070     if( index != 0 ) {
  3071       if( Assembler::is_simm16(disp) ) {
  3072         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3073           if (scale == 0) {
  3074             __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
  3075           } else {
  3076             __ dsll(AT, as_Register(index), scale);
  3077             __ gslwxc1(dst, as_Register(base), AT, disp);
  3079         } else {
  3080           if (scale == 0) {
  3081             __ daddu(AT, as_Register(base), as_Register(index));
  3082           } else {
  3083             __ dsll(AT, as_Register(index), scale);
  3084             __ daddu(AT, as_Register(base), AT);
  3086           __ lwc1(dst, AT, disp);
  3088       } else {
  3089         if (scale == 0) {
  3090           __ daddu(AT, as_Register(base), as_Register(index));
  3091         } else {
  3092           __ dsll(AT, as_Register(index), scale);
  3093           __ daddu(AT, as_Register(base), AT);
  3095         __ move(T9, disp);
  3096         if( UseLoongsonISA ) {
  3097           __ gslwxc1(dst, AT, T9, 0);
  3098         } else {
  3099           __ daddu(AT, AT, T9);
  3100           __ lwc1(dst, AT, 0);
  3103     } else {
  3104       if( Assembler::is_simm16(disp) ) {
  3105         __ lwc1(dst, as_Register(base), disp);
  3106       } else {
  3107         __ move(T9, disp);
  3108         if( UseLoongsonISA ) {
  3109           __ gslwxc1(dst, as_Register(base), T9, 0);
  3110         } else {
  3111           __ daddu(AT, as_Register(base), T9);
  3112           __ lwc1(dst, AT, 0);
  3116   %}
  3118   enc_class store_F_reg_enc (memory mem, regF src) %{
  3119     MacroAssembler _masm(&cbuf);
  3120     int  base = $mem$$base;
  3121     int  index = $mem$$index;
  3122     int  scale = $mem$$scale;
  3123     int  disp = $mem$$disp;
  3124     FloatRegister src = $src$$FloatRegister;
  3126     if( index != 0 ) {
  3127       if( Assembler::is_simm16(disp) ) {
  3128         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3129           if (scale == 0) {
  3130             __ gsswxc1(src, as_Register(base), as_Register(index), disp);
  3131           } else {
  3132             __ dsll(AT, as_Register(index), scale);
  3133             __ gsswxc1(src, as_Register(base), AT, disp);
  3135         } else {
  3136           if (scale == 0) {
  3137             __ daddu(AT, as_Register(base), as_Register(index));
  3138           } else {
  3139             __ dsll(AT, as_Register(index), scale);
  3140             __ daddu(AT, as_Register(base), AT);
  3142           __ swc1(src, AT, disp);
  3144       } else {
  3145         if (scale == 0) {
  3146           __ daddu(AT, as_Register(base), as_Register(index));
  3147         } else {
  3148           __ dsll(AT, as_Register(index), scale);
  3149           __ daddu(AT, as_Register(base), AT);
  3151         __ move(T9, disp);
  3152         if( UseLoongsonISA ) {
  3153           __ gsswxc1(src, AT, T9, 0);
  3154         } else {
  3155           __ daddu(AT, AT, T9);
  3156           __ swc1(src, AT, 0);
  3159     } else {
  3160       if( Assembler::is_simm16(disp) ) {
  3161         __ swc1(src, as_Register(base), disp);
  3162       } else {
  3163         __ move(T9, disp);
  3164         if( UseLoongsonISA ) {
  3165           __ gsswxc1(src, as_Register(base), T9, 0);
  3166         } else {
  3167           __ daddu(AT, as_Register(base), T9);
  3168           __ swc1(src, AT, 0);
  3172   %}
  3174   enc_class load_D_enc (regD dst, memory mem) %{
  3175     MacroAssembler _masm(&cbuf);
  3176     int  base = $mem$$base;
  3177     int  index = $mem$$index;
  3178     int  scale = $mem$$scale;
  3179     int  disp = $mem$$disp;
  3180     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
  3182     if( index != 0 ) {
  3183       if( Assembler::is_simm16(disp) ) {
  3184         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3185           if (scale == 0) {
  3186             __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
  3187           } else {
  3188             __ dsll(AT, as_Register(index), scale);
  3189             __ gsldxc1(dst_reg, as_Register(base), AT, disp);
  3191         } else {
  3192           if (scale == 0) {
  3193             __ daddu(AT, as_Register(base), as_Register(index));
  3194           } else {
  3195             __ dsll(AT, as_Register(index), scale);
  3196             __ daddu(AT, as_Register(base), AT);
  3198           __ ldc1(dst_reg, AT, disp);
  3200       } else {
  3201         if (scale == 0) {
  3202           __ daddu(AT, as_Register(base), as_Register(index));
  3203         } else {
  3204           __ dsll(AT, as_Register(index), scale);
  3205           __ daddu(AT, as_Register(base), AT);
  3207         __ move(T9, disp);
  3208         if( UseLoongsonISA ) {
  3209           __ gsldxc1(dst_reg, AT, T9, 0);
  3210         } else {
  3211           __ addu(AT, AT, T9);
  3212           __ ldc1(dst_reg, AT, 0);
  3215     } else {
  3216       if( Assembler::is_simm16(disp) ) {
  3217         __ ldc1(dst_reg, as_Register(base), disp);
  3218       } else {
  3219         __ move(T9, disp);
  3220         if( UseLoongsonISA ) {
  3221           __ gsldxc1(dst_reg, as_Register(base), T9, 0);
  3222         } else {
  3223           __ addu(AT, as_Register(base), T9);
  3224           __ ldc1(dst_reg, AT, 0);
  3228   %}
  3230   enc_class store_D_reg_enc (memory mem, regD src) %{
  3231     MacroAssembler _masm(&cbuf);
  3232     int  base = $mem$$base;
  3233     int  index = $mem$$index;
  3234     int  scale = $mem$$scale;
  3235     int  disp = $mem$$disp;
  3236     FloatRegister src_reg = as_FloatRegister($src$$reg);
  3238     if( index != 0 ) {
  3239       if( Assembler::is_simm16(disp) ) {
  3240         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3241           if (scale == 0) {
  3242             __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
  3243           } else {
  3244             __ dsll(AT, as_Register(index), scale);
  3245             __ gssdxc1(src_reg, as_Register(base), AT, disp);
  3247         } else {
  3248           if (scale == 0) {
  3249             __ daddu(AT, as_Register(base), as_Register(index));
  3250           } else {
  3251             __ dsll(AT, as_Register(index), scale);
  3252             __ daddu(AT, as_Register(base), AT);
  3254           __ sdc1(src_reg, AT, disp);
  3256       } else {
  3257         if (scale == 0) {
  3258           __ daddu(AT, as_Register(base), as_Register(index));
  3259         } else {
  3260           __ dsll(AT, as_Register(index), scale);
  3261           __ daddu(AT, as_Register(base), AT);
  3263         __ move(T9, disp);
  3264         if( UseLoongsonISA ) {
  3265           __ gssdxc1(src_reg, AT, T9, 0);
  3266         } else {
  3267           __ addu(AT, AT, T9);
  3268           __ sdc1(src_reg, AT, 0);
  3271     } else {
  3272       if( Assembler::is_simm16(disp) ) {
  3273         __ sdc1(src_reg, as_Register(base), disp);
  3274       } else {
  3275         __ move(T9, disp);
  3276         if( UseLoongsonISA ) {
  3277           __ gssdxc1(src_reg, as_Register(base), T9, 0);
  3278         } else {
  3279           __ addu(AT, as_Register(base), T9);
  3280           __ sdc1(src_reg, AT, 0);
  3284   %}
  3286   enc_class Java_To_Runtime (method meth) %{    // CALL Java_To_Runtime, Java_To_Runtime_Leaf
  3287     MacroAssembler _masm(&cbuf);
  3288     // This is the instruction starting address for relocation info.
  3289     __ block_comment("Java_To_Runtime");
  3290     cbuf.set_insts_mark();
  3291     __ relocate(relocInfo::runtime_call_type);
  3293     __ patchable_call((address)$meth$$method);
  3294   %}
  3296   enc_class Java_Static_Call (method meth) %{    // JAVA STATIC CALL
  3297     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
  3298     // who we intended to call.
  3299     MacroAssembler _masm(&cbuf);
  3300     cbuf.set_insts_mark();
  3302     if ( !_method ) {
  3303       __ relocate(relocInfo::runtime_call_type);
  3304     } else if(_optimized_virtual) {
  3305       __ relocate(relocInfo::opt_virtual_call_type);
  3306     } else {
  3307       __ relocate(relocInfo::static_call_type);
  3310     __ patchable_call((address)($meth$$method));
  3311     if( _method ) {  // Emit stub for static call
  3312       emit_java_to_interp(cbuf);
  3314   %}
  3317   /*
  3318    * [Ref: LIR_Assembler::ic_call() ]
  3319    */
  3320   enc_class Java_Dynamic_Call (method meth) %{    // JAVA DYNAMIC CALL
  3321     MacroAssembler _masm(&cbuf);
  3322     __ block_comment("Java_Dynamic_Call");
  3323     __ ic_call((address)$meth$$method);
  3324   %}
  3327   enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
  3328     Register flags = $cr$$Register;
  3329     Label  L;
  3331     MacroAssembler _masm(&cbuf);
  3333     __ addu(flags, R0, R0);
  3334     __ beq(AT, R0, L);
  3335     __ delayed()->nop();
  3336     __ move(flags, 0xFFFFFFFF);
  3337     __ bind(L);
  3338   %}
  3340   enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
  3341     Register result = $result$$Register;
  3342     Register sub    = $sub$$Register;
  3343     Register super  = $super$$Register;
  3344     Register length = $tmp$$Register;
  3345     Register tmp    = T9;
  3346     Label miss;
  3348     /* 2012/9/28 Jin: result may be the same as sub
  3349      *    47c   B40: #    B21 B41 <- B20  Freq: 0.155379
  3350      *    47c     partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
  3351      *    4bc     mov   S2, NULL #@loadConP
  3352      *    4c0     beq   S1, S2, B21 #@branchConP  P=0.999999 C=-1.000000
  3353      */
  3354     MacroAssembler _masm(&cbuf);
  3355     Label done;
  3356     __ check_klass_subtype_slow_path(sub, super, length, tmp,
  3357         NULL, &miss,
  3358         /*set_cond_codes:*/ true);
  3359     /* 2013/7/22 Jin: Refer to X86_64's RDI */
  3360     __ move(result, 0);
  3361     __ b(done);
  3362     __ nop();
  3364     __ bind(miss);
  3365     __ move(result, 1);
  3366     __ bind(done);
  3367   %}
  3369 %}
  3372 //---------MIPS FRAME--------------------------------------------------------------
  3373 // Definition of frame structure and management information.
  3374 //
  3375 //  S T A C K   L A Y O U T    Allocators stack-slot number
  3376 //                             |   (to get allocators register number
  3377 //  G  Owned by    |        |  v    add SharedInfo::stack0)
  3378 //  r   CALLER     |        |
  3379 //  o     |        +--------+      pad to even-align allocators stack-slot
  3380 //  w     V        |  pad0  |        numbers; owned by CALLER
  3381 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
  3382 //  h     ^        |   in   |  5
  3383 //        |        |  args  |  4   Holes in incoming args owned by SELF
  3384 //  |     |    old |        |  3
  3385 //  |     |     SP-+--------+----> Matcher::_old_SP, even aligned
  3386 //  v     |        |  ret   |  3   return address
  3387 //     Owned by    +--------+
  3388 //      Self       |  pad2  |  2   pad to align old SP
  3389 //        |        +--------+  1
  3390 //        |        | locks  |  0
  3391 //        |        +--------+----> SharedInfo::stack0, even aligned
  3392 //        |        |  pad1  | 11   pad to align new SP
  3393 //        |        +--------+
  3394 //        |        |        | 10
  3395 //        |        | spills |  9   spills
  3396 //        V        |        |  8   (pad0 slot for callee)
  3397 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
  3398 //        ^        |  out   |  7
  3399 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
  3400 //   Owned by  new |        |
  3401 //    Callee    SP-+--------+----> Matcher::_new_SP, even aligned
  3402 //                  |        |
  3403 //
  3404 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
  3405 //         known from SELF's arguments and the Java calling convention.
  3406 //         Region 6-7 is determined per call site.
  3407 // Note 2: If the calling convention leaves holes in the incoming argument
  3408 //         area, those holes are owned by SELF.  Holes in the outgoing area
  3409 //         are owned by the CALLEE.  Holes should not be nessecary in the
  3410 //         incoming area, as the Java calling convention is completely under
  3411 //         the control of the AD file.  Doubles can be sorted and packed to
  3412 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
  3413 //         varargs C calling conventions.
  3414 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
  3415 //         even aligned with pad0 as needed.
  3416 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
  3417 //         region 6-11 is even aligned; it may be padded out more so that
  3418 //         the region from SP to FP meets the minimum stack alignment.
  3419 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
  3420 //         alignment.  Region 11, pad1, may be dynamically extended so that
  3421 //         SP meets the minimum alignment.
  3424 frame %{
  3426   stack_direction(TOWARDS_LOW);
  3428   // These two registers define part of the calling convention
  3429   // between compiled code and the interpreter.
  3430   // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
  3431   // for more information. by yjl 3/16/2006
  3433   inline_cache_reg(T1);                // Inline Cache Register
  3434   interpreter_method_oop_reg(S3);      // Method Oop Register when calling interpreter
  3436   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
  3437   cisc_spilling_operand_name(indOffset32);
  3439   // Number of stack slots consumed by locking an object
  3440   // generate Compile::sync_stack_slots
  3441 #ifdef _LP64
  3442   sync_stack_slots(2);
  3443 #else
  3444   sync_stack_slots(1);
  3445 #endif
  3447   frame_pointer(SP);
  3449   // Interpreter stores its frame pointer in a register which is
  3450   // stored to the stack by I2CAdaptors.
  3451   // I2CAdaptors convert from interpreted java to compiled java.
  3453   interpreter_frame_pointer(FP);
  3455   // generate Matcher::stack_alignment
  3456   stack_alignment(StackAlignmentInBytes);  //wordSize = sizeof(char*);
  3458   // Number of stack slots between incoming argument block and the start of
  3459   // a new frame.  The PROLOG must add this many slots to the stack.  The
  3460   // EPILOG must remove this many slots.  Intel needs one slot for
  3461   // return address.
  3462   // generate Matcher::in_preserve_stack_slots
  3463   //in_preserve_stack_slots(VerifyStackAtCalls + 2);  //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
  3464   in_preserve_stack_slots(4);  //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
  3466   // Number of outgoing stack slots killed above the out_preserve_stack_slots
  3467   // for calls to C.  Supports the var-args backing area for register parms.
  3468   varargs_C_out_slots_killed(0);
  3470   // The after-PROLOG location of the return address.  Location of
  3471   // return address specifies a type (REG or STACK) and a number
  3472   // representing the register number (i.e. - use a register name) or
  3473   // stack slot.
  3474   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
  3475   // Otherwise, it is above the locks and verification slot and alignment word
  3476   //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
  3477   return_addr(REG RA);
  3479   // Body of function which returns an integer array locating
  3480   // arguments either in registers or in stack slots.  Passed an array
  3481   // of ideal registers called "sig" and a "length" count.  Stack-slot
  3482   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  3483   // arguments for a CALLEE.  Incoming stack arguments are
  3484   // automatically biased by the preserve_stack_slots field above.
  3487   // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
  3488   // StartNode::calling_convention call this. by yjl 3/16/2006
  3489   calling_convention %{
  3490     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
  3491   %}
  3496   // Body of function which returns an integer array locating
  3497   // arguments either in registers or in stack slots.  Passed an array
  3498   // of ideal registers called "sig" and a "length" count.  Stack-slot
  3499   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  3500   // arguments for a CALLEE.  Incoming stack arguments are
  3501   // automatically biased by the preserve_stack_slots field above.
  3504   // SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
  3505   c_calling_convention %{
  3506    (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
  3507   %}
  3510   // Location of C & interpreter return values
  3511   // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
  3512   // SEE Matcher::match. by yjl 3/16/2006
  3513   c_return_value %{
  3514     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  3515                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  3516     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,    V0_num };
  3517     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,  V0_H_num };
  3518     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  3519   %}
  3521   // Location of return values
  3522   // register(s) contain(s) return value for Op_StartC2I and Op_Start.
  3523   // SEE Matcher::match. by yjl 3/16/2006
  3525   return_value %{
  3526     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  3527                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  3528     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,     V0_num };
  3529     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,   V0_H_num};
  3530     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  3531   %}
  3533 %}
  3535 //----------ATTRIBUTES---------------------------------------------------------
  3536 //----------Operand Attributes-------------------------------------------------
  3537 op_attrib op_cost(0);        // Required cost attribute
  3539 //----------Instruction Attributes---------------------------------------------
  3540 ins_attrib ins_cost(100);       // Required cost attribute
  3541 ins_attrib ins_size(32);         // Required size attribute (in bits)
  3542 ins_attrib ins_pc_relative(0);  // Required PC Relative flag
  3543 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
  3544                                 // non-matching short branch variant of some
  3545                                                             // long branch?
  3546 ins_attrib ins_alignment(4);    // Required alignment attribute (must be a power of 2)
  3547                                 // specifies the alignment that some part of the instruction (not
  3548                                 // necessarily the start) requires.  If > 1, a compute_padding()
  3549                                 // function must be provided for the instruction
  3551 //----------OPERANDS-----------------------------------------------------------
  3552 // Operand definitions must precede instruction definitions for correct parsing
  3553 // in the ADLC because operands constitute user defined types which are used in
  3554 // instruction definitions.
  3556 // Vectors
  3557 operand vecD() %{
  3558   constraint(ALLOC_IN_RC(dbl_reg));
  3559   match(VecD);
  3561   format %{ %}
  3562   interface(REG_INTER);
  3563 %}
  3565 // Flags register, used as output of compare instructions
  3566 operand FlagsReg() %{
  3567   constraint(ALLOC_IN_RC(mips_flags));
  3568   match(RegFlags);
  3570   format %{ "AT" %}
  3571   interface(REG_INTER);
  3572 %}
  3574 //----------Simple Operands----------------------------------------------------
  3575 //TODO: Should we need to define some more special immediate number ?
  3576 // Immediate Operands
  3577 // Integer Immediate
  3578 operand immI() %{
  3579   match(ConI);
  3580   //TODO: should not match immI8 here LEE
  3581   match(immI8);
  3583   op_cost(20);
  3584   format %{ %}
  3585   interface(CONST_INTER);
  3586 %}
  3588 // Long Immediate 8-bit
  3589 operand immL8()
  3590 %{
  3591   predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
  3592   match(ConL);
  3594   op_cost(5);
  3595   format %{ %}
  3596   interface(CONST_INTER);
  3597 %}
  3599 // Constant for test vs zero
  3600 operand immI0() %{
  3601   predicate(n->get_int() == 0);
  3602   match(ConI);
  3604   op_cost(0);
  3605   format %{ %}
  3606   interface(CONST_INTER);
  3607 %}
  3609 // Constant for increment
  3610 operand immI1() %{
  3611   predicate(n->get_int() == 1);
  3612   match(ConI);
  3614   op_cost(0);
  3615   format %{ %}
  3616   interface(CONST_INTER);
  3617 %}
  3619 // Constant for decrement
  3620 operand immI_M1() %{
  3621   predicate(n->get_int() == -1);
  3622   match(ConI);
  3624   op_cost(0);
  3625   format %{ %}
  3626   interface(CONST_INTER);
  3627 %}
  3629 operand immI_MaxI() %{
  3630   predicate(n->get_int() == 2147483647);
  3631   match(ConI);
  3633   op_cost(0);
  3634   format %{ %}
  3635   interface(CONST_INTER);
  3636 %}
  3638 // Valid scale values for addressing modes
  3639 operand immI2() %{
  3640   predicate(0 <= n->get_int() && (n->get_int() <= 3));
  3641   match(ConI);
  3643   format %{ %}
  3644   interface(CONST_INTER);
  3645 %}
  3647 operand immI8() %{
  3648   predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
  3649   match(ConI);
  3651   op_cost(5);
  3652   format %{ %}
  3653   interface(CONST_INTER);
  3654 %}
  3656 operand immI16() %{
  3657   predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
  3658   match(ConI);
  3660   op_cost(10);
  3661   format %{ %}
  3662   interface(CONST_INTER);
  3663 %}
  3665 // Constant for long shifts
  3666 operand immI_32() %{
  3667   predicate( n->get_int() == 32 );
  3668   match(ConI);
  3670   op_cost(0);
  3671   format %{ %}
  3672   interface(CONST_INTER);
  3673 %}
  3675 operand immI_63() %{
  3676   predicate( n->get_int() == 63 );
  3677   match(ConI);
  3679   op_cost(0);
  3680   format %{ %}
  3681   interface(CONST_INTER);
  3682 %}
  3684 operand immI_0_31() %{
  3685   predicate( n->get_int() >= 0 && n->get_int() <= 31 );
  3686   match(ConI);
  3688   op_cost(0);
  3689   format %{ %}
  3690   interface(CONST_INTER);
  3691 %}
  3693 // Operand for non-negtive integer mask
  3694 operand immI_nonneg_mask() %{
  3695   predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
  3696   match(ConI);
  3698   op_cost(0);
  3699   format %{ %}
  3700   interface(CONST_INTER);
  3701 %}
  3703 operand immI_32_63() %{
  3704   predicate( n->get_int() >= 32 && n->get_int() <= 63 );
  3705   match(ConI);
  3706   op_cost(0);
  3708   format %{ %}
  3709   interface(CONST_INTER);
  3710 %}
  3712 operand immI16_sub() %{
  3713   predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
  3714   match(ConI);
  3716   op_cost(10);
  3717   format %{ %}
  3718   interface(CONST_INTER);
  3719 %}
  3721 operand immI_0_32767() %{
  3722   predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
  3723   match(ConI);
  3724   op_cost(0);
  3726   format %{ %}
  3727   interface(CONST_INTER);
  3728 %}
  3730 operand immI_0_65535() %{
  3731   predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
  3732   match(ConI);
  3733   op_cost(0);
  3735   format %{ %}
  3736   interface(CONST_INTER);
  3737 %}
  3739 operand immI_1() %{
  3740   predicate( n->get_int() == 1 );
  3741   match(ConI);
  3743   op_cost(0);
  3744   format %{ %}
  3745   interface(CONST_INTER);
  3746 %}
  3748 operand immI_2() %{
  3749   predicate( n->get_int() == 2 );
  3750   match(ConI);
  3752   op_cost(0);
  3753   format %{ %}
  3754   interface(CONST_INTER);
  3755 %}
  3757 operand immI_3() %{
  3758   predicate( n->get_int() == 3 );
  3759   match(ConI);
  3761   op_cost(0);
  3762   format %{ %}
  3763   interface(CONST_INTER);
  3764 %}
  3766 operand immI_7() %{
  3767   predicate( n->get_int() == 7 );
  3768   match(ConI);
  3770   format %{ %}
  3771   interface(CONST_INTER);
  3772 %}
  3774 // Immediates for special shifts (sign extend)
  3776 // Constants for increment
  3777 operand immI_16() %{
  3778   predicate( n->get_int() == 16 );
  3779   match(ConI);
  3781   format %{ %}
  3782   interface(CONST_INTER);
  3783 %}
  3785 operand immI_24() %{
  3786   predicate( n->get_int() == 24 );
  3787   match(ConI);
  3789   format %{ %}
  3790   interface(CONST_INTER);
  3791 %}
  3793 // Constant for byte-wide masking
  3794 operand immI_255() %{
  3795   predicate( n->get_int() == 255 );
  3796   match(ConI);
  3798   op_cost(0);
  3799   format %{ %}
  3800   interface(CONST_INTER);
  3801 %}
  3803 operand immI_65535() %{
  3804   predicate( n->get_int() == 65535 );
  3805   match(ConI);
  3807   op_cost(5);
  3808   format %{ %}
  3809   interface(CONST_INTER);
  3810 %}
  3812 operand immI_65536() %{
  3813   predicate( n->get_int() == 65536 );
  3814   match(ConI);
  3816   op_cost(5);
  3817   format %{ %}
  3818   interface(CONST_INTER);
  3819 %}
  3821 operand immI_M65536() %{
  3822   predicate( n->get_int() == -65536 );
  3823   match(ConI);
  3825   op_cost(5);
  3826   format %{ %}
  3827   interface(CONST_INTER);
  3828 %}
  3830 // Pointer Immediate
  3831 operand immP() %{
  3832   match(ConP);
  3834   op_cost(10);
  3835   format %{ %}
  3836   interface(CONST_INTER);
  3837 %}
  3839 // NULL Pointer Immediate
  3840 operand immP0() %{
  3841   predicate( n->get_ptr() == 0 );
  3842   match(ConP);
  3843   op_cost(0);
  3845   format %{ %}
  3846   interface(CONST_INTER);
  3847 %}
  3849 // Pointer Immediate: 64-bit
  3850 operand immP_set() %{
  3851   match(ConP);
  3853   op_cost(5);
  3854   // formats are generated automatically for constants and base registers
  3855   format %{ %}
  3856   interface(CONST_INTER);
  3857 %}
  3859 // Pointer Immediate: 64-bit
  3860 operand immP_load() %{
  3861   predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
  3862   match(ConP);
  3864   op_cost(5);
  3865   // formats are generated automatically for constants and base registers
  3866   format %{ %}
  3867   interface(CONST_INTER);
  3868 %}
  3870 // Pointer Immediate: 64-bit
  3871 operand immP_no_oop_cheap() %{
  3872   predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
  3873   match(ConP);
  3875   op_cost(5);
  3876   // formats are generated automatically for constants and base registers
  3877   format %{ %}
  3878   interface(CONST_INTER);
  3879 %}
  3881 // Pointer for polling page
  3882 operand immP_poll() %{
  3883   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
  3884   match(ConP);
  3885   op_cost(5);
  3887   format %{ %}
  3888   interface(CONST_INTER);
  3889 %}
  3891 // Pointer Immediate
  3892 operand immN() %{
  3893   match(ConN);
  3895   op_cost(10);
  3896   format %{ %}
  3897   interface(CONST_INTER);
  3898 %}
  3900 operand immNKlass() %{
  3901   match(ConNKlass);
  3903   op_cost(10);
  3904   format %{ %}
  3905   interface(CONST_INTER);
  3906 %}
  3908 // NULL Pointer Immediate
  3909 operand immN0() %{
  3910   predicate(n->get_narrowcon() == 0);
  3911   match(ConN);
  3913   op_cost(5);
  3914   format %{ %}
  3915   interface(CONST_INTER);
  3916 %}
  3918 // Long Immediate
  3919 operand immL() %{
  3920   match(ConL);
  3922   op_cost(20);
  3923   format %{ %}
  3924   interface(CONST_INTER);
  3925 %}
  3927 // Long Immediate zero
  3928 operand immL0() %{
  3929   predicate( n->get_long() == 0L );
  3930   match(ConL);
  3931   op_cost(0);
  3933   format %{ %}
  3934   interface(CONST_INTER);
  3935 %}
  3937 operand immL7() %{
  3938   predicate( n->get_long() == 7L );
  3939   match(ConL);
  3940   op_cost(0);
  3942   format %{ %}
  3943   interface(CONST_INTER);
  3944 %}
  3946 operand immL_M1() %{
  3947   predicate( n->get_long() == -1L );
  3948   match(ConL);
  3949   op_cost(0);
  3951   format %{ %}
  3952   interface(CONST_INTER);
  3953 %}
  3955 // bit 0..2 zero
  3956 operand immL_M8() %{
  3957   predicate( n->get_long() == -8L );
  3958   match(ConL);
  3959   op_cost(0);
  3961   format %{ %}
  3962   interface(CONST_INTER);
  3963 %}
  3965 // bit 2 zero
  3966 operand immL_M5() %{
  3967   predicate( n->get_long() == -5L );
  3968   match(ConL);
  3969   op_cost(0);
  3971   format %{ %}
  3972   interface(CONST_INTER);
  3973 %}
  3975 // bit 1..2 zero
  3976 operand immL_M7() %{
  3977   predicate( n->get_long() == -7L );
  3978   match(ConL);
  3979   op_cost(0);
  3981   format %{ %}
  3982   interface(CONST_INTER);
  3983 %}
  3985 // bit 0..1 zero
  3986 operand immL_M4() %{
  3987   predicate( n->get_long() == -4L );
  3988   match(ConL);
  3989   op_cost(0);
  3991   format %{ %}
  3992   interface(CONST_INTER);
  3993 %}
  3995 // bit 3..6 zero
  3996 operand immL_M121() %{
  3997   predicate( n->get_long() == -121L );
  3998   match(ConL);
  3999   op_cost(0);
  4001   format %{ %}
  4002   interface(CONST_INTER);
  4003 %}
  4005 // Long immediate from 0 to 127.
  4006 // Used for a shorter form of long mul by 10.
  4007 operand immL_127() %{
  4008   predicate((0 <= n->get_long()) && (n->get_long() <= 127));
  4009   match(ConL);
  4010   op_cost(0);
  4012   format %{ %}
  4013   interface(CONST_INTER);
  4014 %}
  4016 // Operand for non-negtive long mask
  4017 operand immL_nonneg_mask() %{
  4018   predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
  4019   match(ConL);
  4021   op_cost(0);
  4022   format %{ %}
  4023   interface(CONST_INTER);
  4024 %}
  4026 operand immL_0_65535() %{
  4027   predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
  4028   match(ConL);
  4029   op_cost(0);
  4031   format %{ %}
  4032   interface(CONST_INTER);
  4033 %}
  4035 // Long Immediate: cheap (materialize in <= 3 instructions)
  4036 operand immL_cheap() %{
  4037   predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
  4038   match(ConL);
  4039   op_cost(0);
  4041   format %{ %}
  4042   interface(CONST_INTER);
  4043 %}
  4045 // Long Immediate: expensive (materialize in > 3 instructions)
  4046 operand immL_expensive() %{
  4047   predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
  4048   match(ConL);
  4049   op_cost(0);
  4051   format %{ %}
  4052   interface(CONST_INTER);
  4053 %}
  4055 operand immL16() %{
  4056   predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
  4057   match(ConL);
  4059   op_cost(10);
  4060   format %{ %}
  4061   interface(CONST_INTER);
  4062 %}
  4064 operand immL16_sub() %{
  4065   predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
  4066   match(ConL);
  4068   op_cost(10);
  4069   format %{ %}
  4070   interface(CONST_INTER);
  4071 %}
  4073 // Long Immediate: low 32-bit mask
  4074 operand immL_32bits() %{
  4075   predicate(n->get_long() == 0xFFFFFFFFL);
  4076   match(ConL);
  4077   op_cost(20);
  4079   format %{ %}
  4080   interface(CONST_INTER);
  4081 %}
  4083 // Long Immediate 32-bit signed
  4084 operand immL32()
  4085 %{
  4086   predicate(n->get_long() == (int) (n->get_long()));
  4087   match(ConL);
  4089   op_cost(15);
  4090   format %{ %}
  4091   interface(CONST_INTER);
  4092 %}
  4095 //single-precision floating-point zero
  4096 operand immF0() %{
  4097   predicate(jint_cast(n->getf()) == 0);
  4098   match(ConF);
  4100   op_cost(5);
  4101   format %{ %}
  4102   interface(CONST_INTER);
  4103 %}
  4105 //single-precision floating-point immediate
  4106 operand immF() %{
  4107   match(ConF);
  4109   op_cost(20);
  4110   format %{ %}
  4111   interface(CONST_INTER);
  4112 %}
  4114 //double-precision floating-point zero
  4115 operand immD0() %{
  4116   predicate(jlong_cast(n->getd()) == 0);
  4117   match(ConD);
  4119   op_cost(5);
  4120   format %{ %}
  4121   interface(CONST_INTER);
  4122 %}
  4124 //double-precision floating-point immediate
  4125 operand immD() %{
  4126   match(ConD);
  4128   op_cost(20);
  4129   format %{ %}
  4130   interface(CONST_INTER);
  4131 %}
  4133 // Register Operands
  4134 // Integer Register
  4135 operand mRegI() %{
  4136   constraint(ALLOC_IN_RC(int_reg));
  4137   match(RegI);
  4139   format %{ %}
  4140   interface(REG_INTER);
  4141 %}
  4143 operand no_Ax_mRegI() %{
  4144   constraint(ALLOC_IN_RC(no_Ax_int_reg));
  4145   match(RegI);
  4146   match(mRegI);
  4148   format %{  %}
  4149   interface(REG_INTER);
  4150 %}
  4152 operand mS0RegI() %{
  4153   constraint(ALLOC_IN_RC(s0_reg));
  4154   match(RegI);
  4155   match(mRegI);
  4157   format %{ "S0" %}
  4158   interface(REG_INTER);
  4159 %}
  4161 operand mS1RegI() %{
  4162   constraint(ALLOC_IN_RC(s1_reg));
  4163   match(RegI);
  4164   match(mRegI);
  4166   format %{ "S1" %}
  4167   interface(REG_INTER);
  4168 %}
  4170 operand mS2RegI() %{
  4171   constraint(ALLOC_IN_RC(s2_reg));
  4172   match(RegI);
  4173   match(mRegI);
  4175   format %{ "S2" %}
  4176   interface(REG_INTER);
  4177 %}
  4179 operand mS3RegI() %{
  4180   constraint(ALLOC_IN_RC(s3_reg));
  4181   match(RegI);
  4182   match(mRegI);
  4184   format %{ "S3" %}
  4185   interface(REG_INTER);
  4186 %}
  4188 operand mS4RegI() %{
  4189   constraint(ALLOC_IN_RC(s4_reg));
  4190   match(RegI);
  4191   match(mRegI);
  4193   format %{ "S4" %}
  4194   interface(REG_INTER);
  4195 %}
  4197 operand mS5RegI() %{
  4198   constraint(ALLOC_IN_RC(s5_reg));
  4199   match(RegI);
  4200   match(mRegI);
  4202   format %{ "S5" %}
  4203   interface(REG_INTER);
  4204 %}
  4206 operand mS6RegI() %{
  4207   constraint(ALLOC_IN_RC(s6_reg));
  4208   match(RegI);
  4209   match(mRegI);
  4211   format %{ "S6" %}
  4212   interface(REG_INTER);
  4213 %}
  4215 operand mS7RegI() %{
  4216   constraint(ALLOC_IN_RC(s7_reg));
  4217   match(RegI);
  4218   match(mRegI);
  4220   format %{ "S7" %}
  4221   interface(REG_INTER);
  4222 %}
  4225 operand mT0RegI() %{
  4226   constraint(ALLOC_IN_RC(t0_reg));
  4227   match(RegI);
  4228   match(mRegI);
  4230   format %{ "T0" %}
  4231   interface(REG_INTER);
  4232 %}
  4234 operand mT1RegI() %{
  4235   constraint(ALLOC_IN_RC(t1_reg));
  4236   match(RegI);
  4237   match(mRegI);
  4239   format %{ "T1" %}
  4240   interface(REG_INTER);
  4241 %}
  4243 operand mT2RegI() %{
  4244   constraint(ALLOC_IN_RC(t2_reg));
  4245   match(RegI);
  4246   match(mRegI);
  4248   format %{ "T2" %}
  4249   interface(REG_INTER);
  4250 %}
  4252 operand mT3RegI() %{
  4253   constraint(ALLOC_IN_RC(t3_reg));
  4254   match(RegI);
  4255   match(mRegI);
  4257   format %{ "T3" %}
  4258   interface(REG_INTER);
  4259 %}
  4261 operand mT8RegI() %{
  4262   constraint(ALLOC_IN_RC(t8_reg));
  4263   match(RegI);
  4264   match(mRegI);
  4266   format %{ "T8" %}
  4267   interface(REG_INTER);
  4268 %}
  4270 operand mT9RegI() %{
  4271   constraint(ALLOC_IN_RC(t9_reg));
  4272   match(RegI);
  4273   match(mRegI);
  4275   format %{ "T9" %}
  4276   interface(REG_INTER);
  4277 %}
  4279 operand mA0RegI() %{
  4280   constraint(ALLOC_IN_RC(a0_reg));
  4281   match(RegI);
  4282   match(mRegI);
  4284   format %{ "A0" %}
  4285   interface(REG_INTER);
  4286 %}
  4288 operand mA1RegI() %{
  4289   constraint(ALLOC_IN_RC(a1_reg));
  4290   match(RegI);
  4291   match(mRegI);
  4293   format %{ "A1" %}
  4294   interface(REG_INTER);
  4295 %}
  4297 operand mA2RegI() %{
  4298   constraint(ALLOC_IN_RC(a2_reg));
  4299   match(RegI);
  4300   match(mRegI);
  4302   format %{ "A2" %}
  4303   interface(REG_INTER);
  4304 %}
  4306 operand mA3RegI() %{
  4307   constraint(ALLOC_IN_RC(a3_reg));
  4308   match(RegI);
  4309   match(mRegI);
  4311   format %{ "A3" %}
  4312   interface(REG_INTER);
  4313 %}
  4315 operand mA4RegI() %{
  4316   constraint(ALLOC_IN_RC(a4_reg));
  4317   match(RegI);
  4318   match(mRegI);
  4320   format %{ "A4" %}
  4321   interface(REG_INTER);
  4322 %}
  4324 operand mA5RegI() %{
  4325   constraint(ALLOC_IN_RC(a5_reg));
  4326   match(RegI);
  4327   match(mRegI);
  4329   format %{ "A5" %}
  4330   interface(REG_INTER);
  4331 %}
  4333 operand mA6RegI() %{
  4334   constraint(ALLOC_IN_RC(a6_reg));
  4335   match(RegI);
  4336   match(mRegI);
  4338   format %{ "A6" %}
  4339   interface(REG_INTER);
  4340 %}
  4342 operand mA7RegI() %{
  4343   constraint(ALLOC_IN_RC(a7_reg));
  4344   match(RegI);
  4345   match(mRegI);
  4347   format %{ "A7" %}
  4348   interface(REG_INTER);
  4349 %}
  4351 operand mV0RegI() %{
  4352   constraint(ALLOC_IN_RC(v0_reg));
  4353   match(RegI);
  4354   match(mRegI);
  4356   format %{ "V0" %}
  4357   interface(REG_INTER);
  4358 %}
  4360 operand mV1RegI() %{
  4361   constraint(ALLOC_IN_RC(v1_reg));
  4362   match(RegI);
  4363   match(mRegI);
  4365   format %{ "V1" %}
  4366   interface(REG_INTER);
  4367 %}
  4369 operand mRegN() %{
  4370   constraint(ALLOC_IN_RC(int_reg));
  4371   match(RegN);
  4373   format %{ %}
  4374   interface(REG_INTER);
  4375 %}
  4377 operand t0_RegN() %{
  4378   constraint(ALLOC_IN_RC(t0_reg));
  4379   match(RegN);
  4380   match(mRegN);
  4382   format %{ %}
  4383   interface(REG_INTER);
  4384 %}
  4386 operand t1_RegN() %{
  4387   constraint(ALLOC_IN_RC(t1_reg));
  4388   match(RegN);
  4389   match(mRegN);
  4391   format %{ %}
  4392   interface(REG_INTER);
  4393 %}
  4395 operand t2_RegN() %{
  4396   constraint(ALLOC_IN_RC(t2_reg));
  4397   match(RegN);
  4398   match(mRegN);
  4400   format %{ %}
  4401   interface(REG_INTER);
  4402 %}
  4404 operand t3_RegN() %{
  4405   constraint(ALLOC_IN_RC(t3_reg));
  4406   match(RegN);
  4407   match(mRegN);
  4409   format %{ %}
  4410   interface(REG_INTER);
  4411 %}
  4413 operand t8_RegN() %{
  4414   constraint(ALLOC_IN_RC(t8_reg));
  4415   match(RegN);
  4416   match(mRegN);
  4418   format %{ %}
  4419   interface(REG_INTER);
  4420 %}
  4422 operand t9_RegN() %{
  4423   constraint(ALLOC_IN_RC(t9_reg));
  4424   match(RegN);
  4425   match(mRegN);
  4427   format %{ %}
  4428   interface(REG_INTER);
  4429 %}
  4431 operand a0_RegN() %{
  4432   constraint(ALLOC_IN_RC(a0_reg));
  4433   match(RegN);
  4434   match(mRegN);
  4436   format %{ %}
  4437   interface(REG_INTER);
  4438 %}
  4440 operand a1_RegN() %{
  4441   constraint(ALLOC_IN_RC(a1_reg));
  4442   match(RegN);
  4443   match(mRegN);
  4445   format %{ %}
  4446   interface(REG_INTER);
  4447 %}
  4449 operand a2_RegN() %{
  4450   constraint(ALLOC_IN_RC(a2_reg));
  4451   match(RegN);
  4452   match(mRegN);
  4454   format %{ %}
  4455   interface(REG_INTER);
  4456 %}
  4458 operand a3_RegN() %{
  4459   constraint(ALLOC_IN_RC(a3_reg));
  4460   match(RegN);
  4461   match(mRegN);
  4463   format %{ %}
  4464   interface(REG_INTER);
  4465 %}
  4467 operand a4_RegN() %{
  4468   constraint(ALLOC_IN_RC(a4_reg));
  4469   match(RegN);
  4470   match(mRegN);
  4472   format %{ %}
  4473   interface(REG_INTER);
  4474 %}
  4476 operand a5_RegN() %{
  4477   constraint(ALLOC_IN_RC(a5_reg));
  4478   match(RegN);
  4479   match(mRegN);
  4481   format %{ %}
  4482   interface(REG_INTER);
  4483 %}
  4485 operand a6_RegN() %{
  4486   constraint(ALLOC_IN_RC(a6_reg));
  4487   match(RegN);
  4488   match(mRegN);
  4490   format %{ %}
  4491   interface(REG_INTER);
  4492 %}
  4494 operand a7_RegN() %{
  4495   constraint(ALLOC_IN_RC(a7_reg));
  4496   match(RegN);
  4497   match(mRegN);
  4499   format %{ %}
  4500   interface(REG_INTER);
  4501 %}
  4503 operand s0_RegN() %{
  4504   constraint(ALLOC_IN_RC(s0_reg));
  4505   match(RegN);
  4506   match(mRegN);
  4508   format %{ %}
  4509   interface(REG_INTER);
  4510 %}
  4512 operand s1_RegN() %{
  4513   constraint(ALLOC_IN_RC(s1_reg));
  4514   match(RegN);
  4515   match(mRegN);
  4517   format %{ %}
  4518   interface(REG_INTER);
  4519 %}
  4521 operand s2_RegN() %{
  4522   constraint(ALLOC_IN_RC(s2_reg));
  4523   match(RegN);
  4524   match(mRegN);
  4526   format %{ %}
  4527   interface(REG_INTER);
  4528 %}
  4530 operand s3_RegN() %{
  4531   constraint(ALLOC_IN_RC(s3_reg));
  4532   match(RegN);
  4533   match(mRegN);
  4535   format %{ %}
  4536   interface(REG_INTER);
  4537 %}
  4539 operand s4_RegN() %{
  4540   constraint(ALLOC_IN_RC(s4_reg));
  4541   match(RegN);
  4542   match(mRegN);
  4544   format %{ %}
  4545   interface(REG_INTER);
  4546 %}
  4548 operand s5_RegN() %{
  4549   constraint(ALLOC_IN_RC(s5_reg));
  4550   match(RegN);
  4551   match(mRegN);
  4553   format %{ %}
  4554   interface(REG_INTER);
  4555 %}
  4557 operand s6_RegN() %{
  4558   constraint(ALLOC_IN_RC(s6_reg));
  4559   match(RegN);
  4560   match(mRegN);
  4562   format %{ %}
  4563   interface(REG_INTER);
  4564 %}
  4566 operand s7_RegN() %{
  4567   constraint(ALLOC_IN_RC(s7_reg));
  4568   match(RegN);
  4569   match(mRegN);
  4571   format %{ %}
  4572   interface(REG_INTER);
  4573 %}
  4575 operand v0_RegN() %{
  4576   constraint(ALLOC_IN_RC(v0_reg));
  4577   match(RegN);
  4578   match(mRegN);
  4580   format %{ %}
  4581   interface(REG_INTER);
  4582 %}
  4584 operand v1_RegN() %{
  4585   constraint(ALLOC_IN_RC(v1_reg));
  4586   match(RegN);
  4587   match(mRegN);
  4589   format %{ %}
  4590   interface(REG_INTER);
  4591 %}
  4593 // Pointer Register
  4594 operand mRegP() %{
  4595   constraint(ALLOC_IN_RC(p_reg));
  4596   match(RegP);
  4598   format %{  %}
  4599   interface(REG_INTER);
  4600 %}
  4602 operand no_T8_mRegP() %{
  4603   constraint(ALLOC_IN_RC(no_T8_p_reg));
  4604   match(RegP);
  4605   match(mRegP);
  4607   format %{  %}
  4608   interface(REG_INTER);
  4609 %}
  4611 operand s0_RegP()
  4612 %{
  4613   constraint(ALLOC_IN_RC(s0_long_reg));
  4614   match(RegP);
  4615   match(mRegP);
  4616   match(no_T8_mRegP);
  4618   format %{ %}
  4619   interface(REG_INTER);
  4620 %}
  4622 operand s1_RegP()
  4623 %{
  4624   constraint(ALLOC_IN_RC(s1_long_reg));
  4625   match(RegP);
  4626   match(mRegP);
  4627   match(no_T8_mRegP);
  4629   format %{ %}
  4630   interface(REG_INTER);
  4631 %}
  4633 operand s2_RegP()
  4634 %{
  4635   constraint(ALLOC_IN_RC(s2_long_reg));
  4636   match(RegP);
  4637   match(mRegP);
  4638   match(no_T8_mRegP);
  4640   format %{ %}
  4641   interface(REG_INTER);
  4642 %}
  4644 operand s3_RegP()
  4645 %{
  4646   constraint(ALLOC_IN_RC(s3_long_reg));
  4647   match(RegP);
  4648   match(mRegP);
  4649   match(no_T8_mRegP);
  4651   format %{ %}
  4652   interface(REG_INTER);
  4653 %}
  4655 operand s4_RegP()
  4656 %{
  4657   constraint(ALLOC_IN_RC(s4_long_reg));
  4658   match(RegP);
  4659   match(mRegP);
  4660   match(no_T8_mRegP);
  4662   format %{ %}
  4663   interface(REG_INTER);
  4664 %}
  4666 operand s5_RegP()
  4667 %{
  4668   constraint(ALLOC_IN_RC(s5_long_reg));
  4669   match(RegP);
  4670   match(mRegP);
  4671   match(no_T8_mRegP);
  4673   format %{ %}
  4674   interface(REG_INTER);
  4675 %}
  4677 operand s6_RegP()
  4678 %{
  4679   constraint(ALLOC_IN_RC(s6_long_reg));
  4680   match(RegP);
  4681   match(mRegP);
  4682   match(no_T8_mRegP);
  4684   format %{ %}
  4685   interface(REG_INTER);
  4686 %}
  4688 operand s7_RegP()
  4689 %{
  4690   constraint(ALLOC_IN_RC(s7_long_reg));
  4691   match(RegP);
  4692   match(mRegP);
  4693   match(no_T8_mRegP);
  4695   format %{ %}
  4696   interface(REG_INTER);
  4697 %}
  4699 operand t0_RegP()
  4700 %{
  4701   constraint(ALLOC_IN_RC(t0_long_reg));
  4702   match(RegP);
  4703   match(mRegP);
  4704   match(no_T8_mRegP);
  4706   format %{ %}
  4707   interface(REG_INTER);
  4708 %}
  4710 operand t1_RegP()
  4711 %{
  4712   constraint(ALLOC_IN_RC(t1_long_reg));
  4713   match(RegP);
  4714   match(mRegP);
  4715   match(no_T8_mRegP);
  4717   format %{ %}
  4718   interface(REG_INTER);
  4719 %}
  4721 operand t2_RegP()
  4722 %{
  4723   constraint(ALLOC_IN_RC(t2_long_reg));
  4724   match(RegP);
  4725   match(mRegP);
  4726   match(no_T8_mRegP);
  4728   format %{ %}
  4729   interface(REG_INTER);
  4730 %}
  4732 operand t3_RegP()
  4733 %{
  4734   constraint(ALLOC_IN_RC(t3_long_reg));
  4735   match(RegP);
  4736   match(mRegP);
  4737   match(no_T8_mRegP);
  4739   format %{ %}
  4740   interface(REG_INTER);
  4741 %}
  4743 operand t8_RegP()
  4744 %{
  4745   constraint(ALLOC_IN_RC(t8_long_reg));
  4746   match(RegP);
  4747   match(mRegP);
  4749   format %{ %}
  4750   interface(REG_INTER);
  4751 %}
  4753 operand t9_RegP()
  4754 %{
  4755   constraint(ALLOC_IN_RC(t9_long_reg));
  4756   match(RegP);
  4757   match(mRegP);
  4758   match(no_T8_mRegP);
  4760   format %{ %}
  4761   interface(REG_INTER);
  4762 %}
  4764 operand a0_RegP()
  4765 %{
  4766   constraint(ALLOC_IN_RC(a0_long_reg));
  4767   match(RegP);
  4768   match(mRegP);
  4769   match(no_T8_mRegP);
  4771   format %{ %}
  4772   interface(REG_INTER);
  4773 %}
  4775 operand a1_RegP()
  4776 %{
  4777   constraint(ALLOC_IN_RC(a1_long_reg));
  4778   match(RegP);
  4779   match(mRegP);
  4780   match(no_T8_mRegP);
  4782   format %{ %}
  4783   interface(REG_INTER);
  4784 %}
  4786 operand a2_RegP()
  4787 %{
  4788   constraint(ALLOC_IN_RC(a2_long_reg));
  4789   match(RegP);
  4790   match(mRegP);
  4791   match(no_T8_mRegP);
  4793   format %{ %}
  4794   interface(REG_INTER);
  4795 %}
  4797 operand a3_RegP()
  4798 %{
  4799   constraint(ALLOC_IN_RC(a3_long_reg));
  4800   match(RegP);
  4801   match(mRegP);
  4802   match(no_T8_mRegP);
  4804   format %{ %}
  4805   interface(REG_INTER);
  4806 %}
  4808 operand a4_RegP()
  4809 %{
  4810   constraint(ALLOC_IN_RC(a4_long_reg));
  4811   match(RegP);
  4812   match(mRegP);
  4813   match(no_T8_mRegP);
  4815   format %{ %}
  4816   interface(REG_INTER);
  4817 %}
  4820 operand a5_RegP()
  4821 %{
  4822   constraint(ALLOC_IN_RC(a5_long_reg));
  4823   match(RegP);
  4824   match(mRegP);
  4825   match(no_T8_mRegP);
  4827   format %{ %}
  4828   interface(REG_INTER);
  4829 %}
  4831 operand a6_RegP()
  4832 %{
  4833   constraint(ALLOC_IN_RC(a6_long_reg));
  4834   match(RegP);
  4835   match(mRegP);
  4836   match(no_T8_mRegP);
  4838   format %{ %}
  4839   interface(REG_INTER);
  4840 %}
  4842 operand a7_RegP()
  4843 %{
  4844   constraint(ALLOC_IN_RC(a7_long_reg));
  4845   match(RegP);
  4846   match(mRegP);
  4847   match(no_T8_mRegP);
  4849   format %{ %}
  4850   interface(REG_INTER);
  4851 %}
  4853 operand v0_RegP()
  4854 %{
  4855   constraint(ALLOC_IN_RC(v0_long_reg));
  4856   match(RegP);
  4857   match(mRegP);
  4858   match(no_T8_mRegP);
  4860   format %{ %}
  4861   interface(REG_INTER);
  4862 %}
  4864 operand v1_RegP()
  4865 %{
  4866   constraint(ALLOC_IN_RC(v1_long_reg));
  4867   match(RegP);
  4868   match(mRegP);
  4869   match(no_T8_mRegP);
  4871   format %{ %}
  4872   interface(REG_INTER);
  4873 %}
  4875 /*
  4876 operand mSPRegP(mRegP reg) %{
  4877   constraint(ALLOC_IN_RC(sp_reg));
  4878   match(reg);
  4880   format %{ "SP"  %}
  4881   interface(REG_INTER);
  4882 %}
  4884 operand mFPRegP(mRegP reg) %{
  4885   constraint(ALLOC_IN_RC(fp_reg));
  4886   match(reg);
  4888   format %{ "FP"  %}
  4889   interface(REG_INTER);
  4890 %}
  4891 */
  4893 operand mRegL() %{
  4894   constraint(ALLOC_IN_RC(long_reg));
  4895   match(RegL);
  4897   format %{ %}
  4898   interface(REG_INTER);
  4899 %}
  4901 operand v0RegL() %{
  4902   constraint(ALLOC_IN_RC(v0_long_reg));
  4903   match(RegL);
  4904   match(mRegL);
  4906   format %{ %}
  4907   interface(REG_INTER);
  4908 %}
  4910 operand v1RegL() %{
  4911   constraint(ALLOC_IN_RC(v1_long_reg));
  4912   match(RegL);
  4913   match(mRegL);
  4915   format %{ %}
  4916   interface(REG_INTER);
  4917 %}
  4919 operand a0RegL() %{
  4920   constraint(ALLOC_IN_RC(a0_long_reg));
  4921   match(RegL);
  4922   match(mRegL);
  4924   format %{ "A0" %}
  4925   interface(REG_INTER);
  4926 %}
  4928 operand a1RegL() %{
  4929   constraint(ALLOC_IN_RC(a1_long_reg));
  4930   match(RegL);
  4931   match(mRegL);
  4933   format %{ %}
  4934   interface(REG_INTER);
  4935 %}
  4937 operand a2RegL() %{
  4938   constraint(ALLOC_IN_RC(a2_long_reg));
  4939   match(RegL);
  4940   match(mRegL);
  4942   format %{ %}
  4943   interface(REG_INTER);
  4944 %}
  4946 operand a3RegL() %{
  4947   constraint(ALLOC_IN_RC(a3_long_reg));
  4948   match(RegL);
  4949   match(mRegL);
  4951   format %{ %}
  4952   interface(REG_INTER);
  4953 %}
  4955 operand t0RegL() %{
  4956   constraint(ALLOC_IN_RC(t0_long_reg));
  4957   match(RegL);
  4958   match(mRegL);
  4960   format %{ %}
  4961   interface(REG_INTER);
  4962 %}
  4964 operand t1RegL() %{
  4965   constraint(ALLOC_IN_RC(t1_long_reg));
  4966   match(RegL);
  4967   match(mRegL);
  4969   format %{ %}
  4970   interface(REG_INTER);
  4971 %}
  4973 operand t2RegL() %{
  4974   constraint(ALLOC_IN_RC(t2_long_reg));
  4975   match(RegL);
  4976   match(mRegL);
  4978   format %{ %}
  4979   interface(REG_INTER);
  4980 %}
  4982 operand t3RegL() %{
  4983   constraint(ALLOC_IN_RC(t3_long_reg));
  4984   match(RegL);
  4985   match(mRegL);
  4987   format %{ %}
  4988   interface(REG_INTER);
  4989 %}
  4991 operand t8RegL() %{
  4992   constraint(ALLOC_IN_RC(t8_long_reg));
  4993   match(RegL);
  4994   match(mRegL);
  4996   format %{ %}
  4997   interface(REG_INTER);
  4998 %}
  5000 operand a4RegL() %{
  5001   constraint(ALLOC_IN_RC(a4_long_reg));
  5002   match(RegL);
  5003   match(mRegL);
  5005   format %{ %}
  5006   interface(REG_INTER);
  5007 %}
  5009 operand a5RegL() %{
  5010   constraint(ALLOC_IN_RC(a5_long_reg));
  5011   match(RegL);
  5012   match(mRegL);
  5014   format %{ %}
  5015   interface(REG_INTER);
  5016 %}
  5018 operand a6RegL() %{
  5019   constraint(ALLOC_IN_RC(a6_long_reg));
  5020   match(RegL);
  5021   match(mRegL);
  5023   format %{ %}
  5024   interface(REG_INTER);
  5025 %}
  5027 operand a7RegL() %{
  5028   constraint(ALLOC_IN_RC(a7_long_reg));
  5029   match(RegL);
  5030   match(mRegL);
  5032   format %{ %}
  5033   interface(REG_INTER);
  5034 %}
  5036 operand s0RegL() %{
  5037   constraint(ALLOC_IN_RC(s0_long_reg));
  5038   match(RegL);
  5039   match(mRegL);
  5041   format %{ %}
  5042   interface(REG_INTER);
  5043 %}
  5045 operand s1RegL() %{
  5046   constraint(ALLOC_IN_RC(s1_long_reg));
  5047   match(RegL);
  5048   match(mRegL);
  5050   format %{ %}
  5051   interface(REG_INTER);
  5052 %}
  5054 operand s2RegL() %{
  5055   constraint(ALLOC_IN_RC(s2_long_reg));
  5056   match(RegL);
  5057   match(mRegL);
  5059   format %{ %}
  5060   interface(REG_INTER);
  5061 %}
  5063 operand s3RegL() %{
  5064   constraint(ALLOC_IN_RC(s3_long_reg));
  5065   match(RegL);
  5066   match(mRegL);
  5068   format %{ %}
  5069   interface(REG_INTER);
  5070 %}
  5072 operand s4RegL() %{
  5073   constraint(ALLOC_IN_RC(s4_long_reg));
  5074   match(RegL);
  5075   match(mRegL);
  5077   format %{ %}
  5078   interface(REG_INTER);
  5079 %}
  5081 operand s7RegL() %{
  5082   constraint(ALLOC_IN_RC(s7_long_reg));
  5083   match(RegL);
  5084   match(mRegL);
  5086   format %{ %}
  5087   interface(REG_INTER);
  5088 %}
  5090 // Floating register operands
  5091 operand regF() %{
  5092   constraint(ALLOC_IN_RC(flt_reg));
  5093   match(RegF);
  5095   format %{ %}
  5096   interface(REG_INTER);
  5097 %}
  5099 //Double Precision Floating register operands
  5100 operand regD() %{
  5101   constraint(ALLOC_IN_RC(dbl_reg));
  5102   match(RegD);
  5104   format %{ %}
  5105   interface(REG_INTER);
  5106 %}
  5108 //----------Memory Operands----------------------------------------------------
  5109 // Indirect Memory Operand
  5110 operand indirect(mRegP reg) %{
  5111   constraint(ALLOC_IN_RC(p_reg));
  5112   match(reg);
  5114   format %{ "[$reg] @ indirect" %}
  5115   interface(MEMORY_INTER) %{
  5116     base($reg);
  5117     index(0x0);  /* NO_INDEX */
  5118     scale(0x0);
  5119     disp(0x0);
  5120   %}
  5121 %}
  5123 // Indirect Memory Plus Short Offset Operand
  5124 operand indOffset8(mRegP reg, immL8 off)
  5125 %{
  5126   constraint(ALLOC_IN_RC(p_reg));
  5127   match(AddP reg off);
  5129   op_cost(10);
  5130   format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
  5131   interface(MEMORY_INTER) %{
  5132     base($reg);
  5133     index(0x0); /* NO_INDEX */
  5134     scale(0x0);
  5135     disp($off);
  5136   %}
  5137 %}
  5139 // Indirect Memory Times Scale Plus Index Register
  5140 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
  5141 %{
  5142   constraint(ALLOC_IN_RC(p_reg));
  5143   match(AddP reg (LShiftL lreg scale));
  5145   op_cost(10);
  5146   format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
  5147   interface(MEMORY_INTER) %{
  5148     base($reg);
  5149     index($lreg);
  5150     scale($scale);
  5151     disp(0x0);
  5152   %}
  5153 %}
  5156 // [base + index + offset]
  5157 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
  5158 %{
  5159   constraint(ALLOC_IN_RC(p_reg));
  5160   op_cost(5);
  5161   match(AddP (AddP base index) off);
  5163   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
  5164   interface(MEMORY_INTER) %{
  5165     base($base);
  5166     index($index);
  5167     scale(0x0);
  5168     disp($off);
  5169   %}
  5170 %}
  5172 // [base + index + offset]
  5173 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
  5174 %{
  5175   constraint(ALLOC_IN_RC(p_reg));
  5176   op_cost(5);
  5177   match(AddP (AddP base (ConvI2L index)) off);
  5179   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
  5180   interface(MEMORY_INTER) %{
  5181     base($base);
  5182     index($index);
  5183     scale(0x0);
  5184     disp($off);
  5185   %}
  5186 %}
  5188 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5189 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
  5190 %{
  5191   constraint(ALLOC_IN_RC(p_reg));
  5192   match(AddP (AddP reg (LShiftL lreg scale)) off);
  5194   op_cost(10);
  5195   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
  5196   interface(MEMORY_INTER) %{
  5197     base($reg);
  5198     index($lreg);
  5199     scale($scale);
  5200     disp($off);
  5201   %}
  5202 %}
  5204 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
  5205 %{
  5206   constraint(ALLOC_IN_RC(p_reg));
  5207   match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
  5209   op_cost(10);
  5210   format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
  5211   interface(MEMORY_INTER) %{
  5212     base($reg);
  5213     index($ireg);
  5214     scale($scale);
  5215     disp($off);
  5216   %}
  5217 %}
  5219 // [base + index<<scale + offset]
  5220 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
  5221 %{
  5222   constraint(ALLOC_IN_RC(p_reg));
  5223   //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5224   op_cost(10);
  5225   match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
  5227   format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
  5228   interface(MEMORY_INTER) %{
  5229     base($base);
  5230     index($index);
  5231     scale($scale);
  5232     disp($off);
  5233   %}
  5234 %}
  5236 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5237 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
  5238 %{
  5239   predicate(Universe::narrow_oop_shift() == 0);
  5240   constraint(ALLOC_IN_RC(p_reg));
  5241   match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
  5243   op_cost(10);
  5244   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
  5245   interface(MEMORY_INTER) %{
  5246     base($reg);
  5247     index($lreg);
  5248     scale($scale);
  5249     disp($off);
  5250   %}
  5251 %}
  5253 // [base + index<<scale + offset] for compressd Oops
  5254 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
  5255 %{
  5256   constraint(ALLOC_IN_RC(p_reg));
  5257   //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5258   predicate(Universe::narrow_oop_shift() == 0);
  5259   op_cost(10);
  5260   match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
  5262   format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
  5263   interface(MEMORY_INTER) %{
  5264     base($base);
  5265     index($index);
  5266     scale($scale);
  5267     disp($off);
  5268   %}
  5269 %}
  5271 //FIXME: I think it's better to limit the immI to be 16-bit at most!
  5272 // Indirect Memory Plus Long Offset Operand
  5273 operand indOffset32(mRegP reg, immL32 off) %{
  5274   constraint(ALLOC_IN_RC(p_reg));
  5275   op_cost(20);
  5276   match(AddP reg off);
  5278   format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
  5279   interface(MEMORY_INTER) %{
  5280     base($reg);
  5281     index(0x0);   /* NO_INDEX */
  5282     scale(0x0);
  5283     disp($off);
  5284   %}
  5285 %}
  5287 // Indirect Memory Plus Index Register
  5288 operand indIndex(mRegP addr, mRegL index) %{
  5289   constraint(ALLOC_IN_RC(p_reg));
  5290   match(AddP addr index);
  5292   op_cost(20);
  5293   format %{"[$addr + $index] @ indIndex" %}
  5294   interface(MEMORY_INTER) %{
  5295     base($addr);
  5296     index($index);
  5297     scale(0x0);
  5298     disp(0x0);
  5299   %}
  5300 %}
  5302 operand indirectNarrowKlass(mRegN reg)
  5303 %{
  5304   predicate(Universe::narrow_klass_shift() == 0);
  5305   constraint(ALLOC_IN_RC(p_reg));
  5306   op_cost(10);
  5307   match(DecodeNKlass reg);
  5309   format %{ "[$reg] @ indirectNarrowKlass" %}
  5310   interface(MEMORY_INTER) %{
  5311     base($reg);
  5312     index(0x0);
  5313     scale(0x0);
  5314     disp(0x0);
  5315   %}
  5316 %}
  5318 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
  5319 %{
  5320   predicate(Universe::narrow_klass_shift() == 0);
  5321   constraint(ALLOC_IN_RC(p_reg));
  5322   op_cost(10);
  5323   match(AddP (DecodeNKlass reg) off);
  5325   format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
  5326   interface(MEMORY_INTER) %{
  5327     base($reg);
  5328     index(0x0);
  5329     scale(0x0);
  5330     disp($off);
  5331   %}
  5332 %}
  5334 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
  5335 %{
  5336   predicate(Universe::narrow_klass_shift() == 0);
  5337   constraint(ALLOC_IN_RC(p_reg));
  5338   op_cost(10);
  5339   match(AddP (DecodeNKlass reg) off);
  5341   format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
  5342   interface(MEMORY_INTER) %{
  5343     base($reg);
  5344     index(0x0);
  5345     scale(0x0);
  5346     disp($off);
  5347   %}
  5348 %}
  5350 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
  5351 %{
  5352   predicate(Universe::narrow_klass_shift() == 0);
  5353   constraint(ALLOC_IN_RC(p_reg));
  5354   match(AddP (AddP (DecodeNKlass reg) lreg) off);
  5356   op_cost(10);
  5357   format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
  5358   interface(MEMORY_INTER) %{
  5359     base($reg);
  5360     index($lreg);
  5361     scale(0x0);
  5362     disp($off);
  5363   %}
  5364 %}
  5366 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
  5367 %{
  5368   predicate(Universe::narrow_klass_shift() == 0);
  5369   constraint(ALLOC_IN_RC(p_reg));
  5370   match(AddP (DecodeNKlass reg) lreg);
  5372   op_cost(10);
  5373   format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
  5374   interface(MEMORY_INTER) %{
  5375     base($reg);
  5376     index($lreg);
  5377     scale(0x0);
  5378     disp(0x0);
  5379   %}
  5380 %}
  5382 // Indirect Memory Operand
  5383 operand indirectNarrow(mRegN reg)
  5384 %{
  5385   predicate(Universe::narrow_oop_shift() == 0);
  5386   constraint(ALLOC_IN_RC(p_reg));
  5387   op_cost(10);
  5388   match(DecodeN reg);
  5390   format %{ "[$reg] @ indirectNarrow" %}
  5391   interface(MEMORY_INTER) %{
  5392     base($reg);
  5393     index(0x0);
  5394     scale(0x0);
  5395     disp(0x0);
  5396   %}
  5397 %}
  5399 // Indirect Memory Plus Short Offset Operand
  5400 operand indOffset8Narrow(mRegN reg, immL8 off)
  5401 %{
  5402   predicate(Universe::narrow_oop_shift() == 0);
  5403   constraint(ALLOC_IN_RC(p_reg));
  5404   op_cost(10);
  5405   match(AddP (DecodeN reg) off);
  5407   format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
  5408   interface(MEMORY_INTER) %{
  5409     base($reg);
  5410     index(0x0);
  5411     scale(0x0);
  5412     disp($off);
  5413   %}
  5414 %}
  5416 // Indirect Memory Plus Index Register Plus Offset Operand
  5417 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
  5418 %{
  5419   predicate(Universe::narrow_oop_shift() == 0);
  5420   constraint(ALLOC_IN_RC(p_reg));
  5421   match(AddP (AddP (DecodeN reg) lreg) off);
  5423   op_cost(10);
  5424   format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
  5425   interface(MEMORY_INTER) %{
  5426     base($reg);
  5427     index($lreg);
  5428     scale(0x0);
  5429     disp($off);
  5430   %}
  5431 %}
  5433 //----------Load Long Memory Operands------------------------------------------
  5434 // The load-long idiom will use it's address expression again after loading
  5435 // the first word of the long.  If the load-long destination overlaps with
  5436 // registers used in the addressing expression, the 2nd half will be loaded
  5437 // from a clobbered address.  Fix this by requiring that load-long use
  5438 // address registers that do not overlap with the load-long target.
  5440 // load-long support
  5441 operand load_long_RegP() %{
  5442   constraint(ALLOC_IN_RC(p_reg));
  5443   match(RegP);
  5444   match(mRegP);
  5445   op_cost(100);
  5446   format %{  %}
  5447   interface(REG_INTER);
  5448 %}
  5450 // Indirect Memory Operand Long
  5451 operand load_long_indirect(load_long_RegP reg) %{
  5452   constraint(ALLOC_IN_RC(p_reg));
  5453   match(reg);
  5455   format %{ "[$reg]" %}
  5456   interface(MEMORY_INTER) %{
  5457     base($reg);
  5458     index(0x0);
  5459     scale(0x0);
  5460     disp(0x0);
  5461   %}
  5462 %}
  5464 // Indirect Memory Plus Long Offset Operand
  5465 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
  5466   match(AddP reg off);
  5468   format %{ "[$reg + $off]" %}
  5469   interface(MEMORY_INTER) %{
  5470     base($reg);
  5471     index(0x0);
  5472     scale(0x0);
  5473     disp($off);
  5474   %}
  5475 %}
  5477 //----------Conditional Branch Operands----------------------------------------
  5478 // Comparison Op  - This is the operation of the comparison, and is limited to
  5479 //                  the following set of codes:
  5480 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
  5481 //
  5482 // Other attributes of the comparison, such as unsignedness, are specified
  5483 // by the comparison instruction that sets a condition code flags register.
  5484 // That result is represented by a flags operand whose subtype is appropriate
  5485 // to the unsignedness (etc.) of the comparison.
  5486 //
  5487 // Later, the instruction which matches both the Comparison Op (a Bool) and
  5488 // the flags (produced by the Cmp) specifies the coding of the comparison op
  5489 // by matching a specific subtype of Bool operand below, such as cmpOpU.
  5491 // Comparision Code
  5492 operand cmpOp() %{
  5493   match(Bool);
  5495   format %{ "" %}
  5496   interface(COND_INTER) %{
  5497     equal(0x01);
  5498     not_equal(0x02);
  5499     greater(0x03);
  5500     greater_equal(0x04);
  5501     less(0x05);
  5502     less_equal(0x06);
  5503     overflow(0x7);
  5504     no_overflow(0x8);
  5505   %}
  5506 %}
  5509 // Comparision Code
  5510 // Comparison Code, unsigned compare.  Used by FP also, with
  5511 // C2 (unordered) turned into GT or LT already.  The other bits
  5512 // C0 and C3 are turned into Carry & Zero flags.
  5513 operand cmpOpU() %{
  5514   match(Bool);
  5516   format %{ "" %}
  5517   interface(COND_INTER) %{
  5518     equal(0x01);
  5519     not_equal(0x02);
  5520     greater(0x03);
  5521     greater_equal(0x04);
  5522     less(0x05);
  5523     less_equal(0x06);
  5524     overflow(0x7);
  5525     no_overflow(0x8);
  5526   %}
  5527 %}
  5530 //----------Special Memory Operands--------------------------------------------
  5531 // Stack Slot Operand - This operand is used for loading and storing temporary
  5532 //                      values on the stack where a match requires a value to
  5533 //                      flow through memory.
  5534 operand stackSlotP(sRegP reg) %{
  5535   constraint(ALLOC_IN_RC(stack_slots));
  5536   // No match rule because this operand is only generated in matching
  5537   op_cost(50);
  5538   format %{ "[$reg]" %}
  5539   interface(MEMORY_INTER) %{
  5540     base(0x1d);  // SP
  5541     index(0x0);  // No Index
  5542     scale(0x0);  // No Scale
  5543     disp($reg);  // Stack Offset
  5544   %}
  5545 %}
  5547 operand stackSlotI(sRegI reg) %{
  5548   constraint(ALLOC_IN_RC(stack_slots));
  5549   // No match rule because this operand is only generated in matching
  5550   op_cost(50);
  5551   format %{ "[$reg]" %}
  5552   interface(MEMORY_INTER) %{
  5553     base(0x1d);  // SP
  5554     index(0x0);  // No Index
  5555     scale(0x0);  // No Scale
  5556     disp($reg);  // Stack Offset
  5557   %}
  5558 %}
  5560 operand stackSlotF(sRegF reg) %{
  5561   constraint(ALLOC_IN_RC(stack_slots));
  5562   // No match rule because this operand is only generated in matching
  5563   op_cost(50);
  5564   format %{ "[$reg]" %}
  5565   interface(MEMORY_INTER) %{
  5566     base(0x1d);  // SP
  5567     index(0x0);  // No Index
  5568     scale(0x0);  // No Scale
  5569     disp($reg);  // Stack Offset
  5570   %}
  5571 %}
  5573 operand stackSlotD(sRegD reg) %{
  5574   constraint(ALLOC_IN_RC(stack_slots));
  5575   // No match rule because this operand is only generated in matching
  5576   op_cost(50);
  5577   format %{ "[$reg]" %}
  5578   interface(MEMORY_INTER) %{
  5579     base(0x1d);  // SP
  5580     index(0x0);  // No Index
  5581     scale(0x0);  // No Scale
  5582     disp($reg);  // Stack Offset
  5583   %}
  5584 %}
  5586 operand stackSlotL(sRegL reg) %{
  5587   constraint(ALLOC_IN_RC(stack_slots));
  5588   // No match rule because this operand is only generated in matching
  5589   op_cost(50);
  5590   format %{ "[$reg]" %}
  5591   interface(MEMORY_INTER) %{
  5592     base(0x1d);  // SP
  5593     index(0x0);  // No Index
  5594     scale(0x0);  // No Scale
  5595     disp($reg);  // Stack Offset
  5596   %}
  5597 %}
  5600 //------------------------OPERAND CLASSES--------------------------------------
  5601 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
  5602 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);
  5605 //----------PIPELINE-----------------------------------------------------------
  5606 // Rules which define the behavior of the target architectures pipeline.
  5608 pipeline %{
  5610   //----------ATTRIBUTES---------------------------------------------------------
  5611   attributes %{
  5612     fixed_size_instructions;          // Fixed size instructions
  5613     branch_has_delay_slot;      // branch have delay slot in gs2
  5614     max_instructions_per_bundle = 1;     // 1 instruction per bundle
  5615     max_bundles_per_cycle = 4;         // Up to 4 bundles per cycle
  5616          bundle_unit_size=4;
  5617     instruction_unit_size = 4;           // An instruction is 4 bytes long
  5618     instruction_fetch_unit_size = 16;    // The processor fetches one line
  5619     instruction_fetch_units = 1;         // of 16 bytes
  5621     // List of nop instructions
  5622     nops( MachNop );
  5623   %}
  5625   //----------RESOURCES----------------------------------------------------------
  5626   // Resources are the functional units available to the machine
  5628   resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4,  ALU1, ALU2,  ALU = ALU1 | ALU2,  FPU1, FPU2, FPU = FPU1 | FPU2,  MEM,  BR);
  5630   //----------PIPELINE DESCRIPTION-----------------------------------------------
  5631   // Pipeline Description specifies the stages in the machine's pipeline
  5633   // IF: fetch
  5634   // ID: decode
  5635   // RD: read
  5636   // CA: caculate
  5637   // WB: write back
  5638   // CM: commit
  5640   pipe_desc(IF, ID, RD, CA, WB, CM);
  5643   //----------PIPELINE CLASSES---------------------------------------------------
  5644   // Pipeline Classes describe the stages in which input and output are
  5645   // referenced by the hardware pipeline.
  5647   //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
  5648   pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
  5649     single_instruction;
  5650     src1   : RD(read);
  5651     src2   : RD(read);
  5652     dst    : WB(write)+1;
  5653     DECODE : ID;
  5654     ALU    : CA;
  5655   %}
  5657   //No.19 Integer mult operation : dst <-- reg1 mult reg2
  5658   pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
  5659     src1   : RD(read);
  5660     src2   : RD(read);
  5661     dst    : WB(write)+5;
  5662     DECODE : ID;
  5663     ALU2   : CA;
  5664   %}
  5666   pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  5667     src1   : RD(read);
  5668     src2   : RD(read);
  5669     dst    : WB(write)+10;
  5670     DECODE : ID;
  5671     ALU2   : CA;
  5672   %}
  5674   //No.19 Integer div operation : dst <-- reg1 div reg2
  5675   pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
  5676     src1   : RD(read);
  5677     src2   : RD(read);
  5678     dst    : WB(write)+10;
  5679     DECODE : ID;
  5680     ALU2   : CA;
  5681   %}
  5683   //No.19 Integer mod operation : dst <-- reg1 mod reg2
  5684   pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
  5685     instruction_count(2);
  5686     src1   : RD(read);
  5687     src2   : RD(read);
  5688     dst    : WB(write)+10;
  5689     DECODE : ID;
  5690     ALU2   : CA;
  5691   %}
  5693   //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
  5694   pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
  5695     instruction_count(2);
  5696     src1   : RD(read);
  5697     src2   : RD(read);
  5698     dst    : WB(write);
  5699     DECODE : ID;
  5700     ALU    : CA;
  5701   %}
  5703   //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
  5704   pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
  5705     instruction_count(2);
  5706     src    : RD(read);
  5707     dst    : WB(write);
  5708     DECODE : ID;
  5709     ALU    : CA;
  5710   %}
  5712   //no.16 load Long from memory :
  5713   pipe_class ialu_loadL(mRegL dst, memory mem) %{
  5714     instruction_count(2);
  5715     mem    : RD(read);
  5716     dst    : WB(write)+5;
  5717     DECODE : ID;
  5718     MEM    : RD;
  5719   %}
  5721   //No.17 Store Long to Memory :
  5722   pipe_class ialu_storeL(mRegL src, memory mem) %{
  5723     instruction_count(2);
  5724     mem    : RD(read);
  5725     src    : RD(read);
  5726     DECODE : ID;
  5727     MEM    : RD;
  5728   %}
  5730   //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
  5731   pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
  5732          single_instruction;
  5733     src    : RD(read);
  5734     dst    : WB(write);
  5735     DECODE : ID;
  5736     ALU    : CA;
  5737   %}
  5739   //No.3 Integer move operation : dst <-- reg
  5740   pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
  5741     src    : RD(read);
  5742     dst    : WB(write);
  5743     DECODE : ID;
  5744     ALU    : CA;
  5745   %}
  5747   //No.4 No instructions : do nothing
  5748   pipe_class empty( ) %{
  5749     instruction_count(0);
  5750   %}
  5752   //No.5 UnConditional branch :
  5753   pipe_class pipe_jump( label labl ) %{
  5754     multiple_bundles;
  5755     DECODE : ID;
  5756     BR     : RD;
  5757   %}
  5759   //No.6 ALU Conditional branch :
  5760   pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
  5761     multiple_bundles;
  5762     src1   : RD(read);
  5763     src2   : RD(read);
  5764     DECODE : ID;
  5765     BR     : RD;
  5766   %}
  5768   //no.7 load integer from memory :
  5769   pipe_class ialu_loadI(mRegI dst, memory mem) %{
  5770     mem    : RD(read);
  5771     dst    : WB(write)+3;
  5772     DECODE : ID;
  5773     MEM    : RD;
  5774   %}
  5776   //No.8 Store Integer to Memory :
  5777   pipe_class ialu_storeI(mRegI src, memory mem) %{
  5778     mem    : RD(read);
  5779     src    : RD(read);
  5780     DECODE : ID;
  5781     MEM    : RD;
  5782   %}
  5785   //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
  5786   pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
  5787     src1   : RD(read);
  5788     src2   : RD(read);
  5789     dst    : WB(write);
  5790     DECODE : ID;
  5791     FPU    : CA;
  5792   %}
  5794   //No.22 Floating div operation : dst <-- reg1 div reg2
  5795   pipe_class fpu_div(regF dst, regF src1, regF src2) %{
  5796     src1   : RD(read);
  5797     src2   : RD(read);
  5798     dst    : WB(write);
  5799     DECODE : ID;
  5800     FPU2   : CA;
  5801   %}
  5803   pipe_class fcvt_I2D(regD dst, mRegI src) %{
  5804     src    : RD(read);
  5805     dst    : WB(write);
  5806     DECODE : ID;
  5807     FPU1   : CA;
  5808   %}
  5810   pipe_class fcvt_D2I(mRegI dst, regD src) %{
  5811     src    : RD(read);
  5812     dst    : WB(write);
  5813     DECODE : ID;
  5814     FPU1   : CA;
  5815   %}
  5817   pipe_class pipe_mfc1(mRegI dst, regD src) %{
  5818     src    : RD(read);
  5819     dst    : WB(write);
  5820     DECODE : ID;
  5821     MEM    : RD;
  5822   %}
  5824   pipe_class pipe_mtc1(regD dst, mRegI src) %{
  5825     src    : RD(read);
  5826     dst    : WB(write);
  5827     DECODE : ID;
  5828     MEM    : RD(5);
  5829   %}
  5831   //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
  5832   pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
  5833     multiple_bundles;
  5834     src1   : RD(read);
  5835     src2   : RD(read);
  5836     dst    : WB(write);
  5837     DECODE : ID;
  5838     FPU2   : CA;
  5839   %}
  5841   //No.11 Load Floating from Memory :
  5842   pipe_class fpu_loadF(regF dst, memory mem) %{
  5843     instruction_count(1);
  5844     mem    : RD(read);
  5845     dst    : WB(write)+3;
  5846     DECODE : ID;
  5847     MEM    : RD;
  5848   %}
  5850   //No.12 Store Floating to Memory :
  5851   pipe_class fpu_storeF(regF src, memory mem) %{
  5852     instruction_count(1);
  5853     mem    : RD(read);
  5854     src    : RD(read);
  5855     DECODE : ID;
  5856     MEM    : RD;
  5857   %}
  5859   //No.13 FPU Conditional branch :
  5860   pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
  5861     multiple_bundles;
  5862     src1   : RD(read);
  5863     src2   : RD(read);
  5864     DECODE : ID;
  5865     BR     : RD;
  5866   %}
  5868 //No.14 Floating FPU reg operation : dst <-- op reg
  5869   pipe_class fpu1_regF(regF dst, regF src) %{
  5870     src    : RD(read);
  5871     dst    : WB(write);
  5872     DECODE : ID;
  5873     FPU    : CA;
  5874   %}
  5876   pipe_class long_memory_op() %{
  5877     instruction_count(10); multiple_bundles; force_serialization;
  5878     fixed_latency(30);
  5879   %}
  5881   pipe_class simple_call() %{
  5882    instruction_count(10); multiple_bundles; force_serialization;
  5883    fixed_latency(200);
  5884    BR     : RD;
  5885   %}
  5887   pipe_class call() %{
  5888     instruction_count(10); multiple_bundles; force_serialization;
  5889     fixed_latency(200);
  5890   %}
  5892   //FIXME:
  5893   //No.9 Piple slow : for multi-instructions
  5894   pipe_class pipe_slow(  ) %{
  5895     instruction_count(20);
  5896     force_serialization;
  5897     multiple_bundles;
  5898     fixed_latency(50);
  5899   %}
  5901 %}
  5905 //----------INSTRUCTIONS-------------------------------------------------------
  5906 //
  5907 // match      -- States which machine-independent subtree may be replaced
  5908 //               by this instruction.
  5909 // ins_cost   -- The estimated cost of this instruction is used by instruction
  5910 //               selection to identify a minimum cost tree of machine
  5911 //               instructions that matches a tree of machine-independent
  5912 //               instructions.
  5913 // format     -- A string providing the disassembly for this instruction.
  5914 //               The value of an instruction's operand may be inserted
  5915 //               by referring to it with a '$' prefix.
  5916 // opcode     -- Three instruction opcodes may be provided.  These are referred
  5917 //               to within an encode class as $primary, $secondary, and $tertiary
  5918 //               respectively.  The primary opcode is commonly used to
  5919 //               indicate the type of machine instruction, while secondary
  5920 //               and tertiary are often used for prefix options or addressing
  5921 //               modes.
  5922 // ins_encode -- A list of encode classes with parameters. The encode class
  5923 //               name must have been defined in an 'enc_class' specification
  5924 //               in the encode section of the architecture description.
  5927 // Load Integer
  5928 instruct loadI(mRegI dst, memory mem) %{
  5929   match(Set dst (LoadI mem));
  5931   ins_cost(125);
  5932   format %{ "lw    $dst, $mem   #@loadI" %}
  5933   ins_encode (load_I_enc(dst, mem));
  5934   ins_pipe( ialu_loadI );
  5935 %}
  5937 instruct loadI_convI2L(mRegL dst, memory mem) %{
  5938   match(Set dst (ConvI2L (LoadI mem)));
  5940   ins_cost(125);
  5941   format %{ "lw    $dst, $mem   #@loadI_convI2L" %}
  5942   ins_encode (load_I_enc(dst, mem));
  5943   ins_pipe( ialu_loadI );
  5944 %}
  5946 // Load Integer (32 bit signed) to Byte (8 bit signed)
  5947 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  5948   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
  5950   ins_cost(125);
  5951   format %{ "lb  $dst, $mem\t# int -> byte #@loadI2B" %}
  5952   ins_encode(load_B_enc(dst, mem));
  5953   ins_pipe(ialu_loadI);
  5954 %}
  5956 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
  5957 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
  5958   match(Set dst (AndI (LoadI mem) mask));
  5960   ins_cost(125);
  5961   format %{ "lbu  $dst, $mem\t# int -> ubyte #@loadI2UB" %}
  5962   ins_encode(load_UB_enc(dst, mem));
  5963   ins_pipe(ialu_loadI);
  5964 %}
  5966 // Load Integer (32 bit signed) to Short (16 bit signed)
  5967 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
  5968   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
  5970   ins_cost(125);
  5971   format %{ "lh  $dst, $mem\t# int -> short #@loadI2S" %}
  5972   ins_encode(load_S_enc(dst, mem));
  5973   ins_pipe(ialu_loadI);
  5974 %}
  5976 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
  5977 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
  5978   match(Set dst (AndI (LoadI mem) mask));
  5980   ins_cost(125);
  5981   format %{ "lhu  $dst, $mem\t# int -> ushort/char #@loadI2US" %}
  5982   ins_encode(load_C_enc(dst, mem));
  5983   ins_pipe(ialu_loadI);
  5984 %}
  5986 // Load Long.
  5987 instruct loadL(mRegL dst, memory mem) %{
  5988 //  predicate(!((LoadLNode*)n)->require_atomic_access());
  5989   match(Set dst (LoadL mem));
  5991   ins_cost(250);
  5992   format %{ "ld    $dst, $mem   #@loadL" %}
  5993   ins_encode(load_L_enc(dst, mem));
  5994   ins_pipe( ialu_loadL );
  5995 %}
  5997 // Load Long - UNaligned
  5998 instruct loadL_unaligned(mRegL dst, memory mem) %{
  5999   match(Set dst (LoadL_unaligned mem));
  6001   // FIXME: Jin: Need more effective ldl/ldr
  6002   ins_cost(450);
  6003   format %{ "ld    $dst, $mem   #@loadL_unaligned\n\t" %}
  6004   ins_encode(load_L_enc(dst, mem));
  6005   ins_pipe( ialu_loadL );
  6006 %}
  6008 // Store Long
  6009 instruct storeL_reg(memory mem, mRegL src) %{
  6010   match(Set mem (StoreL mem src));
  6012   ins_cost(200);
  6013   format %{ "sd    $mem,   $src #@storeL_reg\n" %}
  6014   ins_encode(store_L_reg_enc(mem, src));
  6015   ins_pipe( ialu_storeL );
  6016 %}
  6018 instruct storeL_immL0(memory mem, immL0 zero) %{
  6019   match(Set mem (StoreL mem zero));
  6021   ins_cost(180);
  6022   format %{ "sd    zero, $mem #@storeL_immL0" %}
  6023   ins_encode(store_L_immL0_enc(mem, zero));
  6024   ins_pipe( ialu_storeL );
  6025 %}
  6027 instruct storeL_imm(memory mem, immL src) %{
  6028   match(Set mem (StoreL mem src));
  6030   ins_cost(200);
  6031   format %{ "sd    $src, $mem #@storeL_imm" %}
  6032   ins_encode(store_L_immL_enc(mem, src));
  6033   ins_pipe( ialu_storeL );
  6034 %}
  6036 // Load Compressed Pointer
  6037 instruct loadN(mRegN dst, memory mem)
  6038 %{
  6039    match(Set dst (LoadN mem));
  6041    ins_cost(125); // XXX
  6042    format %{ "lwu    $dst, $mem\t# compressed ptr @ loadN" %}
  6043    ins_encode (load_N_enc(dst, mem));
  6044    ins_pipe( ialu_loadI ); // XXX
  6045 %}
  6047 instruct loadN2P(mRegP dst, memory mem)
  6048 %{
  6049    match(Set dst (DecodeN (LoadN mem)));
  6050    predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6052    ins_cost(125); // XXX
  6053    format %{ "lwu    $dst, $mem\t# @ loadN2P" %}
  6054    ins_encode (load_N_enc(dst, mem));
  6055    ins_pipe( ialu_loadI ); // XXX
  6056 %}
  6058 // Load Pointer
  6059 instruct loadP(mRegP dst, memory mem) %{
  6060   match(Set dst (LoadP mem));
  6062   ins_cost(125);
  6063   format %{ "ld    $dst, $mem #@loadP" %}
  6064   ins_encode (load_P_enc(dst, mem));
  6065   ins_pipe( ialu_loadI );
  6066 %}
  6068 // Load Klass Pointer
  6069 instruct loadKlass(mRegP dst, memory mem) %{
  6070   match(Set dst (LoadKlass mem));
  6072   ins_cost(125);
  6073   format %{ "MOV    $dst,$mem @ loadKlass" %}
  6074   ins_encode (load_P_enc(dst, mem));
  6075   ins_pipe( ialu_loadI );
  6076 %}
  6078 // Load narrow Klass Pointer
  6079 instruct loadNKlass(mRegN dst, memory mem)
  6080 %{
  6081   match(Set dst (LoadNKlass mem));
  6083   ins_cost(125); // XXX
  6084   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
  6085   ins_encode (load_N_enc(dst, mem));
  6086   ins_pipe( ialu_loadI ); // XXX
  6087 %}
  6089 instruct loadN2PKlass(mRegP dst, memory mem)
  6090 %{
  6091   match(Set dst (DecodeNKlass (LoadNKlass mem)));
  6092   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6094   ins_cost(125); // XXX
  6095   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
  6096   ins_encode (load_N_enc(dst, mem));
  6097   ins_pipe( ialu_loadI ); // XXX
  6098 %}
  6100 // Load Constant
  6101 instruct loadConI(mRegI dst, immI src) %{
  6102   match(Set dst src);
  6104   ins_cost(150);
  6105   format %{ "mov    $dst, $src #@loadConI" %}
  6106   ins_encode %{
  6107     Register dst = $dst$$Register;
  6108     int    value = $src$$constant;
  6109     __ move(dst, value);
  6110   %}
  6111   ins_pipe( ialu_regI_regI );
  6112 %}
  6115 instruct loadConL_set64(mRegL dst, immL src) %{
  6116   match(Set dst src);
  6117   ins_cost(120);
  6118   format %{ "li   $dst, $src @ loadConL_set64" %}
  6119   ins_encode %{
  6120     __ set64($dst$$Register, $src$$constant);
  6121   %}
  6122   ins_pipe(ialu_regL_regL);
  6123 %}
  6125 /*
  6126 // Load long value from constant table (predicated by immL_expensive).
  6127 instruct loadConL_load(mRegL dst, immL_expensive src) %{
  6128   match(Set dst src);
  6129   ins_cost(150);
  6130   format %{ "ld  $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
  6131   ins_encode %{
  6132     int con_offset = $constantoffset($src);
  6134     if (Assembler::is_simm16(con_offset)) {
  6135        __ ld($dst$$Register, $constanttablebase, con_offset);
  6136     } else {
  6137        __ set64(AT, con_offset);
  6138        if (UseLoongsonISA) {
  6139           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6140        } else {
  6141           __ daddu(AT, $constanttablebase, AT);
  6142           __ ld($dst$$Register, AT, 0);
  6145   %}
  6146   ins_pipe(ialu_loadI);
  6147 %}
  6148 */
  6150 instruct loadConL16(mRegL dst, immL16 src) %{
  6151   match(Set dst src);
  6152   ins_cost(105);
  6153   format %{ "mov    $dst, $src #@loadConL16" %}
  6154   ins_encode %{
  6155     Register dst_reg = as_Register($dst$$reg);
  6156     int      value   = $src$$constant;
  6157     __ daddiu(dst_reg, R0, value);
  6158   %}
  6159   ins_pipe( ialu_regL_regL );
  6160 %}
  6163 instruct loadConL0(mRegL dst, immL0 src) %{
  6164   match(Set dst src);
  6165   ins_cost(100);
  6166   format %{ "mov    $dst, zero #@loadConL0" %}
  6167   ins_encode %{
  6168     Register dst_reg = as_Register($dst$$reg);
  6169     __ daddu(dst_reg, R0, R0);
  6170   %}
  6171   ins_pipe( ialu_regL_regL );
  6172 %}
  6174 // Load Range
  6175 instruct loadRange(mRegI dst, memory mem) %{
  6176   match(Set dst (LoadRange mem));
  6178   ins_cost(125);
  6179   format %{ "MOV    $dst,$mem @ loadRange" %}
  6180   ins_encode(load_I_enc(dst, mem));
  6181   ins_pipe( ialu_loadI );
  6182 %}
  6185 instruct storeP(memory mem, mRegP src ) %{
  6186   match(Set mem (StoreP mem src));
  6188   ins_cost(125);
  6189   format %{ "sd    $src, $mem #@storeP" %}
  6190   ins_encode(store_P_reg_enc(mem, src));
  6191   ins_pipe( ialu_storeI );
  6192 %}
  6194 // Store NULL Pointer, mark word, or other simple pointer constant.
  6195 instruct storeImmP0(memory mem, immP0 zero) %{
  6196   match(Set mem (StoreP mem zero));
  6198   ins_cost(125);
  6199   format %{ "mov    $mem, $zero #@storeImmP0" %}
  6200   ins_encode(store_P_immP0_enc(mem));
  6201   ins_pipe( ialu_storeI );
  6202 %}
  6204 // Store Byte Immediate
  6205 instruct storeImmB(memory mem, immI8 src) %{
  6206   match(Set mem (StoreB mem src));
  6208   ins_cost(150);
  6209   format %{ "movb   $mem, $src #@storeImmB" %}
  6210   ins_encode(store_B_immI_enc(mem, src));
  6211   ins_pipe( ialu_storeI );
  6212 %}
  6214 // Store Compressed Pointer
  6215 instruct storeN(memory mem, mRegN src)
  6216 %{
  6217   match(Set mem (StoreN mem src));
  6219   ins_cost(125); // XXX
  6220   format %{ "sw    $mem, $src\t# compressed ptr @ storeN" %}
  6221   ins_encode(store_N_reg_enc(mem, src));
  6222   ins_pipe( ialu_storeI );
  6223 %}
  6225 instruct storeP2N(memory mem, mRegP src)
  6226 %{
  6227   match(Set mem (StoreN mem (EncodeP src)));
  6228   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6230   ins_cost(125); // XXX
  6231   format %{ "sw    $mem, $src\t# @ storeP2N" %}
  6232   ins_encode(store_N_reg_enc(mem, src));
  6233   ins_pipe( ialu_storeI );
  6234 %}
  6236 instruct storeNKlass(memory mem, mRegN src)
  6237 %{
  6238   match(Set mem (StoreNKlass mem src));
  6240   ins_cost(125); // XXX
  6241   format %{ "sw    $mem, $src\t# compressed klass ptr @ storeNKlass" %}
  6242   ins_encode(store_N_reg_enc(mem, src));
  6243   ins_pipe( ialu_storeI );
  6244 %}
  6246 instruct storeP2NKlass(memory mem, mRegP src)
  6247 %{
  6248   match(Set mem (StoreNKlass mem (EncodePKlass src)));
  6249   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6251   ins_cost(125); // XXX
  6252   format %{ "sw    $mem, $src\t# @ storeP2NKlass" %}
  6253   ins_encode(store_N_reg_enc(mem, src));
  6254   ins_pipe( ialu_storeI );
  6255 %}
  6257 instruct storeImmN0(memory mem, immN0 zero)
  6258 %{
  6259   match(Set mem (StoreN mem zero));
  6261   ins_cost(125); // XXX
  6262   format %{ "storeN0    zero, $mem\t# compressed ptr" %}
  6263   ins_encode(storeImmN0_enc(mem, zero));
  6264   ins_pipe( ialu_storeI );
  6265 %}
  6267 // Store Byte
  6268 instruct storeB(memory mem, mRegI src) %{
  6269   match(Set mem (StoreB mem src));
  6271   ins_cost(125);
  6272   format %{ "sb    $src, $mem #@storeB" %}
  6273   ins_encode(store_B_reg_enc(mem, src));
  6274   ins_pipe( ialu_storeI );
  6275 %}
  6277 instruct storeB_convL2I(memory mem, mRegL src) %{
  6278   match(Set mem (StoreB mem (ConvL2I src)));
  6280   ins_cost(125);
  6281   format %{ "sb    $src, $mem #@storeB_convL2I" %}
  6282   ins_encode(store_B_reg_enc(mem, src));
  6283   ins_pipe( ialu_storeI );
  6284 %}
  6286 // Load Byte (8bit signed)
  6287 instruct loadB(mRegI dst, memory mem) %{
  6288   match(Set dst (LoadB mem));
  6290   ins_cost(125);
  6291   format %{ "lb   $dst, $mem #@loadB" %}
  6292   ins_encode(load_B_enc(dst, mem));
  6293   ins_pipe( ialu_loadI );
  6294 %}
  6296 instruct loadB_convI2L(mRegL dst, memory mem) %{
  6297   match(Set dst (ConvI2L (LoadB mem)));
  6299   ins_cost(125);
  6300   format %{ "lb   $dst, $mem #@loadB_convI2L" %}
  6301   ins_encode(load_B_enc(dst, mem));
  6302   ins_pipe( ialu_loadI );
  6303 %}
  6305 // Load Byte (8bit UNsigned)
  6306 instruct loadUB(mRegI dst, memory mem) %{
  6307   match(Set dst (LoadUB mem));
  6309   ins_cost(125);
  6310   format %{ "lbu   $dst, $mem #@loadUB" %}
  6311   ins_encode(load_UB_enc(dst, mem));
  6312   ins_pipe( ialu_loadI );
  6313 %}
  6315 instruct loadUB_convI2L(mRegL dst, memory mem) %{
  6316   match(Set dst (ConvI2L (LoadUB mem)));
  6318   ins_cost(125);
  6319   format %{ "lbu   $dst, $mem #@loadUB_convI2L" %}
  6320   ins_encode(load_UB_enc(dst, mem));
  6321   ins_pipe( ialu_loadI );
  6322 %}
  6324 // Load Short (16bit signed)
  6325 instruct loadS(mRegI dst, memory mem) %{
  6326   match(Set dst (LoadS mem));
  6328   ins_cost(125);
  6329   format %{ "lh   $dst, $mem #@loadS" %}
  6330   ins_encode(load_S_enc(dst, mem));
  6331   ins_pipe( ialu_loadI );
  6332 %}
  6334 // Load Short (16 bit signed) to Byte (8 bit signed)
  6335 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  6336   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
  6338   ins_cost(125);
  6339   format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
  6340   ins_encode(load_B_enc(dst, mem));
  6341   ins_pipe(ialu_loadI);
  6342 %}
  6344 instruct loadS_convI2L(mRegL dst, memory mem) %{
  6345   match(Set dst (ConvI2L (LoadS mem)));
  6347   ins_cost(125);
  6348   format %{ "lh   $dst, $mem #@loadS_convI2L" %}
  6349   ins_encode(load_S_enc(dst, mem));
  6350   ins_pipe( ialu_loadI );
  6351 %}
  6353 // Store Integer Immediate
  6354 instruct storeImmI(memory mem, immI src) %{
  6355   match(Set mem (StoreI mem src));
  6357   ins_cost(150);
  6358   format %{ "mov    $mem, $src #@storeImmI" %}
  6359   ins_encode(store_I_immI_enc(mem, src));
  6360   ins_pipe( ialu_storeI );
  6361 %}
  6363 // Store Integer
  6364 instruct storeI(memory mem, mRegI src) %{
  6365   match(Set mem (StoreI mem src));
  6367   ins_cost(125);
  6368   format %{ "sw    $mem, $src #@storeI" %}
  6369   ins_encode(store_I_reg_enc(mem, src));
  6370   ins_pipe( ialu_storeI );
  6371 %}
  6373 instruct storeI_convL2I(memory mem, mRegL src) %{
  6374   match(Set mem (StoreI mem (ConvL2I src)));
  6376   ins_cost(125);
  6377   format %{ "sw    $mem, $src #@storeI_convL2I" %}
  6378   ins_encode(store_I_reg_enc(mem, src));
  6379   ins_pipe( ialu_storeI );
  6380 %}
  6382 // Load Float
  6383 instruct loadF(regF dst, memory mem) %{
  6384   match(Set dst (LoadF mem));
  6386   ins_cost(150);
  6387   format %{ "loadF $dst, $mem #@loadF" %}
  6388   ins_encode(load_F_enc(dst, mem));
  6389   ins_pipe( ialu_loadI );
  6390 %}
  6392 instruct loadConP_general(mRegP dst, immP src) %{
  6393   match(Set dst src);
  6395   ins_cost(120);
  6396   format %{ "li   $dst, $src #@loadConP_general" %}
  6398   ins_encode %{
  6399     Register dst = $dst$$Register;
  6400     long* value = (long*)$src$$constant;
  6402     if($src->constant_reloc() == relocInfo::metadata_type){
  6403       int klass_index = __ oop_recorder()->find_index((Klass*)value);
  6404       RelocationHolder rspec = metadata_Relocation::spec(klass_index);
  6406       __ relocate(rspec);
  6407       __ patchable_set48(dst, (long)value);
  6408     }else if($src->constant_reloc() == relocInfo::oop_type){
  6409       int oop_index = __ oop_recorder()->find_index((jobject)value);
  6410       RelocationHolder rspec = oop_Relocation::spec(oop_index);
  6412       __ relocate(rspec);
  6413       __ patchable_set48(dst, (long)value);
  6414     } else if ($src->constant_reloc() == relocInfo::none) {
  6415         __ set64(dst, (long)value);
  6417   %}
  6419   ins_pipe( ialu_regI_regI );
  6420 %}
  6422 /*
  6423 instruct loadConP_load(mRegP dst, immP_load src) %{
  6424   match(Set dst src);
  6426   ins_cost(100);
  6427   format %{ "ld     $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
  6429   ins_encode %{
  6431     int con_offset = $constantoffset($src);
  6433     if (Assembler::is_simm16(con_offset)) {
  6434        __ ld($dst$$Register, $constanttablebase, con_offset);
  6435     } else {
  6436        __ set64(AT, con_offset);
  6437        if (UseLoongsonISA) {
  6438           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6439        } else {
  6440           __ daddu(AT, $constanttablebase, AT);
  6441           __ ld($dst$$Register, AT, 0);
  6444   %}
  6446   ins_pipe(ialu_loadI);
  6447 %}
  6448 */
  6450 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
  6451   match(Set dst src);
  6453   ins_cost(80);
  6454   format %{ "li    $dst, $src @ loadConP_no_oop_cheap" %}
  6456   ins_encode %{
  6457     __ set64($dst$$Register, $src$$constant);
  6458   %}
  6460   ins_pipe(ialu_regI_regI);
  6461 %}
  6464 instruct loadConP_poll(mRegP dst, immP_poll src) %{
  6465   match(Set dst src);
  6467   ins_cost(50);
  6468   format %{ "li   $dst, $src #@loadConP_poll" %}
  6470   ins_encode %{
  6471     Register dst = $dst$$Register;
  6472     intptr_t value = (intptr_t)$src$$constant;
  6474     __ set64(dst, (jlong)value);
  6475   %}
  6477   ins_pipe( ialu_regI_regI );
  6478 %}
  6480 instruct loadConP0(mRegP dst, immP0 src)
  6481 %{
  6482   match(Set dst src);
  6484   ins_cost(50);
  6485   format %{ "mov    $dst, R0\t# ptr" %}
  6486   ins_encode %{
  6487      Register dst_reg = $dst$$Register;
  6488      __ daddu(dst_reg, R0, R0);
  6489   %}
  6490   ins_pipe( ialu_regI_regI );
  6491 %}
  6493 instruct loadConN0(mRegN dst, immN0 src) %{
  6494   match(Set dst src);
  6495   format %{ "move    $dst, R0\t# compressed NULL ptr" %}
  6496   ins_encode %{
  6497     __ move($dst$$Register, R0);
  6498   %}
  6499   ins_pipe( ialu_regI_regI );
  6500 %}
  6502 instruct loadConN(mRegN dst, immN src) %{
  6503   match(Set dst src);
  6505   ins_cost(125);
  6506   format %{ "li    $dst, $src\t# compressed ptr @ loadConN" %}
  6507   ins_encode %{
  6508     Register dst = $dst$$Register;
  6509     __ set_narrow_oop(dst, (jobject)$src$$constant);
  6510   %}
  6511   ins_pipe( ialu_regI_regI ); // XXX
  6512 %}
  6514 instruct loadConNKlass(mRegN dst, immNKlass src) %{
  6515   match(Set dst src);
  6517   ins_cost(125);
  6518   format %{ "li    $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
  6519   ins_encode %{
  6520     Register dst = $dst$$Register;
  6521     __ set_narrow_klass(dst, (Klass*)$src$$constant);
  6522   %}
  6523   ins_pipe( ialu_regI_regI ); // XXX
  6524 %}
  6526 //FIXME
  6527 // Tail Call; Jump from runtime stub to Java code.
  6528 // Also known as an 'interprocedural jump'.
  6529 // Target of jump will eventually return to caller.
  6530 // TailJump below removes the return address.
  6531 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
  6532   match(TailCall jump_target method_oop );
  6533   ins_cost(300);
  6534   format %{ "JMP    $jump_target \t# @TailCalljmpInd" %}
  6536   ins_encode %{
  6537     Register target = $jump_target$$Register;
  6538     Register    oop = $method_oop$$Register;
  6540     /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
  6541     __ push(RA);
  6543     __ move(S3, oop);
  6544     __ jr(target);
  6545     __ nop();
  6546   %}
  6548   ins_pipe( pipe_jump );
  6549 %}
  6551 // Create exception oop: created by stack-crawling runtime code.
  6552 // Created exception is now available to this handler, and is setup
  6553 // just prior to jumping to this handler.  No code emitted.
  6554 instruct CreateException( a0_RegP ex_oop )
  6555 %{
  6556   match(Set ex_oop (CreateEx));
  6558   // use the following format syntax
  6559   format %{ "# exception oop is in A0; no code emitted @CreateException" %}
  6560   ins_encode %{
  6561     /* Jin: X86 leaves this function empty */
  6562     __ block_comment("CreateException is empty in X86/MIPS");
  6563   %}
  6564   ins_pipe( empty );
  6565 //  ins_pipe( pipe_jump );
  6566 %}
  6569 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
  6571 - Common try/catch:
  6572  2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
  6573                     |- V0, V1 are created
  6574                     |- T9 <= SharedRuntime::exception_handler_for_return_address
  6575                     `- jr T9
  6576                          `- the caller's exception_handler
  6577                                `- jr OptoRuntime::exception_blob
  6578                                       `- here
  6579 - Rethrow(e.g. 'unwind'):
  6580   * The callee:
  6581      |- an exception is triggered during execution
  6582      `- exits the callee method through RethrowException node
  6583           |- The callee pushes exception_oop(T0) and exception_pc(RA)
  6584           `- The callee jumps to OptoRuntime::rethrow_stub()
  6585   * In OptoRuntime::rethrow_stub:
  6586      |- The VM calls _rethrow_Java to determine the return address in the caller method
  6587      `- exits the stub with tailjmpInd
  6588           |- pops exception_oop(V0) and exception_pc(V1)
  6589           `- jumps to the return address(usually an exception_handler)
  6590   * The caller:
  6591      `- continues processing the exception_blob with V0/V1
  6592 */
  6594 /*
  6595 Disassembling OptoRuntime::rethrow_stub()
  6597 ; locals
  6598    0x2d3bf320: addiu sp, sp, 0xfffffff8
  6599    0x2d3bf324: sw ra, 0x4(sp)
  6600    0x2d3bf328: sw fp, 0x0(sp)
  6601    0x2d3bf32c: addu fp, sp, zero
  6602    0x2d3bf330: addiu sp, sp, 0xfffffff0
  6603    0x2d3bf334: sw ra, 0x8(sp)
  6604    0x2d3bf338: sw t0, 0x4(sp)
  6605    0x2d3bf33c: sw sp, 0x0(sp)
  6607 ; get_thread(S2)
  6608    0x2d3bf340: addu s2, sp, zero
  6609    0x2d3bf344: srl s2, s2, 12
  6610    0x2d3bf348: sll s2, s2, 2
  6611    0x2d3bf34c: lui at, 0x2c85
  6612    0x2d3bf350: addu at, at, s2
  6613    0x2d3bf354: lw s2, 0xffffcc80(at)
  6615    0x2d3bf358: lw s0, 0x0(sp)
  6616    0x2d3bf35c: sw s0, 0x118(s2)    // last_sp -> threa
  6617    0x2d3bf360: sw s2, 0xc(sp)
  6619 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
  6620    0x2d3bf364: lw a0, 0x4(sp)
  6621    0x2d3bf368: lw a1, 0xc(sp)
  6622    0x2d3bf36c: lw a2, 0x8(sp)
  6623   ;; Java_To_Runtime
  6624    0x2d3bf370: lui t9, 0x2c34
  6625    0x2d3bf374: addiu t9, t9, 0xffff8a48
  6626    0x2d3bf378: jalr t9
  6627    0x2d3bf37c: nop
  6629    0x2d3bf380: addu s3, v0, zero     ; S3: SharedRuntime::raw_exception_handler_for_return_address()
  6631    0x2d3bf384: lw s0, 0xc(sp)
  6632    0x2d3bf388: sw zero, 0x118(s0)
  6633    0x2d3bf38c: sw zero, 0x11c(s0)
  6634    0x2d3bf390: lw s1, 0x144(s0)      ; ex_oop: S1
  6635    0x2d3bf394: addu s2, s0, zero
  6636    0x2d3bf398: sw zero, 0x144(s2)
  6637    0x2d3bf39c: lw s0, 0x4(s2)
  6638    0x2d3bf3a0: addiu s4, zero, 0x0
  6639    0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
  6640    0x2d3bf3a8: nop
  6641    0x2d3bf3ac: addiu sp, sp, 0x10
  6642    0x2d3bf3b0: addiu sp, sp, 0x8
  6643    0x2d3bf3b4: lw ra, 0xfffffffc(sp)
  6644    0x2d3bf3b8: lw fp, 0xfffffff8(sp)
  6645    0x2d3bf3bc: lui at, 0x2b48
  6646    0x2d3bf3c0: lw at, 0x100(at)
  6648 ; tailjmpInd: Restores exception_oop & exception_pc
  6649    0x2d3bf3c4: addu v1, ra, zero
  6650    0x2d3bf3c8: addu v0, s1, zero
  6651    0x2d3bf3cc: jr s3
  6652    0x2d3bf3d0: nop
  6653 ; Exception:
  6654    0x2d3bf3d4: lui s1, 0x2cc8    ; generate_forward_exception()
  6655    0x2d3bf3d8: addiu s1, s1, 0x40
  6656    0x2d3bf3dc: addiu s2, zero, 0x0
  6657    0x2d3bf3e0: addiu sp, sp, 0x10
  6658    0x2d3bf3e4: addiu sp, sp, 0x8
  6659    0x2d3bf3e8: lw ra, 0xfffffffc(sp)
  6660    0x2d3bf3ec: lw fp, 0xfffffff8(sp)
  6661    0x2d3bf3f0: lui at, 0x2b48
  6662    0x2d3bf3f4: lw at, 0x100(at)
  6663 ; TailCalljmpInd
  6664               __ push(RA);    ; to be used in generate_forward_exception()
  6665    0x2d3bf3f8: addu t7, s2, zero
  6666    0x2d3bf3fc: jr s1
  6667    0x2d3bf400: nop
  6668 */
  6669 // Rethrow exception:
  6670 // The exception oop will come in the first argument position.
  6671 // Then JUMP (not call) to the rethrow stub code.
  6672 instruct RethrowException()
  6673 %{
  6674   match(Rethrow);
  6676   // use the following format syntax
  6677   format %{ "JMP    rethrow_stub #@RethrowException" %}
  6678   ins_encode %{
  6679     __ block_comment("@ RethrowException");
  6681     cbuf.set_insts_mark();
  6682     cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
  6684     // call OptoRuntime::rethrow_stub to get the exception handler in parent method
  6685     __ patchable_jump((address)OptoRuntime::rethrow_stub());
  6686   %}
  6687   ins_pipe( pipe_jump );
  6688 %}
  6690 // ============================================================================
  6691 // Branch Instructions --- long offset versions
  6693 // Jump Direct
  6694 instruct jmpDir_long(label labl) %{
  6695   match(Goto);
  6696   effect(USE labl);
  6698   ins_cost(300);
  6699   format %{ "JMP    $labl #@jmpDir_long" %}
  6701   ins_encode %{
  6702     Label* L = $labl$$label;
  6703     __ jmp_far(*L);
  6704   %}
  6706   ins_pipe( pipe_jump );
  6707   //ins_pc_relative(1);
  6708 %}
  6710 // Jump Direct Conditional - Label defines a relative address from Jcc+1
  6711 instruct  jmpLoopEnd_long(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
  6712   match(CountedLoopEnd cop (CmpI src1 src2));
  6713   effect(USE labl);
  6715   ins_cost(300);
  6716   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_long" %}
  6717   ins_encode %{
  6718     Register op1 = $src1$$Register;
  6719     Register op2 = $src2$$Register;
  6720     Label*     L = $labl$$label;
  6721     int     flag = $cop$$cmpcode;
  6723     switch(flag) {
  6724       case 0x01: //equal
  6725         __ beq_long(op1, op2, *L);
  6726         break;
  6727       case 0x02: //not_equal
  6728         __ bne_long(op1, op2, *L);
  6729         break;
  6730       case 0x03: //above
  6731         __ slt(AT, op2, op1);
  6732         __ bne_long(AT, R0, *L);
  6733         break;
  6734       case 0x04: //above_equal
  6735         __ slt(AT, op1, op2);
  6736         __ beq_long(AT, R0, *L);
  6737         break;
  6738       case 0x05: //below
  6739         __ slt(AT, op1, op2);
  6740         __ bne_long(AT, R0, *L);
  6741         break;
  6742       case 0x06: //below_equal
  6743         __ slt(AT, op2, op1);
  6744         __ beq_long(AT, R0, *L);
  6745         break;
  6746       default:
  6747         Unimplemented();
  6749   %}
  6750   ins_pipe( pipe_jump );
  6751   ins_pc_relative(1);
  6752 %}
  6754 instruct  jmpLoopEnd_reg_immI_long(cmpOp cop, mRegI src1, immI src2, label labl) %{
  6755   match(CountedLoopEnd cop (CmpI src1 src2));
  6756   effect(USE labl);
  6758   ins_cost(300);
  6759   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI_long" %}
  6760   ins_encode %{
  6761     Register op1 = $src1$$Register;
  6762     Register op2 = AT;
  6763     Label*     L = $labl$$label;
  6764     int     flag = $cop$$cmpcode;
  6766     __ move(op2, $src2$$constant);
  6768     switch(flag) {
  6769       case 0x01: //equal
  6770         __ beq_long(op1, op2, *L);
  6771         break;
  6772       case 0x02: //not_equal
  6773         __ bne_long(op1, op2, *L);
  6774         break;
  6775       case 0x03: //above
  6776         __ slt(AT, op2, op1);
  6777         __ bne_long(AT, R0, *L);
  6778         break;
  6779       case 0x04: //above_equal
  6780         __ slt(AT, op1, op2);
  6781         __ beq_long(AT, R0, *L);
  6782         break;
  6783       case 0x05: //below
  6784         __ slt(AT, op1, op2);
  6785         __ bne_long(AT, R0, *L);
  6786         break;
  6787       case 0x06: //below_equal
  6788         __ slt(AT, op2, op1);
  6789         __ beq_long(AT, R0, *L);
  6790         break;
  6791       default:
  6792         Unimplemented();
  6794   %}
  6795   ins_pipe( pipe_jump );
  6796   ins_pc_relative(1);
  6797 %}
  6800 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
  6801 instruct jmpCon_flags_long(cmpOp cop, FlagsReg cr, label labl) %{
  6802   match(If cop cr);
  6803   effect(USE labl);
  6805   ins_cost(300);
  6806   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags_long" %}
  6808   ins_encode %{
  6809     Label*    L =  $labl$$label;
  6810     switch($cop$$cmpcode) {
  6811       case 0x01: //equal
  6812         __ bne_long(AT, R0, *L);
  6813         break;
  6814       case 0x02: //not equal
  6815         __ beq_long(AT, R0, *L);
  6816         break;
  6817       default:
  6818         Unimplemented();
  6820   %}
  6822   ins_pipe( pipe_jump );
  6823   ins_pc_relative(1);
  6824 %}
  6826 // Conditional jumps
  6827 instruct branchConP_zero_long(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  6828   match(If cmp (CmpP op1 zero));
  6829   effect(USE labl);
  6831   ins_cost(180);
  6832   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero_long" %}
  6834   ins_encode %{
  6835     Register op1 = $op1$$Register;
  6836     Register op2 = R0;
  6837     Label*    L  = $labl$$label;
  6838     int     flag = $cmp$$cmpcode;
  6840     switch(flag) {
  6841       case 0x01: //equal
  6842         __ beq_long(op1, op2, *L);
  6843         break;
  6844       case 0x02: //not_equal
  6845         __ bne_long(op1, op2, *L);
  6846         break;
  6847       default:
  6848         Unimplemented();
  6850   %}
  6852   ins_pc_relative(1);
  6853   ins_pipe( pipe_alu_branch );
  6854 %}
  6856 instruct branchConN2P_zero_long(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  6857   match(If cmp (CmpP (DecodeN op1) zero));
  6858   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6859   effect(USE labl);
  6861   ins_cost(180);
  6862   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero_long" %}
  6864   ins_encode %{
  6865     Register op1 = $op1$$Register;
  6866     Register op2 = R0;
  6867     Label*    L  = $labl$$label;
  6868     int     flag = $cmp$$cmpcode;
  6870     switch(flag)
  6872       case 0x01: //equal
  6873         __ beq_long(op1, op2, *L);
  6874         break;
  6875       case 0x02: //not_equal
  6876         __ bne_long(op1, op2, *L);
  6877         break;
  6878       default:
  6879         Unimplemented();
  6881   %}
  6883   ins_pc_relative(1);
  6884   ins_pipe( pipe_alu_branch );
  6885 %}
  6888 instruct branchConP_long(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  6889   match(If cmp (CmpP op1 op2));
  6890 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  6891   effect(USE labl);
  6893   ins_cost(200);
  6894   format %{ "b$cmp   $op1, $op2, $labl #@branchConP_long" %}
  6896   ins_encode %{
  6897     Register op1 = $op1$$Register;
  6898     Register op2 = $op2$$Register;
  6899     Label*    L  = $labl$$label;
  6900     int     flag = $cmp$$cmpcode;
  6902     switch(flag) {
  6903       case 0x01: //equal
  6904         __ beq_long(op1, op2, *L);
  6905         break;
  6906       case 0x02: //not_equal
  6907         __ bne_long(op1, op2, *L);
  6908         break;
  6909       case 0x03: //above
  6910         __ sltu(AT, op2, op1);
  6911         __ bne_long(R0, AT, *L);
  6912         break;
  6913       case 0x04: //above_equal
  6914         __ sltu(AT, op1, op2);
  6915         __ beq_long(AT, R0, *L);
  6916         break;
  6917       case 0x05: //below
  6918         __ sltu(AT, op1, op2);
  6919         __ bne_long(R0, AT, *L);
  6920         break;
  6921       case 0x06: //below_equal
  6922         __ sltu(AT, op2, op1);
  6923         __ beq_long(AT, R0, *L);
  6924        break;
  6925       default:
  6926           Unimplemented();
  6928   %}
  6930   ins_pc_relative(1);
  6931   ins_pipe( pipe_alu_branch );
  6932 %}
  6934 instruct cmpN_null_branch_long(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  6935   match(If cmp (CmpN op1 null));
  6936   effect(USE labl);
  6938   ins_cost(180);
  6939   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  6940             "BP$cmp   $labl @ cmpN_null_branch_long" %}
  6941   ins_encode %{
  6942     Register op1 = $op1$$Register;
  6943     Register op2 = R0;
  6944     Label*    L  = $labl$$label;
  6945     int     flag = $cmp$$cmpcode;
  6947     switch(flag) {
  6948     case 0x01: //equal
  6949       __ beq_long(op1, op2, *L);
  6950       break;
  6951     case 0x02: //not_equal
  6952       __ bne_long(op1, op2, *L);
  6953       break;
  6954     default:
  6955           Unimplemented();
  6957   %}
  6958 //TODO: pipe_branchP or create pipe_branchN LEE
  6959   ins_pc_relative(1);
  6960   ins_pipe( pipe_alu_branch );
  6961 %}
  6963 instruct cmpN_reg_branch_long(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  6964   match(If cmp (CmpN op1 op2));
  6965   effect(USE labl);
  6967   ins_cost(180);
  6968   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  6969             "BP$cmp   $labl @ cmpN_reg_branch_long" %}
  6970   ins_encode %{
  6971     Register op1_reg = $op1$$Register;
  6972     Register op2_reg = $op2$$Register;
  6973     Label*    L  = $labl$$label;
  6974     int     flag = $cmp$$cmpcode;
  6976     switch(flag) {
  6977     case 0x01: //equal
  6978       __ beq_long(op1_reg, op2_reg, *L);
  6979       break;
  6980     case 0x02: //not_equal
  6981       __ bne_long(op1_reg, op2_reg, *L);
  6982       break;
  6983     case 0x03: //above
  6984       __ sltu(AT, op2_reg, op1_reg);
  6985       __ bne_long(R0, AT, *L);
  6986       break;
  6987     case 0x04: //above_equal
  6988       __ sltu(AT, op1_reg, op2_reg);
  6989       __ beq_long(AT, R0, *L);
  6990       break;
  6991     case 0x05: //below
  6992       __ sltu(AT, op1_reg, op2_reg);
  6993       __ bne_long(R0, AT, *L);
  6994       break;
  6995     case 0x06: //below_equal
  6996       __ sltu(AT, op2_reg, op1_reg);
  6997       __ beq_long(AT, R0, *L);
  6998       break;
  6999     default:
  7000       Unimplemented();
  7002   %}
  7003   ins_pc_relative(1);
  7004   ins_pipe( pipe_alu_branch );
  7005 %}
  7007 instruct branchConIU_reg_reg_long(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  7008   match( If cmp (CmpU src1 src2) );
  7009   effect(USE labl);
  7010   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg_long" %}
  7012   ins_encode %{
  7013     Register op1 = $src1$$Register;
  7014     Register op2 = $src2$$Register;
  7015     Label*     L = $labl$$label;
  7016     int     flag = $cmp$$cmpcode;
  7018     switch(flag) {
  7019       case 0x01: //equal
  7020         __ beq_long(op1, op2, *L);
  7021         break;
  7022       case 0x02: //not_equal
  7023         __ bne_long(op1, op2, *L);
  7024         break;
  7025       case 0x03: //above
  7026         __ sltu(AT, op2, op1);
  7027         __ bne_long(AT, R0, *L);
  7028         break;
  7029       case 0x04: //above_equal
  7030         __ sltu(AT, op1, op2);
  7031         __ beq_long(AT, R0, *L);
  7032         break;
  7033       case 0x05: //below
  7034         __ sltu(AT, op1, op2);
  7035         __ bne_long(AT, R0, *L);
  7036         break;
  7037       case 0x06: //below_equal
  7038         __ sltu(AT, op2, op1);
  7039         __ beq_long(AT, R0, *L);
  7040         break;
  7041       default:
  7042         Unimplemented();
  7044   %}
  7046   ins_pc_relative(1);
  7047   ins_pipe( pipe_alu_branch );
  7048 %}
  7051 instruct branchConIU_reg_imm_long(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  7052   match( If cmp (CmpU src1 src2) );
  7053   effect(USE labl);
  7054   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm_long" %}
  7056   ins_encode %{
  7057     Register op1 = $src1$$Register;
  7058     int      val = $src2$$constant;
  7059     Label*     L = $labl$$label;
  7060     int     flag = $cmp$$cmpcode;
  7062     __ move(AT, val);
  7063     switch(flag) {
  7064       case 0x01: //equal
  7065         __ beq_long(op1, AT, *L);
  7066         break;
  7067       case 0x02: //not_equal
  7068         __ bne_long(op1, AT, *L);
  7069         break;
  7070       case 0x03: //above
  7071         __ sltu(AT, AT, op1);
  7072         __ bne_long(R0, AT, *L);
  7073         break;
  7074       case 0x04: //above_equal
  7075         __ sltu(AT, op1, AT);
  7076         __ beq_long(AT, R0, *L);
  7077         break;
  7078       case 0x05: //below
  7079         __ sltu(AT, op1, AT);
  7080         __ bne_long(R0, AT, *L);
  7081         break;
  7082       case 0x06: //below_equal
  7083         __ sltu(AT, AT, op1);
  7084         __ beq_long(AT, R0, *L);
  7085        break;
  7086       default:
  7087         Unimplemented();
  7089   %}
  7091   ins_pc_relative(1);
  7092   ins_pipe( pipe_alu_branch );
  7093 %}
  7095 instruct branchConI_reg_reg_long(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  7096   match( If cmp (CmpI src1 src2) );
  7097   effect(USE labl);
  7098   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg_long" %}
  7100   ins_encode %{
  7101     Register op1 = $src1$$Register;
  7102     Register op2 = $src2$$Register;
  7103     Label*     L = $labl$$label;
  7104     int     flag = $cmp$$cmpcode;
  7106     switch(flag) {
  7107       case 0x01: //equal
  7108         __ beq_long(op1, op2, *L);
  7109         break;
  7110       case 0x02: //not_equal
  7111         __ bne_long(op1, op2, *L);
  7112         break;
  7113       case 0x03: //above
  7114         __ slt(AT, op2, op1);
  7115         __ bne_long(R0, AT, *L);
  7116         break;
  7117       case 0x04: //above_equal
  7118         __ slt(AT, op1, op2);
  7119         __ beq_long(AT, R0, *L);
  7120         break;
  7121       case 0x05: //below
  7122         __ slt(AT, op1, op2);
  7123         __ bne_long(R0, AT, *L);
  7124         break;
  7125       case 0x06: //below_equal
  7126         __ slt(AT, op2, op1);
  7127         __ beq_long(AT, R0, *L);
  7128         break;
  7129       default:
  7130         Unimplemented();
  7132   %}
  7134   ins_pc_relative(1);
  7135   ins_pipe( pipe_alu_branch );
  7136 %}
  7138 instruct branchConI_reg_imm0_long(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  7139   match( If cmp (CmpI src1 src2) );
  7140   effect(USE labl);
  7141   ins_cost(170);
  7142   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0_long" %}
  7144   ins_encode %{
  7145     Register op1 = $src1$$Register;
  7146     Label*     L =  $labl$$label;
  7147     int     flag = $cmp$$cmpcode;
  7149     switch(flag) {
  7150       case 0x01: //equal
  7151         __ beq_long(op1, R0, *L);
  7152         break;
  7153       case 0x02: //not_equal
  7154         __ bne_long(op1, R0, *L);
  7155         break;
  7156       case 0x03: //greater
  7157         __ slt(AT, R0, op1);
  7158         __ bne_long(R0, AT, *L);
  7159         break;
  7160       case 0x04: //greater_equal
  7161         __ slt(AT, op1, R0);
  7162         __ beq_long(AT, R0, *L);
  7163         break;
  7164       case 0x05: //less
  7165         __ slt(AT, op1, R0);
  7166         __ bne_long(R0, AT, *L);
  7167         break;
  7168       case 0x06: //less_equal
  7169         __ slt(AT, R0, op1);
  7170         __ beq_long(AT, R0, *L);
  7171         break;
  7172       default:
  7173         Unimplemented();
  7175   %}
  7177   ins_pc_relative(1);
  7178   ins_pipe( pipe_alu_branch );
  7179 %}
  7181 instruct branchConI_reg_imm_long(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  7182   match( If cmp (CmpI src1 src2) );
  7183   effect(USE labl);
  7184   ins_cost(200);
  7185   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm_long" %}
  7187   ins_encode %{
  7188     Register op1 = $src1$$Register;
  7189     int      val = $src2$$constant;
  7190     Label*     L =  $labl$$label;
  7191     int     flag = $cmp$$cmpcode;
  7193     __ move(AT, val);
  7194     switch(flag) {
  7195       case 0x01: //equal
  7196         __ beq_long(op1, AT, *L);
  7197         break;
  7198       case 0x02: //not_equal
  7199         __ bne_long(op1, AT, *L);
  7200         break;
  7201       case 0x03: //greater
  7202         __ slt(AT, AT, op1);
  7203         __ bne_long(R0, AT, *L);
  7204         break;
  7205       case 0x04: //greater_equal
  7206         __ slt(AT, op1, AT);
  7207         __ beq_long(AT, R0, *L);
  7208         break;
  7209       case 0x05: //less
  7210         __ slt(AT, op1, AT);
  7211         __ bne_long(R0, AT, *L);
  7212         break;
  7213       case 0x06: //less_equal
  7214         __ slt(AT, AT, op1);
  7215         __ beq_long(AT, R0, *L);
  7216        break;
  7217       default:
  7218           Unimplemented();
  7220   %}
  7222   ins_pc_relative(1);
  7223   ins_pipe( pipe_alu_branch );
  7224 %}
  7226 instruct branchConIU_reg_imm0_long(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  7227   match( If cmp (CmpU src1 zero) );
  7228   effect(USE labl);
  7229   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0_long" %}
  7231   ins_encode %{
  7232     Register op1 = $src1$$Register;
  7233     Label*     L = $labl$$label;
  7234     int     flag = $cmp$$cmpcode;
  7236     switch(flag) {
  7237       case 0x01: //equal
  7238         __ beq_long(op1, R0, *L);
  7239         break;
  7240       case 0x02: //not_equal
  7241         __ bne_long(op1, R0, *L);
  7242         break;
  7243       case 0x03: //above
  7244         __ bne_long(R0, op1, *L);
  7245         break;
  7246       case 0x04: //above_equal
  7247         __ beq_long(R0, R0, *L);
  7248         break;
  7249       case 0x05: //below
  7250         return;
  7251         break;
  7252       case 0x06: //below_equal
  7253         __ beq_long(op1, R0, *L);
  7254         break;
  7255       default:
  7256         Unimplemented();
  7258   %}
  7260   ins_pc_relative(1);
  7261   ins_pipe( pipe_alu_branch );
  7262 %}
  7265 instruct branchConIU_reg_immI16_long(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  7266   match( If cmp (CmpU src1 src2) );
  7267   effect(USE labl);
  7268   ins_cost(180);
  7269   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16_long" %}
  7271   ins_encode %{
  7272     Register op1 = $src1$$Register;
  7273     int      val = $src2$$constant;
  7274     Label*     L = $labl$$label;
  7275     int     flag = $cmp$$cmpcode;
  7277     switch(flag) {
  7278       case 0x01: //equal
  7279         __ move(AT, val);
  7280         __ beq_long(op1, AT, *L);
  7281         break;
  7282       case 0x02: //not_equal
  7283         __ move(AT, val);
  7284         __ bne_long(op1, AT, *L);
  7285         break;
  7286       case 0x03: //above
  7287         __ move(AT, val);
  7288         __ sltu(AT, AT, op1);
  7289         __ bne_long(R0, AT, *L);
  7290         break;
  7291       case 0x04: //above_equal
  7292         __ sltiu(AT, op1, val);
  7293         __ beq_long(AT, R0, *L);
  7294         break;
  7295       case 0x05: //below
  7296         __ sltiu(AT, op1, val);
  7297         __ bne_long(R0, AT, *L);
  7298         break;
  7299       case 0x06: //below_equal
  7300         __ move(AT, val);
  7301         __ sltu(AT, AT, op1);
  7302         __ beq_long(AT, R0, *L);
  7303         break;
  7304       default:
  7305         Unimplemented();
  7307   %}
  7309   ins_pc_relative(1);
  7310   ins_pipe( pipe_alu_branch );
  7311 %}
  7314 instruct branchConL_regL_regL_long(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  7315   match( If cmp (CmpL src1 src2) );
  7316   effect(USE labl);
  7317   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL_long" %}
  7318   ins_cost(250);
  7320   ins_encode %{
  7321     Register opr1_reg = as_Register($src1$$reg);
  7322     Register opr2_reg = as_Register($src2$$reg);
  7324     Label*   target = $labl$$label;
  7325     int     flag = $cmp$$cmpcode;
  7327     switch(flag) {
  7328       case 0x01: //equal
  7329         __ beq_long(opr1_reg, opr2_reg, *target);
  7330         break;
  7332       case 0x02: //not_equal
  7333         __ bne_long(opr1_reg, opr2_reg, *target);
  7334         break;
  7336       case 0x03: //greater
  7337         __ slt(AT, opr2_reg, opr1_reg);
  7338         __ bne_long(AT, R0, *target);
  7339         break;
  7341       case 0x04: //greater_equal
  7342         __ slt(AT, opr1_reg, opr2_reg);
  7343         __ beq_long(AT, R0, *target);
  7344         break;
  7346       case 0x05: //less
  7347         __ slt(AT, opr1_reg, opr2_reg);
  7348         __ bne_long(AT, R0, *target);
  7349         break;
  7351       case 0x06: //less_equal
  7352         __ slt(AT, opr2_reg, opr1_reg);
  7353         __ beq_long(AT, R0, *target);
  7354         break;
  7356       default:
  7357         Unimplemented();
  7359   %}
  7362   ins_pc_relative(1);
  7363   ins_pipe( pipe_alu_branch );
  7364 %}
  7366 instruct branchConL_regL_immL0_long(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  7367   match( If cmp (CmpL src1 zero) );
  7368   effect(USE labl);
  7369   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0_long" %}
  7370   ins_cost(150);
  7372   ins_encode %{
  7373     Register opr1_reg = as_Register($src1$$reg);
  7374     Register opr2_reg = R0;
  7376     Label*   target = $labl$$label;
  7377     int     flag = $cmp$$cmpcode;
  7379     switch(flag) {
  7380       case 0x01: //equal
  7381         __ beq_long(opr1_reg, opr2_reg, *target);
  7382         break;
  7384       case 0x02: //not_equal
  7385         __ bne_long(opr1_reg, opr2_reg, *target);
  7386         break;
  7388       case 0x03: //greater
  7389         __ slt(AT, opr2_reg, opr1_reg);
  7390         __ bne_long(AT, R0, *target);
  7391         break;
  7393       case 0x04: //greater_equal
  7394         __ slt(AT, opr1_reg, opr2_reg);
  7395         __ beq_long(AT, R0, *target);
  7396         break;
  7398       case 0x05: //less
  7399         __ slt(AT, opr1_reg, opr2_reg);
  7400         __ bne_long(AT, R0, *target);
  7401         break;
  7403       case 0x06: //less_equal
  7404         __ slt(AT, opr2_reg, opr1_reg);
  7405         __ beq_long(AT, R0, *target);
  7406         break;
  7408       default:
  7409         Unimplemented();
  7411   %}
  7414   ins_pc_relative(1);
  7415   ins_pipe( pipe_alu_branch );
  7416 %}
  7418 instruct branchConL_regL_immL_long(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  7419   match( If cmp (CmpL src1 src2) );
  7420   effect(USE labl);
  7421   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL_long" %}
  7422   ins_cost(180);
  7424   ins_encode %{
  7425     Register opr1_reg = as_Register($src1$$reg);
  7426     Register opr2_reg = AT;
  7428     Label*   target = $labl$$label;
  7429     int     flag = $cmp$$cmpcode;
  7431     __ set64(opr2_reg, $src2$$constant);
  7433     switch(flag) {
  7434       case 0x01: //equal
  7435         __ beq_long(opr1_reg, opr2_reg, *target);
  7436         break;
  7438       case 0x02: //not_equal
  7439         __ bne_long(opr1_reg, opr2_reg, *target);
  7440         break;
  7442       case 0x03: //greater
  7443         __ slt(AT, opr2_reg, opr1_reg);
  7444         __ bne_long(AT, R0, *target);
  7445         break;
  7447       case 0x04: //greater_equal
  7448         __ slt(AT, opr1_reg, opr2_reg);
  7449         __ beq_long(AT, R0, *target);
  7450         break;
  7452       case 0x05: //less
  7453         __ slt(AT, opr1_reg, opr2_reg);
  7454         __ bne_long(AT, R0, *target);
  7455         break;
  7457       case 0x06: //less_equal
  7458         __ slt(AT, opr2_reg, opr1_reg);
  7459         __ beq_long(AT, R0, *target);
  7460         break;
  7462       default:
  7463         Unimplemented();
  7465   %}
  7468   ins_pc_relative(1);
  7469   ins_pipe( pipe_alu_branch );
  7470 %}
  7473 //FIXME
  7474 instruct branchConF_reg_reg_long(cmpOp cmp, regF src1, regF src2, label labl) %{
  7475   match( If cmp (CmpF src1 src2) );
  7476   effect(USE labl);
  7477   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg_long" %}
  7479   ins_encode %{
  7480     FloatRegister reg_op1 = $src1$$FloatRegister;
  7481     FloatRegister reg_op2 = $src2$$FloatRegister;
  7482     Label*     L =  $labl$$label;
  7483     int     flag = $cmp$$cmpcode;
  7485     switch(flag) {
  7486       case 0x01: //equal
  7487         __ c_eq_s(reg_op1, reg_op2);
  7488         __ bc1t_long(*L);
  7489         break;
  7490       case 0x02: //not_equal
  7491         __ c_eq_s(reg_op1, reg_op2);
  7492         __ bc1f_long(*L);
  7493         break;
  7494       case 0x03: //greater
  7495         __ c_ule_s(reg_op1, reg_op2);
  7496         __ bc1f_long(*L);
  7497         break;
  7498       case 0x04: //greater_equal
  7499         __ c_ult_s(reg_op1, reg_op2);
  7500         __ bc1f_long(*L);
  7501         break;
  7502       case 0x05: //less
  7503         __ c_ult_s(reg_op1, reg_op2);
  7504         __ bc1t_long(*L);
  7505         break;
  7506       case 0x06: //less_equal
  7507         __ c_ule_s(reg_op1, reg_op2);
  7508         __ bc1t_long(*L);
  7509         break;
  7510       default:
  7511         Unimplemented();
  7513   %}
  7515   ins_pc_relative(1);
  7516   ins_pipe(pipe_slow);
  7517 %}
  7519 instruct branchConD_reg_reg_long(cmpOp cmp, regD src1, regD src2, label labl) %{
  7520   match( If cmp (CmpD src1 src2) );
  7521   effect(USE labl);
  7522   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg_long" %}
  7524   ins_encode %{
  7525     FloatRegister reg_op1 = $src1$$FloatRegister;
  7526     FloatRegister reg_op2 = $src2$$FloatRegister;
  7527     Label*     L =  $labl$$label;
  7528     int     flag = $cmp$$cmpcode;
  7530     switch(flag) {
  7531       case 0x01: //equal
  7532         __ c_eq_d(reg_op1, reg_op2);
  7533         __ bc1t_long(*L);
  7534         break;
  7535       case 0x02: //not_equal
  7536         //2016/4/19 aoqi: c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
  7537         __ c_eq_d(reg_op1, reg_op2);
  7538         __ bc1f_long(*L);
  7539         break;
  7540       case 0x03: //greater
  7541         __ c_ule_d(reg_op1, reg_op2);
  7542         __ bc1f_long(*L);
  7543         break;
  7544       case 0x04: //greater_equal
  7545         __ c_ult_d(reg_op1, reg_op2);
  7546         __ bc1f_long(*L);
  7547         break;
  7548       case 0x05: //less
  7549         __ c_ult_d(reg_op1, reg_op2);
  7550         __ bc1t_long(*L);
  7551         break;
  7552       case 0x06: //less_equal
  7553         __ c_ule_d(reg_op1, reg_op2);
  7554         __ bc1t_long(*L);
  7555         break;
  7556       default:
  7557         Unimplemented();
  7559   %}
  7561   ins_pc_relative(1);
  7562   ins_pipe(pipe_slow);
  7563 %}
  7566 // ============================================================================
  7567 // Branch Instructions -- short offset versions
  7569 // Jump Direct
  7570 instruct jmpDir_short(label labl) %{
  7571   match(Goto);
  7572   effect(USE labl);
  7574   ins_cost(300);
  7575   format %{ "JMP    $labl #@jmpDir_short" %}
  7577   ins_encode %{
  7578     Label &L = *($labl$$label);
  7579     if(&L)
  7580        __ b(L);
  7581     else
  7582        __ b(int(0));
  7583     __ nop();
  7584   %}
  7586     ins_pipe( pipe_jump );
  7587     ins_pc_relative(1);
  7588     ins_short_branch(1);
  7589 %}
  7591 // Jump Direct Conditional - Label defines a relative address from Jcc+1
  7592 instruct  jmpLoopEnd_short(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
  7593   match(CountedLoopEnd cop (CmpI src1 src2));
  7594   effect(USE labl);
  7596   ins_cost(300);
  7597   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_short" %}
  7598   ins_encode %{
  7599     Register op1 = $src1$$Register;
  7600     Register op2 = $src2$$Register;
  7601     Label     &L = *($labl$$label);
  7602     int     flag = $cop$$cmpcode;
  7604     switch(flag) {
  7605       case 0x01: //equal
  7606         if (&L)
  7607           __ beq(op1, op2, L);
  7608         else
  7609           __ beq(op1, op2, (int)0);
  7610         break;
  7611       case 0x02: //not_equal
  7612         if (&L)
  7613           __ bne(op1, op2, L);
  7614         else
  7615           __ bne(op1, op2, (int)0);
  7616         break;
  7617       case 0x03: //above
  7618         __ slt(AT, op2, op1);
  7619         if(&L)
  7620           __ bne(AT, R0, L);
  7621         else
  7622           __ bne(AT, R0, (int)0);
  7623         break;
  7624       case 0x04: //above_equal
  7625         __ slt(AT, op1, op2);
  7626         if(&L)
  7627           __ beq(AT, R0, L);
  7628         else
  7629           __ beq(AT, R0, (int)0);
  7630         break;
  7631       case 0x05: //below
  7632         __ slt(AT, op1, op2);
  7633         if(&L)
  7634           __ bne(AT, R0, L);
  7635         else
  7636           __ bne(AT, R0, (int)0);
  7637         break;
  7638       case 0x06: //below_equal
  7639         __ slt(AT, op2, op1);
  7640         if(&L)
  7641           __ beq(AT, R0, L);
  7642         else
  7643           __ beq(AT, R0, (int)0);
  7644         break;
  7645       default:
  7646         Unimplemented();
  7648     __ nop();
  7649   %}
  7650   ins_pipe( pipe_jump );
  7651   ins_pc_relative(1);
  7652   ins_short_branch(1);
  7653 %}
  7655 instruct  jmpLoopEnd_reg_immI_short(cmpOp cop, mRegI src1, immI src2, label labl) %{
  7656   match(CountedLoopEnd cop (CmpI src1 src2));
  7657   effect(USE labl);
  7659   ins_cost(300);
  7660   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI_short" %}
  7661   ins_encode %{
  7662     Register op1 = $src1$$Register;
  7663     Register op2 = AT;
  7664     Label     &L = *($labl$$label);
  7665     int     flag = $cop$$cmpcode;
  7667     __ move(op2, $src2$$constant);
  7669     switch(flag) {
  7670       case 0x01: //equal
  7671         if (&L)
  7672           __ beq(op1, op2, L);
  7673         else
  7674           __ beq(op1, op2, (int)0);
  7675         break;
  7676       case 0x02: //not_equal
  7677         if (&L)
  7678           __ bne(op1, op2, L);
  7679         else
  7680           __ bne(op1, op2, (int)0);
  7681         break;
  7682       case 0x03: //above
  7683         __ slt(AT, op2, op1);
  7684         if(&L)
  7685           __ bne(AT, R0, L);
  7686         else
  7687           __ bne(AT, R0, (int)0);
  7688         break;
  7689       case 0x04: //above_equal
  7690         __ slt(AT, op1, op2);
  7691         if(&L)
  7692           __ beq(AT, R0, L);
  7693         else
  7694           __ beq(AT, R0, (int)0);
  7695         break;
  7696       case 0x05: //below
  7697         __ slt(AT, op1, op2);
  7698         if(&L)
  7699           __ bne(AT, R0, L);
  7700         else
  7701           __ bne(AT, R0, (int)0);
  7702         break;
  7703       case 0x06: //below_equal
  7704         __ slt(AT, op2, op1);
  7705         if(&L)
  7706           __ beq(AT, R0, L);
  7707         else
  7708           __ beq(AT, R0, (int)0);
  7709         break;
  7710       default:
  7711         Unimplemented();
  7713     __ nop();
  7714   %}
  7715   ins_pipe( pipe_jump );
  7716   ins_pc_relative(1);
  7717   ins_short_branch(1);
  7718 %}
  7721 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
  7722 instruct jmpCon_flags_short(cmpOp cop, FlagsReg cr, label labl) %{
  7723   match(If cop cr);
  7724   effect(USE labl);
  7726   ins_cost(300);
  7727   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags_short" %}
  7729   ins_encode %{
  7730     Label    &L =  *($labl$$label);
  7731     switch($cop$$cmpcode) {
  7732       case 0x01: //equal
  7733         if (&L)
  7734           __ bne(AT, R0, L);
  7735         else
  7736           __ bne(AT, R0, (int)0);
  7737         break;
  7738       case 0x02: //not equal
  7739         if (&L)
  7740           __ beq(AT, R0, L);
  7741         else
  7742           __ beq(AT, R0, (int)0);
  7743         break;
  7744       default:
  7745         Unimplemented();
  7747     __ nop();
  7748   %}
  7750   ins_pipe( pipe_jump );
  7751   ins_pc_relative(1);
  7752   ins_short_branch(1);
  7753 %}
  7755 // Conditional jumps
  7756 instruct branchConP_zero_short(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  7757   match(If cmp (CmpP op1 zero));
  7758   effect(USE labl);
  7760   ins_cost(180);
  7761   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero_short" %}
  7763   ins_encode %{
  7764     Register op1 = $op1$$Register;
  7765     Register op2 = R0;
  7766     Label    &L  = *($labl$$label);
  7767     int     flag = $cmp$$cmpcode;
  7769     switch(flag) {
  7770       case 0x01: //equal
  7771         if (&L)
  7772           __ beq(op1, op2, L);
  7773         else
  7774           __ beq(op1, op2, (int)0);
  7775         break;
  7776       case 0x02: //not_equal
  7777         if (&L)
  7778           __ bne(op1, op2, L);
  7779         else
  7780           __ bne(op1, op2, (int)0);
  7781         break;
  7782       default:
  7783         Unimplemented();
  7785     __ nop();
  7786   %}
  7788   ins_pc_relative(1);
  7789   ins_pipe( pipe_alu_branch );
  7790   ins_short_branch(1);
  7791 %}
  7793 instruct branchConN2P_zero_short(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  7794   match(If cmp (CmpP (DecodeN op1) zero));
  7795   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  7796   effect(USE labl);
  7798   ins_cost(180);
  7799   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero_short" %}
  7801   ins_encode %{
  7802     Register op1 = $op1$$Register;
  7803     Register op2 = R0;
  7804     Label    &L  = *($labl$$label);
  7805     int     flag = $cmp$$cmpcode;
  7807     switch(flag)
  7809       case 0x01: //equal
  7810         if (&L)
  7811           __ beq(op1, op2, L);
  7812         else
  7813           __ beq(op1, op2, (int)0);
  7814         break;
  7815       case 0x02: //not_equal
  7816         if (&L)
  7817           __ bne(op1, op2, L);
  7818         else
  7819           __ bne(op1, op2, (int)0);
  7820         break;
  7821       default:
  7822         Unimplemented();
  7824     __ nop();
  7825   %}
  7827   ins_pc_relative(1);
  7828   ins_pipe( pipe_alu_branch );
  7829   ins_short_branch(1);
  7830 %}
  7833 instruct branchConP_short(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  7834   match(If cmp (CmpP op1 op2));
  7835 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  7836   effect(USE labl);
  7838   ins_cost(200);
  7839   format %{ "b$cmp   $op1, $op2, $labl #@branchConP_short" %}
  7841   ins_encode %{
  7842     Register op1 = $op1$$Register;
  7843     Register op2 = $op2$$Register;
  7844     Label    &L  = *($labl$$label);
  7845     int     flag = $cmp$$cmpcode;
  7847     switch(flag) {
  7848       case 0x01: //equal
  7849         if (&L)
  7850           __ beq(op1, op2, L);
  7851         else
  7852           __ beq(op1, op2, (int)0);
  7853         break;
  7854       case 0x02: //not_equal
  7855         if (&L)
  7856           __ bne(op1, op2, L);
  7857         else
  7858           __ bne(op1, op2, (int)0);
  7859         break;
  7860       case 0x03: //above
  7861         __ sltu(AT, op2, op1);
  7862         if(&L)
  7863           __ bne(R0, AT, L);
  7864         else
  7865                 __ bne(R0, AT, (int)0);
  7866         break;
  7867       case 0x04: //above_equal
  7868         __ sltu(AT, op1, op2);
  7869         if(&L)
  7870                  __ beq(AT, R0, L);
  7871         else
  7872                  __ beq(AT, R0, (int)0);
  7873         break;
  7874       case 0x05: //below
  7875         __ sltu(AT, op1, op2);
  7876         if(&L)
  7877            __ bne(R0, AT, L);
  7878         else
  7879            __ bne(R0, AT, (int)0);
  7880         break;
  7881       case 0x06: //below_equal
  7882         __ sltu(AT, op2, op1);
  7883         if(&L)
  7884           __ beq(AT, R0, L);
  7885         else
  7886           __ beq(AT, R0, (int)0);
  7887        break;
  7888       default:
  7889           Unimplemented();
  7891     __ nop();
  7892   %}
  7894   ins_pc_relative(1);
  7895   ins_pipe( pipe_alu_branch );
  7896   ins_short_branch(1);
  7897 %}
  7899 instruct cmpN_null_branch_short(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  7900   match(If cmp (CmpN op1 null));
  7901   effect(USE labl);
  7903   ins_cost(180);
  7904   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  7905             "BP$cmp   $labl @ cmpN_null_branch_short" %}
  7906   ins_encode %{
  7907     Register op1 = $op1$$Register;
  7908     Register op2 = R0;
  7909     Label    &L  = *($labl$$label);
  7910     int     flag = $cmp$$cmpcode;
  7912     switch(flag) {
  7913     case 0x01: //equal
  7914       if (&L)
  7915         __ beq(op1, op2, L);
  7916       else
  7917         __ beq(op1, op2, (int)0);
  7918       break;
  7919     case 0x02: //not_equal
  7920       if (&L)
  7921         __ bne(op1, op2, L);
  7922       else
  7923         __ bne(op1, op2, (int)0);
  7924       break;
  7925     default:
  7926           Unimplemented();
  7928     __ nop();
  7929   %}
  7930 //TODO: pipe_branchP or create pipe_branchN LEE
  7931   ins_pc_relative(1);
  7932   ins_pipe( pipe_alu_branch );
  7933   ins_short_branch(1);
  7934 %}
  7936 instruct cmpN_reg_branch_short(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  7937   match(If cmp (CmpN op1 op2));
  7938   effect(USE labl);
  7940   ins_cost(180);
  7941   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  7942             "BP$cmp   $labl @ cmpN_reg_branch_short" %}
  7943   ins_encode %{
  7944     Register op1_reg = $op1$$Register;
  7945     Register op2_reg = $op2$$Register;
  7946     Label    &L  = *($labl$$label);
  7947     int     flag = $cmp$$cmpcode;
  7949     switch(flag) {
  7950     case 0x01: //equal
  7951       if (&L)
  7952         __ beq(op1_reg, op2_reg, L);
  7953       else
  7954         __ beq(op1_reg, op2_reg, (int)0);
  7955       break;
  7956     case 0x02: //not_equal
  7957       if (&L)
  7958         __ bne(op1_reg, op2_reg, L);
  7959       else
  7960         __ bne(op1_reg, op2_reg, (int)0);
  7961       break;
  7962     case 0x03: //above
  7963       __ sltu(AT, op2_reg, op1_reg);
  7964       if(&L)
  7965         __ bne(R0, AT, L);
  7966       else
  7967         __ bne(R0, AT, (int)0);
  7968       break;
  7969     case 0x04: //above_equal
  7970       __ sltu(AT, op1_reg, op2_reg);
  7971       if(&L)
  7972         __ beq(AT, R0, L);
  7973       else
  7974         __ beq(AT, R0, (int)0);
  7975       break;
  7976     case 0x05: //below
  7977       __ sltu(AT, op1_reg, op2_reg);
  7978       if(&L)
  7979         __ bne(R0, AT, L);
  7980       else
  7981         __ bne(R0, AT, (int)0);
  7982       break;
  7983     case 0x06: //below_equal
  7984       __ sltu(AT, op2_reg, op1_reg);
  7985       if(&L)
  7986         __ beq(AT, R0, L);
  7987       else
  7988         __ beq(AT, R0, (int)0);
  7989       break;
  7990     default:
  7991       Unimplemented();
  7993     __ nop();
  7994   %}
  7995   ins_pc_relative(1);
  7996   ins_pipe( pipe_alu_branch );
  7997   ins_short_branch(1);
  7998 %}
  8000 instruct branchConIU_reg_reg_short(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  8001   match( If cmp (CmpU src1 src2) );
  8002   effect(USE labl);
  8003   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg_short" %}
  8005   ins_encode %{
  8006     Register op1 = $src1$$Register;
  8007     Register op2 = $src2$$Register;
  8008     Label     &L = *($labl$$label);
  8009     int     flag = $cmp$$cmpcode;
  8011     switch(flag) {
  8012       case 0x01: //equal
  8013         if (&L)
  8014           __ beq(op1, op2, L);
  8015         else
  8016           __ beq(op1, op2, (int)0);
  8017         break;
  8018       case 0x02: //not_equal
  8019         if (&L)
  8020           __ bne(op1, op2, L);
  8021         else
  8022           __ bne(op1, op2, (int)0);
  8023         break;
  8024       case 0x03: //above
  8025         __ sltu(AT, op2, op1);
  8026         if(&L)
  8027           __ bne(AT, R0, L);
  8028         else
  8029                 __ bne(AT, R0, (int)0);
  8030         break;
  8031       case 0x04: //above_equal
  8032         __ sltu(AT, op1, op2);
  8033         if(&L)
  8034           __ beq(AT, R0, L);
  8035         else
  8036                 __ beq(AT, R0, (int)0);
  8037         break;
  8038       case 0x05: //below
  8039         __ sltu(AT, op1, op2);
  8040         if(&L)
  8041            __ bne(AT, R0, L);
  8042         else
  8043            __ bne(AT, R0, (int)0);
  8044         break;
  8045       case 0x06: //below_equal
  8046         __ sltu(AT, op2, op1);
  8047         if(&L)
  8048           __ beq(AT, R0, L);
  8049         else
  8050           __ beq(AT, R0, (int)0);
  8051         break;
  8052       default:
  8053         Unimplemented();
  8055     __ nop();
  8056   %}
  8058   ins_pc_relative(1);
  8059   ins_pipe( pipe_alu_branch );
  8060   ins_short_branch(1);
  8061 %}
  8064 instruct branchConIU_reg_imm_short(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  8065   match( If cmp (CmpU src1 src2) );
  8066   effect(USE labl);
  8067   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm_short" %}
  8069   ins_encode %{
  8070     Register op1 = $src1$$Register;
  8071     int      val = $src2$$constant;
  8072     Label     &L = *($labl$$label);
  8073     int     flag = $cmp$$cmpcode;
  8075     __ move(AT, val);
  8076     switch(flag) {
  8077       case 0x01: //equal
  8078         if (&L)
  8079           __ beq(op1, AT, L);
  8080         else
  8081           __ beq(op1, AT, (int)0);
  8082         break;
  8083       case 0x02: //not_equal
  8084         if (&L)
  8085           __ bne(op1, AT, L);
  8086         else
  8087           __ bne(op1, AT, (int)0);
  8088         break;
  8089       case 0x03: //above
  8090         __ sltu(AT, AT, op1);
  8091         if(&L)
  8092           __ bne(R0, AT, L);
  8093         else
  8094                 __ bne(R0, AT, (int)0);
  8095         break;
  8096       case 0x04: //above_equal
  8097         __ sltu(AT, op1, AT);
  8098         if(&L)
  8099           __ beq(AT, R0, L);
  8100         else
  8101                 __ beq(AT, R0, (int)0);
  8102         break;
  8103       case 0x05: //below
  8104         __ sltu(AT, op1, AT);
  8105         if(&L)
  8106            __ bne(R0, AT, L);
  8107         else
  8108            __ bne(R0, AT, (int)0);
  8109         break;
  8110       case 0x06: //below_equal
  8111         __ sltu(AT, AT, op1);
  8112         if(&L)
  8113           __ beq(AT, R0, L);
  8114         else
  8115           __ beq(AT, R0, (int)0);
  8116        break;
  8117       default:
  8118         Unimplemented();
  8120     __ nop();
  8121   %}
  8123   ins_pc_relative(1);
  8124   ins_pipe( pipe_alu_branch );
  8125   ins_short_branch(1);
  8126 %}
  8128 instruct branchConI_reg_reg_short(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  8129   match( If cmp (CmpI src1 src2) );
  8130   effect(USE labl);
  8131   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg_short" %}
  8133   ins_encode %{
  8134     Register op1 = $src1$$Register;
  8135     Register op2 = $src2$$Register;
  8136     Label     &L = *($labl$$label);
  8137     int     flag = $cmp$$cmpcode;
  8139     switch(flag) {
  8140       case 0x01: //equal
  8141         if (&L)
  8142           __ beq(op1, op2, L);
  8143         else
  8144           __ beq(op1, op2, (int)0);
  8145         break;
  8146       case 0x02: //not_equal
  8147         if (&L)
  8148           __ bne(op1, op2, L);
  8149         else
  8150           __ bne(op1, op2, (int)0);
  8151         break;
  8152       case 0x03: //above
  8153         __ slt(AT, op2, op1);
  8154         if(&L)
  8155           __ bne(R0, AT, L);
  8156         else
  8157                 __ bne(R0, AT, (int)0);
  8158         break;
  8159       case 0x04: //above_equal
  8160         __ slt(AT, op1, op2);
  8161         if(&L)
  8162           __ beq(AT, R0, L);
  8163         else
  8164                 __ beq(AT, R0, (int)0);
  8165         break;
  8166       case 0x05: //below
  8167         __ slt(AT, op1, op2);
  8168         if(&L)
  8169            __ bne(R0, AT, L);
  8170         else
  8171            __ bne(R0, AT, (int)0);
  8172         break;
  8173       case 0x06: //below_equal
  8174         __ slt(AT, op2, op1);
  8175         if(&L)
  8176           __ beq(AT, R0, L);
  8177         else
  8178           __ beq(AT, R0, (int)0);
  8179        break;
  8180       default:
  8181         Unimplemented();
  8183     __ nop();
  8184   %}
  8186   ins_pc_relative(1);
  8187   ins_pipe( pipe_alu_branch );
  8188   ins_short_branch(1);
  8189 %}
  8191 instruct branchConI_reg_imm0_short(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  8192   match( If cmp (CmpI src1 src2) );
  8193   effect(USE labl);
  8194   ins_cost(170);
  8195   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0_short" %}
  8197   ins_encode %{
  8198     Register op1 = $src1$$Register;
  8199     Label     &L =  *($labl$$label);
  8200     int     flag = $cmp$$cmpcode;
  8202     switch(flag) {
  8203       case 0x01: //equal
  8204         if (&L)
  8205           __ beq(op1, R0, L);
  8206         else
  8207           __ beq(op1, R0, (int)0);
  8208         break;
  8209       case 0x02: //not_equal
  8210         if (&L)
  8211           __ bne(op1, R0, L);
  8212         else
  8213           __ bne(op1, R0, (int)0);
  8214         break;
  8215       case 0x03: //greater
  8216         if(&L)
  8217                __ bgtz(op1, L);
  8218         else
  8219                __ bgtz(op1, (int)0);
  8220         break;
  8221       case 0x04: //greater_equal
  8222         if(&L)
  8223                __ bgez(op1, L);
  8224         else
  8225                __ bgez(op1, (int)0);
  8226         break;
  8227       case 0x05: //less
  8228         if(&L)
  8229                 __ bltz(op1, L);
  8230         else
  8231                 __ bltz(op1, (int)0);
  8232         break;
  8233       case 0x06: //less_equal
  8234         if(&L)
  8235                __ blez(op1, L);
  8236         else
  8237                __ blez(op1, (int)0);
  8238        break;
  8239       default:
  8240         Unimplemented();
  8242     __ nop();
  8243   %}
  8245   ins_pc_relative(1);
  8246   ins_pipe( pipe_alu_branch );
  8247   ins_short_branch(1);
  8248 %}
  8251 instruct branchConI_reg_imm_short(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  8252   match( If cmp (CmpI src1 src2) );
  8253   effect(USE labl);
  8254   ins_cost(200);
  8255   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm_short" %}
  8257   ins_encode %{
  8258     Register op1 = $src1$$Register;
  8259     int      val = $src2$$constant;
  8260     Label     &L =  *($labl$$label);
  8261     int     flag = $cmp$$cmpcode;
  8263     __ move(AT, val);
  8264     switch(flag) {
  8265       case 0x01: //equal
  8266         if (&L)
  8267           __ beq(op1, AT, L);
  8268         else
  8269           __ beq(op1, AT, (int)0);
  8270         break;
  8271       case 0x02: //not_equal
  8272         if (&L)
  8273           __ bne(op1, AT, L);
  8274         else
  8275           __ bne(op1, AT, (int)0);
  8276         break;
  8277       case 0x03: //greater
  8278         __ slt(AT, AT, op1);
  8279         if(&L)
  8280           __ bne(R0, AT, L);
  8281         else
  8282                 __ bne(R0, AT, (int)0);
  8283         break;
  8284       case 0x04: //greater_equal
  8285         __ slt(AT, op1, AT);
  8286         if(&L)
  8287           __ beq(AT, R0, L);
  8288         else
  8289                 __ beq(AT, R0, (int)0);
  8290         break;
  8291       case 0x05: //less
  8292         __ slt(AT, op1, AT);
  8293         if(&L)
  8294            __ bne(R0, AT, L);
  8295         else
  8296            __ bne(R0, AT, (int)0);
  8297         break;
  8298       case 0x06: //less_equal
  8299         __ slt(AT, AT, op1);
  8300         if(&L)
  8301           __ beq(AT, R0, L);
  8302         else
  8303           __ beq(AT, R0, (int)0);
  8304        break;
  8305       default:
  8306           Unimplemented();
  8308     __ nop();
  8309   %}
  8311   ins_pc_relative(1);
  8312   ins_pipe( pipe_alu_branch );
  8313   ins_short_branch(1);
  8314 %}
  8316 instruct branchConIU_reg_imm0_short(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  8317   match( If cmp (CmpU src1 zero) );
  8318   effect(USE labl);
  8319   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0_short" %}
  8321   ins_encode %{
  8322     Register op1 = $src1$$Register;
  8323     Label     &L = *($labl$$label);
  8324     int     flag = $cmp$$cmpcode;
  8326     switch(flag) {
  8327       case 0x01: //equal
  8328         if (&L)
  8329           __ beq(op1, R0, L);
  8330         else
  8331           __ beq(op1, R0, (int)0);
  8332         break;
  8333       case 0x02: //not_equal
  8334         if (&L)
  8335           __ bne(op1, R0, L);
  8336         else
  8337           __ bne(op1, R0, (int)0);
  8338         break;
  8339       case 0x03: //above
  8340         if(&L)
  8341           __ bne(R0, op1, L);
  8342         else
  8343           __ bne(R0, op1, (int)0);
  8344         break;
  8345       case 0x04: //above_equal
  8346         if(&L)
  8347           __ beq(R0, R0, L);
  8348         else
  8349           __ beq(R0, R0, (int)0);
  8350         break;
  8351       case 0x05: //below
  8352         return;
  8353         break;
  8354       case 0x06: //below_equal
  8355         if(&L)
  8356           __ beq(op1, R0, L);
  8357         else
  8358           __ beq(op1, R0, (int)0);
  8359         break;
  8360       default:
  8361         Unimplemented();
  8363     __ nop();
  8364     %}
  8366   ins_pc_relative(1);
  8367   ins_pipe( pipe_alu_branch );
  8368   ins_short_branch(1);
  8369 %}
  8372 instruct branchConIU_reg_immI16_short(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  8373   match( If cmp (CmpU src1 src2) );
  8374   effect(USE labl);
  8375   ins_cost(180);
  8376   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16_short" %}
  8378   ins_encode %{
  8379     Register op1 = $src1$$Register;
  8380     int      val = $src2$$constant;
  8381     Label     &L = *($labl$$label);
  8382     int     flag = $cmp$$cmpcode;
  8384     switch(flag) {
  8385       case 0x01: //equal
  8386         __ move(AT, val);
  8387         if (&L)
  8388           __ beq(op1, AT, L);
  8389         else
  8390           __ beq(op1, AT, (int)0);
  8391         break;
  8392       case 0x02: //not_equal
  8393         __ move(AT, val);
  8394         if (&L)
  8395           __ bne(op1, AT, L);
  8396         else
  8397           __ bne(op1, AT, (int)0);
  8398         break;
  8399       case 0x03: //above
  8400         __ move(AT, val);
  8401         __ sltu(AT, AT, op1);
  8402         if(&L)
  8403           __ bne(R0, AT, L);
  8404         else
  8405           __ bne(R0, AT, (int)0);
  8406         break;
  8407       case 0x04: //above_equal
  8408         __ sltiu(AT, op1, val);
  8409         if(&L)
  8410           __ beq(AT, R0, L);
  8411         else
  8412           __ beq(AT, R0, (int)0);
  8413         break;
  8414       case 0x05: //below
  8415         __ sltiu(AT, op1, val);
  8416         if(&L)
  8417           __ bne(R0, AT, L);
  8418         else
  8419           __ bne(R0, AT, (int)0);
  8420         break;
  8421       case 0x06: //below_equal
  8422         __ move(AT, val);
  8423         __ sltu(AT, AT, op1);
  8424         if(&L)
  8425           __ beq(AT, R0, L);
  8426         else
  8427           __ beq(AT, R0, (int)0);
  8428         break;
  8429       default:
  8430         Unimplemented();
  8432     __ nop();
  8433   %}
  8435   ins_pc_relative(1);
  8436   ins_pipe( pipe_alu_branch );
  8437   ins_short_branch(1);
  8438 %}
  8441 instruct branchConL_regL_regL_short(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  8442   match( If cmp (CmpL src1 src2) );
  8443   effect(USE labl);
  8444   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL_short" %}
  8445   ins_cost(250);
  8447   ins_encode %{
  8448     Register opr1_reg = as_Register($src1$$reg);
  8449     Register opr2_reg = as_Register($src2$$reg);
  8451     Label   &target = *($labl$$label);
  8452     int     flag = $cmp$$cmpcode;
  8454     switch(flag) {
  8455       case 0x01: //equal
  8456         if (&target)
  8457           __ beq(opr1_reg, opr2_reg, target);
  8458         else
  8459           __ beq(opr1_reg, opr2_reg, (int)0);
  8460         __ delayed()->nop();
  8461         break;
  8463       case 0x02: //not_equal
  8464         if(&target)
  8465           __ bne(opr1_reg, opr2_reg, target);
  8466         else
  8467           __ bne(opr1_reg, opr2_reg, (int)0);
  8468         __ delayed()->nop();
  8469         break;
  8471       case 0x03: //greater
  8472         __ slt(AT, opr2_reg, opr1_reg);
  8473         if(&target)
  8474           __ bne(AT, R0, target);
  8475         else
  8476           __ bne(AT, R0, (int)0);
  8477         __ delayed()->nop();
  8478         break;
  8480       case 0x04: //greater_equal
  8481         __ slt(AT, opr1_reg, opr2_reg);
  8482         if(&target)
  8483           __ beq(AT, R0, target);
  8484         else
  8485           __ beq(AT, R0, (int)0);
  8486         __ delayed()->nop();
  8488         break;
  8490       case 0x05: //less
  8491         __ slt(AT, opr1_reg, opr2_reg);
  8492         if(&target)
  8493           __ bne(AT, R0, target);
  8494         else
  8495           __ bne(AT, R0, (int)0);
  8496         __ delayed()->nop();
  8498         break;
  8500       case 0x06: //less_equal
  8501         __ slt(AT, opr2_reg, opr1_reg);
  8503         if(&target)
  8504           __ beq(AT, R0, target);
  8505         else
  8506           __ beq(AT, R0, (int)0);
  8507         __ delayed()->nop();
  8509         break;
  8511       default:
  8512         Unimplemented();
  8514   %}
  8517   ins_pc_relative(1);
  8518   ins_pipe( pipe_alu_branch );
  8519   ins_short_branch(1);
  8520 %}
  8523 instruct branchConL_regL_immL0_short(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  8524   match( If cmp (CmpL src1 zero) );
  8525   effect(USE labl);
  8526   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0_short" %}
  8527   ins_cost(150);
  8529   ins_encode %{
  8530     Register opr1_reg = as_Register($src1$$reg);
  8531     Label   &target = *($labl$$label);
  8532     int     flag = $cmp$$cmpcode;
  8534     switch(flag) {
  8535       case 0x01: //equal
  8536         if (&target)
  8537            __ beq(opr1_reg, R0, target);
  8538         else
  8539            __ beq(opr1_reg, R0, int(0));
  8540         break;
  8542       case 0x02: //not_equal
  8543         if(&target)
  8544            __ bne(opr1_reg, R0, target);
  8545         else
  8546            __ bne(opr1_reg, R0, (int)0);
  8547         break;
  8549       case 0x03: //greater
  8550         if(&target)
  8551            __ bgtz(opr1_reg, target);
  8552         else
  8553            __ bgtz(opr1_reg, (int)0);
  8554        break;
  8556       case 0x04: //greater_equal
  8557         if(&target)
  8558            __ bgez(opr1_reg, target);
  8559         else
  8560            __ bgez(opr1_reg, (int)0);
  8561         break;
  8563       case 0x05: //less
  8564         __ slt(AT, opr1_reg, R0);
  8565         if(&target)
  8566            __ bne(AT, R0, target);
  8567         else
  8568            __ bne(AT, R0, (int)0);
  8569         break;
  8571       case 0x06: //less_equal
  8572         if (&target)
  8573            __ blez(opr1_reg, target);
  8574         else
  8575            __ blez(opr1_reg, int(0));
  8576         break;
  8578       default:
  8579           Unimplemented();
  8581     __ delayed()->nop();
  8582   %}
  8585   ins_pc_relative(1);
  8586   ins_pipe( pipe_alu_branch );
  8587   ins_short_branch(1);
  8588 %}
  8590 instruct branchConL_regL_immL_short(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  8591   match( If cmp (CmpL src1 src2) );
  8592   effect(USE labl);
  8593   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL_short" %}
  8594   ins_cost(180);
  8596   ins_encode %{
  8597     Register opr1_reg = as_Register($src1$$reg);
  8598     Register opr2_reg = AT;
  8600     Label   &target = *($labl$$label);
  8601     int     flag = $cmp$$cmpcode;
  8603     __ set64(opr2_reg, $src2$$constant);
  8605     switch(flag) {
  8606       case 0x01: //equal
  8607         if (&target)
  8608           __ beq(opr1_reg, opr2_reg, target);
  8609         else
  8610           __ beq(opr1_reg, opr2_reg, (int)0);
  8611         break;
  8613       case 0x02: //not_equal
  8614         if(&target)
  8615           __ bne(opr1_reg, opr2_reg, target);
  8616         else
  8617           __ bne(opr1_reg, opr2_reg, (int)0);
  8618         break;
  8620       case 0x03: //greater
  8621         __ slt(AT, opr2_reg, opr1_reg);
  8622         if(&target)
  8623           __ bne(AT, R0, target);
  8624         else
  8625           __ bne(AT, R0, (int)0);
  8626         break;
  8628       case 0x04: //greater_equal
  8629         __ slt(AT, opr1_reg, opr2_reg);
  8630         if(&target)
  8631           __ beq(AT, R0, target);
  8632         else
  8633           __ beq(AT, R0, (int)0);
  8634         break;
  8636       case 0x05: //less
  8637         __ slt(AT, opr1_reg, opr2_reg);
  8638         if(&target)
  8639           __ bne(AT, R0, target);
  8640         else
  8641           __ bne(AT, R0, (int)0);
  8642         break;
  8644       case 0x06: //less_equal
  8645         __ slt(AT, opr2_reg, opr1_reg);
  8646         if(&target)
  8647           __ beq(AT, R0, target);
  8648         else
  8649           __ beq(AT, R0, (int)0);
  8650         break;
  8652       default:
  8653         Unimplemented();
  8655     __ nop();
  8656   %}
  8659   ins_pc_relative(1);
  8660   ins_pipe( pipe_alu_branch );
  8661   ins_short_branch(1);
  8662 %}
  8665 //FIXME
  8666 instruct branchConF_reg_reg_short(cmpOp cmp, regF src1, regF src2, label labl) %{
  8667   match( If cmp (CmpF src1 src2) );
  8668   effect(USE labl);
  8669   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg_short" %}
  8671   ins_encode %{
  8672     FloatRegister reg_op1 = $src1$$FloatRegister;
  8673     FloatRegister reg_op2 = $src2$$FloatRegister;
  8674     Label     &L =  *($labl$$label);
  8675     int     flag = $cmp$$cmpcode;
  8677     switch(flag) {
  8678       case 0x01: //equal
  8679         __ c_eq_s(reg_op1, reg_op2);
  8680         if (&L)
  8681           __ bc1t(L);
  8682         else
  8683           __ bc1t((int)0);
  8684         break;
  8685       case 0x02: //not_equal
  8686         __ c_eq_s(reg_op1, reg_op2);
  8687         if (&L)
  8688           __ bc1f(L);
  8689         else
  8690           __ bc1f((int)0);
  8691         break;
  8692       case 0x03: //greater
  8693         __ c_ule_s(reg_op1, reg_op2);
  8694         if(&L)
  8695           __ bc1f(L);
  8696         else
  8697           __ bc1f((int)0);
  8698         break;
  8699       case 0x04: //greater_equal
  8700         __ c_ult_s(reg_op1, reg_op2);
  8701         if(&L)
  8702           __ bc1f(L);
  8703         else
  8704           __ bc1f((int)0);
  8705         break;
  8706       case 0x05: //less
  8707         __ c_ult_s(reg_op1, reg_op2);
  8708         if(&L)
  8709           __ bc1t(L);
  8710         else
  8711           __ bc1t((int)0);
  8712         break;
  8713       case 0x06: //less_equal
  8714         __ c_ule_s(reg_op1, reg_op2);
  8715         if(&L)
  8716           __ bc1t(L);
  8717         else
  8718           __ bc1t((int)0);
  8719         break;
  8720       default:
  8721         Unimplemented();
  8723     __ nop();
  8724   %}
  8726   ins_pc_relative(1);
  8727   ins_pipe(pipe_slow);
  8728   ins_short_branch(1);
  8729 %}
  8731 instruct branchConD_reg_reg_short(cmpOp cmp, regD src1, regD src2, label labl) %{
  8732   match( If cmp (CmpD src1 src2) );
  8733   effect(USE labl);
  8734   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg_short" %}
  8736   ins_encode %{
  8737     FloatRegister reg_op1 = $src1$$FloatRegister;
  8738     FloatRegister reg_op2 = $src2$$FloatRegister;
  8739     Label     &L =  *($labl$$label);
  8740     int     flag = $cmp$$cmpcode;
  8742     switch(flag) {
  8743       case 0x01: //equal
  8744         __ c_eq_d(reg_op1, reg_op2);
  8745         if (&L)
  8746           __ bc1t(L);
  8747         else
  8748           __ bc1t((int)0);
  8749         break;
  8750       case 0x02: //not_equal
  8751         //2016/4/19 aoqi: c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
  8752         __ c_eq_d(reg_op1, reg_op2);
  8753         if (&L)
  8754           __ bc1f(L);
  8755         else
  8756           __ bc1f((int)0);
  8757         break;
  8758       case 0x03: //greater
  8759         __ c_ule_d(reg_op1, reg_op2);
  8760         if(&L)
  8761           __ bc1f(L);
  8762         else
  8763           __ bc1f((int)0);
  8764         break;
  8765       case 0x04: //greater_equal
  8766         __ c_ult_d(reg_op1, reg_op2);
  8767         if(&L)
  8768           __ bc1f(L);
  8769         else
  8770           __ bc1f((int)0);
  8771         break;
  8772       case 0x05: //less
  8773         __ c_ult_d(reg_op1, reg_op2);
  8774         if(&L)
  8775           __ bc1t(L);
  8776         else
  8777           __ bc1t((int)0);
  8778         break;
  8779       case 0x06: //less_equal
  8780         __ c_ule_d(reg_op1, reg_op2);
  8781         if(&L)
  8782           __ bc1t(L);
  8783         else
  8784           __ bc1t((int)0);
  8785         break;
  8786       default:
  8787         Unimplemented();
  8789     __ nop();
  8790   %}
  8792   ins_pc_relative(1);
  8793   ins_pipe(pipe_slow);
  8794   ins_short_branch(1);
  8795 %}
  8797 // =================== End of branch instructions ==========================
  8799 // Call Runtime Instruction
  8800 instruct CallRuntimeDirect(method meth) %{
  8801   match(CallRuntime );
  8802   effect(USE meth);
  8804   ins_cost(300);
  8805   format %{ "CALL,runtime #@CallRuntimeDirect" %}
  8806   ins_encode( Java_To_Runtime( meth ) );
  8807   ins_pipe( pipe_slow );
  8808   ins_alignment(16);
  8809 %}
  8813 //------------------------MemBar Instructions-------------------------------
  8814 //Memory barrier flavors
  8816 instruct membar_acquire() %{
  8817   match(MemBarAcquire);
  8818   ins_cost(400);
  8820   format %{ "MEMBAR-acquire @ membar_acquire" %}
  8821   ins_encode %{
  8822     __ sync();
  8823   %}
  8824   ins_pipe(empty);
  8825 %}
  8827 instruct load_fence() %{
  8828   match(LoadFence);
  8829   ins_cost(400);
  8831   format %{ "MEMBAR @ load_fence" %}
  8832   ins_encode %{
  8833     __ sync();
  8834   %}
  8835   ins_pipe(pipe_slow);
  8836 %}
  8838 instruct membar_acquire_lock()
  8839 %{
  8840   match(MemBarAcquireLock);
  8841   ins_cost(0);
  8843   size(0);
  8844   format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
  8845   ins_encode();
  8846   ins_pipe(empty);
  8847 %}
  8849 instruct membar_release() %{
  8850   match(MemBarRelease);
  8851   ins_cost(400);
  8853   format %{ "MEMBAR-release @ membar_release" %}
  8855   ins_encode %{
  8856     // Attention: DO NOT DELETE THIS GUY!
  8857     __ sync();
  8858   %}
  8860   ins_pipe(pipe_slow);
  8861 %}
  8863 instruct store_fence() %{
  8864   match(StoreFence);
  8865   ins_cost(400);
  8867   format %{ "MEMBAR @ store_fence" %}
  8869   ins_encode %{
  8870     __ sync();
  8871   %}
  8873   ins_pipe(pipe_slow);
  8874 %}
  8876 instruct membar_release_lock()
  8877 %{
  8878   match(MemBarReleaseLock);
  8879   ins_cost(0);
  8881   size(0);
  8882   format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
  8883   ins_encode();
  8884   ins_pipe(empty);
  8885 %}
  8888 instruct membar_volatile() %{
  8889   match(MemBarVolatile);
  8890   ins_cost(400);
  8892   format %{ "MEMBAR-volatile" %}
  8893   ins_encode %{
  8894     if( !os::is_MP() ) return;     // Not needed on single CPU
  8895     __ sync();
  8897   %}
  8898   ins_pipe(pipe_slow);
  8899 %}
  8901 instruct unnecessary_membar_volatile() %{
  8902   match(MemBarVolatile);
  8903   predicate(Matcher::post_store_load_barrier(n));
  8904   ins_cost(0);
  8906   size(0);
  8907   format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
  8908   ins_encode( );
  8909   ins_pipe(empty);
  8910 %}
  8912 instruct membar_storestore() %{
  8913   match(MemBarStoreStore);
  8915   ins_cost(400);
  8916   format %{ "MEMBAR-storestore @ membar_storestore" %}
  8917   ins_encode %{
  8918     __ sync();
  8919   %}
  8920   ins_pipe(empty);
  8921 %}
  8923 //----------Move Instructions--------------------------------------------------
  8924 instruct castX2P(mRegP dst, mRegL src) %{
  8925   match(Set dst (CastX2P src));
  8926   format %{ "castX2P  $dst, $src @ castX2P" %}
  8927   ins_encode %{
  8928     Register src = $src$$Register;
  8929     Register dst = $dst$$Register;
  8931   if(src != dst)
  8932     __ move(dst, src);
  8933   %}
  8934   ins_cost(10);
  8935   ins_pipe( ialu_regI_mov );
  8936 %}
  8938 instruct castP2X(mRegL dst, mRegP src ) %{
  8939   match(Set dst (CastP2X src));
  8941   format %{ "mov    $dst, $src\t  #@castP2X" %}
  8942   ins_encode %{
  8943     Register src = $src$$Register;
  8944     Register dst = $dst$$Register;
  8946   if(src != dst)
  8947     __ move(dst, src);
  8948   %}
  8949   ins_pipe( ialu_regI_mov );
  8950 %}
  8952 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
  8953   match(Set dst (MoveF2I src));
  8954   effect(DEF dst, USE src);
  8955   ins_cost(85);
  8956   format %{ "MoveF2I   $dst, $src @ MoveF2I_reg_reg" %}
  8957   ins_encode %{
  8958     Register dst = as_Register($dst$$reg);
  8959     FloatRegister src = as_FloatRegister($src$$reg);
  8961     __ mfc1(dst, src);
  8962   %}
  8963   ins_pipe( pipe_slow );
  8964 %}
  8966 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
  8967   match(Set dst (MoveI2F src));
  8968   effect(DEF dst, USE src);
  8969   ins_cost(85);
  8970   format %{ "MoveI2F   $dst, $src @ MoveI2F_reg_reg" %}
  8971   ins_encode %{
  8972     Register src = as_Register($src$$reg);
  8973     FloatRegister dst = as_FloatRegister($dst$$reg);
  8975     __ mtc1(src, dst);
  8976   %}
  8977   ins_pipe( pipe_slow );
  8978 %}
  8980 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
  8981   match(Set dst (MoveD2L src));
  8982   effect(DEF dst, USE src);
  8983   ins_cost(85);
  8984   format %{ "MoveD2L   $dst, $src @ MoveD2L_reg_reg" %}
  8985   ins_encode %{
  8986     Register dst = as_Register($dst$$reg);
  8987     FloatRegister src = as_FloatRegister($src$$reg);
  8989     __ dmfc1(dst, src);
  8990   %}
  8991   ins_pipe( pipe_slow );
  8992 %}
  8994 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
  8995   match(Set dst (MoveL2D src));
  8996   effect(DEF dst, USE src);
  8997   ins_cost(85);
  8998   format %{ "MoveL2D   $dst, $src @ MoveL2D_reg_reg" %}
  8999   ins_encode %{
  9000     FloatRegister dst = as_FloatRegister($dst$$reg);
  9001     Register src = as_Register($src$$reg);
  9003     __ dmtc1(src, dst);
  9004   %}
  9005   ins_pipe( pipe_slow );
  9006 %}
  9008 //----------Conditional Move---------------------------------------------------
  9009 // Conditional move
  9010 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9011   match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9012   ins_cost(80);
  9013   format %{
  9014              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpI_reg_reg\n"
  9015              "\tCMOV  $dst,$src \t @cmovI_cmpI_reg_reg"
  9016          %}
  9018   ins_encode %{
  9019     Register op1 = $tmp1$$Register;
  9020     Register op2 = $tmp2$$Register;
  9021     Register dst = $dst$$Register;
  9022     Register src = $src$$Register;
  9023     int     flag = $cop$$cmpcode;
  9025     switch(flag) {
  9026       case 0x01: //equal
  9027         __ subu32(AT, op1, op2);
  9028         __ movz(dst, src, AT);
  9029         break;
  9031       case 0x02: //not_equal
  9032         __ subu32(AT, op1, op2);
  9033         __ movn(dst, src, AT);
  9034         break;
  9036       case 0x03: //great
  9037         __ slt(AT, op2, op1);
  9038         __ movn(dst, src, AT);
  9039         break;
  9041       case 0x04: //great_equal
  9042         __ slt(AT, op1, op2);
  9043         __ movz(dst, src, AT);
  9044         break;
  9046       case 0x05: //less
  9047         __ slt(AT, op1, op2);
  9048         __ movn(dst, src, AT);
  9049         break;
  9051       case 0x06: //less_equal
  9052         __ slt(AT, op2, op1);
  9053         __ movz(dst, src, AT);
  9054        break;
  9056       default:
  9057         Unimplemented();
  9059   %}
  9061   ins_pipe( pipe_slow );
  9062 %}
  9064 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9065   match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9066   ins_cost(80);
  9067   format %{
  9068              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
  9069              "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
  9070          %}
  9071   ins_encode %{
  9072     Register op1 = $tmp1$$Register;
  9073     Register op2 = $tmp2$$Register;
  9074     Register dst = $dst$$Register;
  9075     Register src = $src$$Register;
  9076     int     flag = $cop$$cmpcode;
  9078     switch(flag) {
  9079       case 0x01: //equal
  9080         __ subu(AT, op1, op2);
  9081         __ movz(dst, src, AT);
  9082         break;
  9084       case 0x02: //not_equal
  9085         __ subu(AT, op1, op2);
  9086         __ movn(dst, src, AT);
  9087         break;
  9089       case 0x03: //above
  9090         __ sltu(AT, op2, op1);
  9091         __ movn(dst, src, AT);
  9092         break;
  9094       case 0x04: //above_equal
  9095         __ sltu(AT, op1, op2);
  9096         __ movz(dst, src, AT);
  9097         break;
  9099       case 0x05: //below
  9100         __ sltu(AT, op1, op2);
  9101         __ movn(dst, src, AT);
  9102         break;
  9104       case 0x06: //below_equal
  9105         __ sltu(AT, op2, op1);
  9106         __ movz(dst, src, AT);
  9107        break;
  9109       default:
  9110         Unimplemented();
  9112   %}
  9114   ins_pipe( pipe_slow );
  9115 %}
  9117 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9118   match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9119   ins_cost(80);
  9120   format %{
  9121              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
  9122              "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
  9123          %}
  9124   ins_encode %{
  9125     Register op1 = $tmp1$$Register;
  9126     Register op2 = $tmp2$$Register;
  9127     Register dst = $dst$$Register;
  9128     Register src = $src$$Register;
  9129     int     flag = $cop$$cmpcode;
  9131     switch(flag) {
  9132       case 0x01: //equal
  9133         __ subu32(AT, op1, op2);
  9134         __ movz(dst, src, AT);
  9135         break;
  9137       case 0x02: //not_equal
  9138         __ subu32(AT, op1, op2);
  9139         __ movn(dst, src, AT);
  9140         break;
  9142       case 0x03: //above
  9143         __ sltu(AT, op2, op1);
  9144         __ movn(dst, src, AT);
  9145         break;
  9147       case 0x04: //above_equal
  9148         __ sltu(AT, op1, op2);
  9149         __ movz(dst, src, AT);
  9150         break;
  9152       case 0x05: //below
  9153         __ sltu(AT, op1, op2);
  9154         __ movn(dst, src, AT);
  9155         break;
  9157       case 0x06: //below_equal
  9158         __ sltu(AT, op2, op1);
  9159         __ movz(dst, src, AT);
  9160        break;
  9162       default:
  9163           Unimplemented();
  9165   %}
  9167   ins_pipe( pipe_slow );
  9168 %}
  9170 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9171   match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9172   ins_cost(80);
  9173   format %{
  9174              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
  9175              "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
  9176          %}
  9177   ins_encode %{
  9178     Register op1 = $tmp1$$Register;
  9179     Register op2 = $tmp2$$Register;
  9180     Register dst = $dst$$Register;
  9181     Register src = $src$$Register;
  9182     int     flag = $cop$$cmpcode;
  9184     switch(flag) {
  9185       case 0x01: //equal
  9186         __ subu32(AT, op1, op2);
  9187         __ movz(dst, src, AT);
  9188         break;
  9190       case 0x02: //not_equal
  9191         __ subu32(AT, op1, op2);
  9192         __ movn(dst, src, AT);
  9193         break;
  9195       case 0x03: //above
  9196         __ sltu(AT, op2, op1);
  9197         __ movn(dst, src, AT);
  9198         break;
  9200       case 0x04: //above_equal
  9201         __ sltu(AT, op1, op2);
  9202         __ movz(dst, src, AT);
  9203         break;
  9205       case 0x05: //below
  9206         __ sltu(AT, op1, op2);
  9207         __ movn(dst, src, AT);
  9208         break;
  9210       case 0x06: //below_equal
  9211         __ sltu(AT, op2, op1);
  9212         __ movz(dst, src, AT);
  9213        break;
  9215       default:
  9216           Unimplemented();
  9218   %}
  9220   ins_pipe( pipe_slow );
  9221 %}
  9223 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9224   match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9225   ins_cost(80);
  9226   format %{
  9227              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpF_reg_reg\n"
  9228              "\tCMOV  $dst,$src \t @cmovP_cmpF_reg_reg"
  9229          %}
  9231   ins_encode %{
  9232     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9233     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9234     Register dst = $dst$$Register;
  9235     Register src = $src$$Register;
  9236     int     flag = $cop$$cmpcode;
  9238     switch(flag) {
  9239       case 0x01: //equal
  9240         __ c_eq_s(reg_op1, reg_op2);
  9241         __ movt(dst, src);
  9242         break;
  9243       case 0x02: //not_equal
  9244         __ c_eq_s(reg_op1, reg_op2);
  9245         __ movf(dst, src);
  9246         break;
  9247       case 0x03: //greater
  9248         __ c_ole_s(reg_op1, reg_op2);
  9249         __ movf(dst, src);
  9250         break;
  9251       case 0x04: //greater_equal
  9252         __ c_olt_s(reg_op1, reg_op2);
  9253         __ movf(dst, src);
  9254         break;
  9255       case 0x05: //less
  9256         __ c_ult_s(reg_op1, reg_op2);
  9257         __ movt(dst, src);
  9258         break;
  9259       case 0x06: //less_equal
  9260         __ c_ule_s(reg_op1, reg_op2);
  9261         __ movt(dst, src);
  9262         break;
  9263       default:
  9264         Unimplemented();
  9266   %}
  9267   ins_pipe( pipe_slow );
  9268 %}
  9270 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9271   match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9272   ins_cost(80);
  9273   format %{
  9274              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
  9275              "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
  9276          %}
  9277   ins_encode %{
  9278     Register op1 = $tmp1$$Register;
  9279     Register op2 = $tmp2$$Register;
  9280     Register dst = $dst$$Register;
  9281     Register src = $src$$Register;
  9282     int     flag = $cop$$cmpcode;
  9284     switch(flag) {
  9285       case 0x01: //equal
  9286         __ subu32(AT, op1, op2);
  9287         __ movz(dst, src, AT);
  9288         break;
  9290       case 0x02: //not_equal
  9291         __ subu32(AT, op1, op2);
  9292         __ movn(dst, src, AT);
  9293         break;
  9295       case 0x03: //above
  9296         __ sltu(AT, op2, op1);
  9297         __ movn(dst, src, AT);
  9298         break;
  9300       case 0x04: //above_equal
  9301         __ sltu(AT, op1, op2);
  9302         __ movz(dst, src, AT);
  9303         break;
  9305       case 0x05: //below
  9306         __ sltu(AT, op1, op2);
  9307         __ movn(dst, src, AT);
  9308         break;
  9310       case 0x06: //below_equal
  9311         __ sltu(AT, op2, op1);
  9312         __ movz(dst, src, AT);
  9313        break;
  9315       default:
  9316         Unimplemented();
  9318   %}
  9320   ins_pipe( pipe_slow );
  9321 %}
  9323 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9324   match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9325   ins_cost(80);
  9326   format %{
  9327              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
  9328              "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
  9329          %}
  9330   ins_encode %{
  9331     Register op1 = $tmp1$$Register;
  9332     Register op2 = $tmp2$$Register;
  9333     Register dst = $dst$$Register;
  9334     Register src = $src$$Register;
  9335     int     flag = $cop$$cmpcode;
  9337     switch(flag) {
  9338       case 0x01: //equal
  9339         __ subu(AT, op1, op2);
  9340         __ movz(dst, src, AT);
  9341         break;
  9343       case 0x02: //not_equal
  9344         __ subu(AT, op1, op2);
  9345         __ movn(dst, src, AT);
  9346         break;
  9348       case 0x03: //above
  9349         __ sltu(AT, op2, op1);
  9350         __ movn(dst, src, AT);
  9351         break;
  9353       case 0x04: //above_equal
  9354         __ sltu(AT, op1, op2);
  9355         __ movz(dst, src, AT);
  9356         break;
  9358       case 0x05: //below
  9359         __ sltu(AT, op1, op2);
  9360         __ movn(dst, src, AT);
  9361         break;
  9363       case 0x06: //below_equal
  9364         __ sltu(AT, op2, op1);
  9365         __ movz(dst, src, AT);
  9366         break;
  9368       default:
  9369         Unimplemented();
  9371   %}
  9373   ins_pipe( pipe_slow );
  9374 %}
  9376 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9377   match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9378   ins_cost(80);
  9379   format %{
  9380              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpD_reg_reg\n"
  9381              "\tCMOV  $dst,$src \t @cmovP_cmpD_reg_reg"
  9382          %}
  9383   ins_encode %{
  9384     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9385     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9386     Register dst = as_Register($dst$$reg);
  9387     Register src = as_Register($src$$reg);
  9389     int     flag = $cop$$cmpcode;
  9391     switch(flag) {
  9392       case 0x01: //equal
  9393         __ c_eq_d(reg_op1, reg_op2);
  9394         __ movt(dst, src);
  9395         break;
  9396       case 0x02: //not_equal
  9397         __ c_eq_d(reg_op1, reg_op2);
  9398         __ movf(dst, src);
  9399         break;
  9400       case 0x03: //greater
  9401         __ c_ole_d(reg_op1, reg_op2);
  9402         __ movf(dst, src);
  9403         break;
  9404       case 0x04: //greater_equal
  9405         __ c_olt_d(reg_op1, reg_op2);
  9406         __ movf(dst, src);
  9407         break;
  9408       case 0x05: //less
  9409         __ c_ult_d(reg_op1, reg_op2);
  9410         __ movt(dst, src);
  9411         break;
  9412       case 0x06: //less_equal
  9413         __ c_ule_d(reg_op1, reg_op2);
  9414         __ movt(dst, src);
  9415         break;
  9416       default:
  9417         Unimplemented();
  9419   %}
  9421   ins_pipe( pipe_slow );
  9422 %}
  9425 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9426   match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9427   ins_cost(80);
  9428   format %{
  9429              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
  9430              "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
  9431          %}
  9432   ins_encode %{
  9433     Register op1 = $tmp1$$Register;
  9434     Register op2 = $tmp2$$Register;
  9435     Register dst = $dst$$Register;
  9436     Register src = $src$$Register;
  9437     int     flag = $cop$$cmpcode;
  9439     switch(flag) {
  9440       case 0x01: //equal
  9441         __ subu32(AT, op1, op2);
  9442         __ movz(dst, src, AT);
  9443         break;
  9445       case 0x02: //not_equal
  9446         __ subu32(AT, op1, op2);
  9447         __ movn(dst, src, AT);
  9448         break;
  9450       case 0x03: //above
  9451         __ sltu(AT, op2, op1);
  9452         __ movn(dst, src, AT);
  9453         break;
  9455       case 0x04: //above_equal
  9456         __ sltu(AT, op1, op2);
  9457         __ movz(dst, src, AT);
  9458         break;
  9460       case 0x05: //below
  9461         __ sltu(AT, op1, op2);
  9462         __ movn(dst, src, AT);
  9463         break;
  9465       case 0x06: //below_equal
  9466         __ sltu(AT, op2, op1);
  9467         __ movz(dst, src, AT);
  9468         break;
  9470       default:
  9471         Unimplemented();
  9473   %}
  9475   ins_pipe( pipe_slow );
  9476 %}
  9479 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9480   match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9481   ins_cost(80);
  9482   format %{
  9483              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
  9484              "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
  9485          %}
  9486   ins_encode %{
  9487     Register op1 = $tmp1$$Register;
  9488     Register op2 = $tmp2$$Register;
  9489     Register dst = $dst$$Register;
  9490     Register src = $src$$Register;
  9491     int     flag = $cop$$cmpcode;
  9493     switch(flag) {
  9494       case 0x01: //equal
  9495         __ subu(AT, op1, op2);
  9496         __ movz(dst, src, AT);
  9497         break;
  9499       case 0x02: //not_equal
  9500         __ subu(AT, op1, op2);
  9501         __ movn(dst, src, AT);
  9502         break;
  9504       case 0x03: //above
  9505         __ sltu(AT, op2, op1);
  9506         __ movn(dst, src, AT);
  9507         break;
  9509       case 0x04: //above_equal
  9510         __ sltu(AT, op1, op2);
  9511         __ movz(dst, src, AT);
  9512         break;
  9514       case 0x05: //below
  9515         __ sltu(AT, op1, op2);
  9516         __ movn(dst, src, AT);
  9517         break;
  9519       case 0x06: //below_equal
  9520         __ sltu(AT, op2, op1);
  9521         __ movz(dst, src, AT);
  9522         break;
  9524       default:
  9525         Unimplemented();
  9527   %}
  9529   ins_pipe( pipe_slow );
  9530 %}
  9532 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  9533   match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9534   ins_cost(80);
  9535   format %{
  9536              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpL_reg_reg\n"
  9537              "\tCMOV  $dst,$src \t @cmovI_cmpL_reg_reg"
  9538          %}
  9539   ins_encode %{
  9540     Register opr1 = as_Register($tmp1$$reg);
  9541     Register opr2 = as_Register($tmp2$$reg);
  9542     Register dst     = $dst$$Register;
  9543     Register src     = $src$$Register;
  9544     int     flag = $cop$$cmpcode;
  9546     switch(flag) {
  9547       case 0x01: //equal
  9548         __ subu(AT, opr1, opr2);
  9549         __ movz(dst, src, AT);
  9550         break;
  9552       case 0x02: //not_equal
  9553         __ subu(AT, opr1, opr2);
  9554         __ movn(dst, src, AT);
  9555         break;
  9557       case 0x03: //greater
  9558         __ slt(AT, opr2, opr1);
  9559         __ movn(dst, src, AT);
  9560         break;
  9562       case 0x04: //greater_equal
  9563         __ slt(AT, opr1, opr2);
  9564         __ movz(dst, src, AT);
  9565         break;
  9567       case 0x05: //less
  9568         __ slt(AT, opr1, opr2);
  9569         __ movn(dst, src, AT);
  9570         break;
  9572       case 0x06: //less_equal
  9573         __ slt(AT, opr2, opr1);
  9574         __ movz(dst, src, AT);
  9575         break;
  9577       default:
  9578         Unimplemented();
  9580   %}
  9582   ins_pipe( pipe_slow );
  9583 %}
  9585 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  9586   match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9587   ins_cost(80);
  9588   format %{
  9589              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpL_reg_reg\n"
  9590              "\tCMOV  $dst,$src \t @cmovP_cmpL_reg_reg"
  9591          %}
  9592   ins_encode %{
  9593     Register opr1 = as_Register($tmp1$$reg);
  9594     Register opr2 = as_Register($tmp2$$reg);
  9595     Register dst     = $dst$$Register;
  9596     Register src     = $src$$Register;
  9597     int     flag = $cop$$cmpcode;
  9599     switch(flag) {
  9600       case 0x01: //equal
  9601         __ subu(AT, opr1, opr2);
  9602         __ movz(dst, src, AT);
  9603         break;
  9605       case 0x02: //not_equal
  9606         __ subu(AT, opr1, opr2);
  9607         __ movn(dst, src, AT);
  9608         break;
  9610       case 0x03: //greater
  9611         __ slt(AT, opr2, opr1);
  9612         __ movn(dst, src, AT);
  9613         break;
  9615       case 0x04: //greater_equal
  9616         __ slt(AT, opr1, opr2);
  9617         __ movz(dst, src, AT);
  9618         break;
  9620       case 0x05: //less
  9621         __ slt(AT, opr1, opr2);
  9622         __ movn(dst, src, AT);
  9623         break;
  9625       case 0x06: //less_equal
  9626         __ slt(AT, opr2, opr1);
  9627         __ movz(dst, src, AT);
  9628         break;
  9630       default:
  9631         Unimplemented();
  9633   %}
  9635   ins_pipe( pipe_slow );
  9636 %}
  9638 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9639   match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9640   ins_cost(80);
  9641   format %{
  9642              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpD_reg_reg\n"
  9643              "\tCMOV  $dst,$src \t @cmovI_cmpD_reg_reg"
  9644          %}
  9645   ins_encode %{
  9646     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9647     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9648     Register dst = as_Register($dst$$reg);
  9649     Register src = as_Register($src$$reg);
  9651     int     flag = $cop$$cmpcode;
  9653     switch(flag) {
  9654       case 0x01: //equal
  9655         __ c_eq_d(reg_op1, reg_op2);
  9656         __ movt(dst, src);
  9657         break;
  9658       case 0x02: //not_equal
  9659 //2016/4/19 aoqi: See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
  9660         __ c_eq_d(reg_op1, reg_op2);
  9661         __ movf(dst, src);
  9662         break;
  9663       case 0x03: //greater
  9664         __ c_ole_d(reg_op1, reg_op2);
  9665         __ movf(dst, src);
  9666         break;
  9667       case 0x04: //greater_equal
  9668         __ c_olt_d(reg_op1, reg_op2);
  9669         __ movf(dst, src);
  9670         break;
  9671       case 0x05: //less
  9672         __ c_ult_d(reg_op1, reg_op2);
  9673         __ movt(dst, src);
  9674         break;
  9675       case 0x06: //less_equal
  9676         __ c_ule_d(reg_op1, reg_op2);
  9677         __ movt(dst, src);
  9678         break;
  9679       default:
  9680         Unimplemented();
  9682   %}
  9684   ins_pipe( pipe_slow );
  9685 %}
  9688 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9689   match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9690   ins_cost(80);
  9691   format %{
  9692              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
  9693              "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
  9694          %}
  9695   ins_encode %{
  9696     Register op1 = $tmp1$$Register;
  9697     Register op2 = $tmp2$$Register;
  9698     Register dst = $dst$$Register;
  9699     Register src = $src$$Register;
  9700     int     flag = $cop$$cmpcode;
  9702     switch(flag) {
  9703       case 0x01: //equal
  9704         __ subu(AT, op1, op2);
  9705         __ movz(dst, src, AT);
  9706         break;
  9708       case 0x02: //not_equal
  9709         __ subu(AT, op1, op2);
  9710         __ movn(dst, src, AT);
  9711         break;
  9713       case 0x03: //above
  9714         __ sltu(AT, op2, op1);
  9715         __ movn(dst, src, AT);
  9716         break;
  9718       case 0x04: //above_equal
  9719         __ sltu(AT, op1, op2);
  9720         __ movz(dst, src, AT);
  9721         break;
  9723       case 0x05: //below
  9724         __ sltu(AT, op1, op2);
  9725         __ movn(dst, src, AT);
  9726         break;
  9728       case 0x06: //below_equal
  9729         __ sltu(AT, op2, op1);
  9730         __ movz(dst, src, AT);
  9731        break;
  9733       default:
  9734         Unimplemented();
  9736   %}
  9738   ins_pipe( pipe_slow );
  9739 %}
  9741 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9742   match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9743   ins_cost(80);
  9744   format %{
  9745              "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
  9746              "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
  9747          %}
  9748   ins_encode %{
  9749     Register op1 = $tmp1$$Register;
  9750     Register op2 = $tmp2$$Register;
  9751     Register dst = $dst$$Register;
  9752     Register src = $src$$Register;
  9753     int     flag = $cop$$cmpcode;
  9755     switch(flag) {
  9756       case 0x01: //equal
  9757         __ subu32(AT, op1, op2);
  9758         __ movz(dst, src, AT);
  9759         break;
  9761       case 0x02: //not_equal
  9762         __ subu32(AT, op1, op2);
  9763         __ movn(dst, src, AT);
  9764         break;
  9766       case 0x03: //above
  9767         __ slt(AT, op2, op1);
  9768         __ movn(dst, src, AT);
  9769         break;
  9771       case 0x04: //above_equal
  9772         __ slt(AT, op1, op2);
  9773         __ movz(dst, src, AT);
  9774         break;
  9776       case 0x05: //below
  9777         __ slt(AT, op1, op2);
  9778         __ movn(dst, src, AT);
  9779         break;
  9781       case 0x06: //below_equal
  9782         __ slt(AT, op2, op1);
  9783         __ movz(dst, src, AT);
  9784         break;
  9786       default:
  9787         Unimplemented();
  9789   %}
  9791   ins_pipe( pipe_slow );
  9792 %}
  9794 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
  9795   match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9796   ins_cost(80);
  9797   format %{
  9798              "CMP$cop  $tmp1, $tmp2\t  @cmovN_cmpL_reg_reg\n"
  9799              "\tCMOV  $dst,$src \t @cmovN_cmpL_reg_reg"
  9800          %}
  9801   ins_encode %{
  9802     Register opr1 = as_Register($tmp1$$reg);
  9803     Register opr2 = as_Register($tmp2$$reg);
  9804     Register dst  = $dst$$Register;
  9805     Register src  = $src$$Register;
  9806     int     flag  = $cop$$cmpcode;
  9808     switch(flag) {
  9809       case 0x01: //equal
  9810         __ subu(AT, opr1, opr2);
  9811         __ movz(dst, src, AT);
  9812         break;
  9814       case 0x02: //not_equal
  9815         __ subu(AT, opr1, opr2);
  9816         __ movn(dst, src, AT);
  9817         break;
  9819       case 0x03: //greater
  9820         __ slt(AT, opr2, opr1);
  9821         __ movn(dst, src, AT);
  9822         break;
  9824       case 0x04: //greater_equal
  9825         __ slt(AT, opr1, opr2);
  9826         __ movz(dst, src, AT);
  9827         break;
  9829       case 0x05: //less
  9830         __ slt(AT, opr1, opr2);
  9831         __ movn(dst, src, AT);
  9832         break;
  9834       case 0x06: //less_equal
  9835         __ slt(AT, opr2, opr1);
  9836         __ movz(dst, src, AT);
  9837         break;
  9839       default:
  9840         Unimplemented();
  9842   %}
  9844   ins_pipe( pipe_slow );
  9845 %}
  9847 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9848   match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9849   ins_cost(80);
  9850   format %{
  9851              "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
  9852              "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
  9853          %}
  9854   ins_encode %{
  9855     Register op1 = $tmp1$$Register;
  9856     Register op2 = $tmp2$$Register;
  9857     Register dst = $dst$$Register;
  9858     Register src = $src$$Register;
  9859     int     flag = $cop$$cmpcode;
  9861     switch(flag) {
  9862       case 0x01: //equal
  9863         __ subu32(AT, op1, op2);
  9864         __ movz(dst, src, AT);
  9865         break;
  9867       case 0x02: //not_equal
  9868         __ subu32(AT, op1, op2);
  9869         __ movn(dst, src, AT);
  9870         break;
  9872       case 0x03: //above
  9873         __ slt(AT, op2, op1);
  9874         __ movn(dst, src, AT);
  9875         break;
  9877       case 0x04: //above_equal
  9878         __ slt(AT, op1, op2);
  9879         __ movz(dst, src, AT);
  9880         break;
  9882       case 0x05: //below
  9883         __ slt(AT, op1, op2);
  9884         __ movn(dst, src, AT);
  9885         break;
  9887       case 0x06: //below_equal
  9888         __ slt(AT, op2, op1);
  9889         __ movz(dst, src, AT);
  9890        break;
  9892       default:
  9893         Unimplemented();
  9895   %}
  9897   ins_pipe( pipe_slow );
  9898 %}
  9900 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9901   match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9902   ins_cost(80);
  9903   format %{
  9904              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
  9905              "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
  9906          %}
  9907   ins_encode %{
  9908     Register op1 = $tmp1$$Register;
  9909     Register op2 = $tmp2$$Register;
  9910     Register dst = $dst$$Register;
  9911     Register src = $src$$Register;
  9912     int     flag = $cop$$cmpcode;
  9914     switch(flag) {
  9915       case 0x01: //equal
  9916         __ subu32(AT, op1, op2);
  9917         __ movz(dst, src, AT);
  9918         break;
  9920       case 0x02: //not_equal
  9921         __ subu32(AT, op1, op2);
  9922         __ movn(dst, src, AT);
  9923         break;
  9925       case 0x03: //above
  9926         __ sltu(AT, op2, op1);
  9927         __ movn(dst, src, AT);
  9928         break;
  9930       case 0x04: //above_equal
  9931         __ sltu(AT, op1, op2);
  9932         __ movz(dst, src, AT);
  9933         break;
  9935       case 0x05: //below
  9936         __ sltu(AT, op1, op2);
  9937         __ movn(dst, src, AT);
  9938         break;
  9940       case 0x06: //below_equal
  9941         __ sltu(AT, op2, op1);
  9942         __ movz(dst, src, AT);
  9943         break;
  9945       default:
  9946         Unimplemented();
  9948   %}
  9950   ins_pipe( pipe_slow );
  9951 %}
  9953 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9954   match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9955   ins_cost(80);
  9956   format %{
  9957              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpF_reg_reg\n"
  9958              "\tCMOV  $dst,$src \t @cmovL_cmpF_reg_reg"
  9959          %}
  9961   ins_encode %{
  9962     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9963     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9964     Register dst = $dst$$Register;
  9965     Register src = $src$$Register;
  9966     int     flag = $cop$$cmpcode;
  9968     switch(flag) {
  9969       case 0x01: //equal
  9970         __ c_eq_s(reg_op1, reg_op2);
  9971         __ movt(dst, src);
  9972         break;
  9973       case 0x02: //not_equal
  9974         __ c_eq_s(reg_op1, reg_op2);
  9975         __ movf(dst, src);
  9976         break;
  9977       case 0x03: //greater
  9978         __ c_ole_s(reg_op1, reg_op2);
  9979         __ movf(dst, src);
  9980         break;
  9981       case 0x04: //greater_equal
  9982         __ c_olt_s(reg_op1, reg_op2);
  9983         __ movf(dst, src);
  9984         break;
  9985       case 0x05: //less
  9986         __ c_ult_s(reg_op1, reg_op2);
  9987         __ movt(dst, src);
  9988         break;
  9989       case 0x06: //less_equal
  9990         __ c_ule_s(reg_op1, reg_op2);
  9991         __ movt(dst, src);
  9992        break;
  9993       default:
  9994         Unimplemented();
  9996   %}
  9997   ins_pipe( pipe_slow );
  9998 %}
 10000 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10001   match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10002   ins_cost(80);
 10003   format %{
 10004              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpI_reg_reg\n"
 10005              "\tCMOV  $dst,$src \t @cmovL_cmpI_reg_reg"
 10006          %}
 10008   ins_encode %{
 10009     Register op1 = $tmp1$$Register;
 10010     Register op2 = $tmp2$$Register;
 10011     Register dst = as_Register($dst$$reg);
 10012     Register src = as_Register($src$$reg);
 10013     int     flag = $cop$$cmpcode;
 10015     switch(flag)
 10017       case 0x01: //equal
 10018         __ subu32(AT, op1, op2);
 10019         __ movz(dst, src, AT);
 10020         break;
 10022       case 0x02: //not_equal
 10023         __ subu32(AT, op1, op2);
 10024         __ movn(dst, src, AT);
 10025         break;
 10027       case 0x03: //great
 10028         __ slt(AT, op2, op1);
 10029         __ movn(dst, src, AT);
 10030         break;
 10032       case 0x04: //great_equal
 10033         __ slt(AT, op1, op2);
 10034         __ movz(dst, src, AT);
 10035         break;
 10037       case 0x05: //less
 10038         __ slt(AT, op1, op2);
 10039         __ movn(dst, src, AT);
 10040         break;
 10042       case 0x06: //less_equal
 10043         __ slt(AT, op2, op1);
 10044         __ movz(dst, src, AT);
 10045        break;
 10047       default:
 10048         Unimplemented();
 10050   %}
 10052   ins_pipe( pipe_slow );
 10053 %}
 10055 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
 10056   match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
 10057   ins_cost(80);
 10058   format %{
 10059              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpL_reg_reg\n"
 10060              "\tCMOV  $dst,$src \t @cmovL_cmpL_reg_reg"
 10061          %}
 10062   ins_encode %{
 10063     Register opr1 = as_Register($tmp1$$reg);
 10064     Register opr2 = as_Register($tmp2$$reg);
 10065     Register dst  = as_Register($dst$$reg);
 10066     Register src  = as_Register($src$$reg);
 10067     int     flag = $cop$$cmpcode;
 10069     switch(flag) {
 10070       case 0x01: //equal
 10071         __ subu(AT, opr1, opr2);
 10072         __ movz(dst, src, AT);
 10073         break;
 10075       case 0x02: //not_equal
 10076         __ subu(AT, opr1, opr2);
 10077         __ movn(dst, src, AT);
 10078         break;
 10080       case 0x03: //greater
 10081         __ slt(AT, opr2, opr1);
 10082         __ movn(dst, src, AT);
 10083         break;
 10085       case 0x04: //greater_equal
 10086         __ slt(AT, opr1, opr2);
 10087         __ movz(dst, src, AT);
 10088         break;
 10090       case 0x05: //less
 10091         __ slt(AT, opr1, opr2);
 10092         __ movn(dst, src, AT);
 10093         break;
 10095       case 0x06: //less_equal
 10096        __ slt(AT, opr2, opr1);
 10097        __ movz(dst, src, AT);
 10098        break;
 10100       default:
 10101         Unimplemented();
 10103   %}
 10105   ins_pipe( pipe_slow );
 10106 %}
 10108 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
 10109   match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
 10110   ins_cost(80);
 10111   format %{
 10112              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
 10113              "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
 10114          %}
 10115   ins_encode %{
 10116     Register op1 = $tmp1$$Register;
 10117     Register op2 = $tmp2$$Register;
 10118     Register dst = $dst$$Register;
 10119     Register src = $src$$Register;
 10120     int     flag = $cop$$cmpcode;
 10122     switch(flag) {
 10123       case 0x01: //equal
 10124         __ subu32(AT, op1, op2);
 10125         __ movz(dst, src, AT);
 10126         break;
 10128       case 0x02: //not_equal
 10129         __ subu32(AT, op1, op2);
 10130         __ movn(dst, src, AT);
 10131         break;
 10133       case 0x03: //above
 10134         __ sltu(AT, op2, op1);
 10135         __ movn(dst, src, AT);
 10136         break;
 10138       case 0x04: //above_equal
 10139         __ sltu(AT, op1, op2);
 10140         __ movz(dst, src, AT);
 10141         break;
 10143       case 0x05: //below
 10144         __ sltu(AT, op1, op2);
 10145         __ movn(dst, src, AT);
 10146         break;
 10148       case 0x06: //below_equal
 10149         __ sltu(AT, op2, op1);
 10150         __ movz(dst, src, AT);
 10151         break;
 10153       default:
 10154         Unimplemented();
 10156   %}
 10158   ins_pipe( pipe_slow );
 10159 %}
 10162 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
 10163   match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
 10164   ins_cost(80);
 10165   format %{
 10166              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpD_reg_reg\n"
 10167              "\tCMOV  $dst,$src \t @cmovL_cmpD_reg_reg"
 10168          %}
 10169   ins_encode %{
 10170     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
 10171     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
 10172     Register dst = as_Register($dst$$reg);
 10173     Register src = as_Register($src$$reg);
 10175     int     flag = $cop$$cmpcode;
 10177     switch(flag) {
 10178       case 0x01: //equal
 10179         __ c_eq_d(reg_op1, reg_op2);
 10180         __ movt(dst, src);
 10181         break;
 10182       case 0x02: //not_equal
 10183         __ c_eq_d(reg_op1, reg_op2);
 10184         __ movf(dst, src);
 10185         break;
 10186       case 0x03: //greater
 10187         __ c_ole_d(reg_op1, reg_op2);
 10188         __ movf(dst, src);
 10189         break;
 10190       case 0x04: //greater_equal
 10191         __ c_olt_d(reg_op1, reg_op2);
 10192         __ movf(dst, src);
 10193         break;
 10194       case 0x05: //less
 10195         __ c_ult_d(reg_op1, reg_op2);
 10196         __ movt(dst, src);
 10197         break;
 10198       case 0x06: //less_equal
 10199         __ c_ule_d(reg_op1, reg_op2);
 10200         __ movt(dst, src);
 10201         break;
 10202       default:
 10203         Unimplemented();
 10205   %}
 10207   ins_pipe( pipe_slow );
 10208 %}
 10210 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
 10211   match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
 10212   ins_cost(200);
 10213   format %{
 10214              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpD_reg_reg\n"
 10215              "\tCMOV  $dst,$src \t @cmovD_cmpD_reg_reg"
 10216          %}
 10217   ins_encode %{
 10218     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
 10219     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
 10220     FloatRegister dst = as_FloatRegister($dst$$reg);
 10221     FloatRegister src = as_FloatRegister($src$$reg);
 10223     int     flag = $cop$$cmpcode;
 10225     switch(flag) {
 10226       case 0x01: //equal
 10227         __ c_eq_d(reg_op1, reg_op2);
 10228         __ movt_d(dst, src);
 10229         break;
 10230       case 0x02: //not_equal
 10231         __ c_eq_d(reg_op1, reg_op2);
 10232         __ movf_d(dst, src);
 10233         break;
 10234       case 0x03: //greater
 10235         __ c_ole_d(reg_op1, reg_op2);
 10236         __ movf_d(dst, src);
 10237         break;
 10238       case 0x04: //greater_equal
 10239         __ c_olt_d(reg_op1, reg_op2);
 10240         __ movf_d(dst, src);
 10241         break;
 10242       case 0x05: //less
 10243         __ c_ult_d(reg_op1, reg_op2);
 10244         __ movt_d(dst, src);
 10245         break;
 10246       case 0x06: //less_equal
 10247         __ c_ule_d(reg_op1, reg_op2);
 10248         __ movt_d(dst, src);
 10249         break;
 10250       default:
 10251         Unimplemented();
 10253   %}
 10255   ins_pipe( pipe_slow );
 10256 %}
 10258 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10259   match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10260   ins_cost(200);
 10261   format %{
 10262              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpI_reg_reg\n"
 10263              "\tCMOV  $dst, $src \t @cmovF_cmpI_reg_reg"
 10264          %}
 10266   ins_encode %{
 10267     Register op1 = $tmp1$$Register;
 10268     Register op2 = $tmp2$$Register;
 10269     FloatRegister dst = as_FloatRegister($dst$$reg);
 10270     FloatRegister src = as_FloatRegister($src$$reg);
 10271     int     flag = $cop$$cmpcode;
 10272     Label      L;
 10274     switch(flag) {
 10275       case 0x01: //equal
 10276         __ bne(op1, op2, L);
 10277         __ nop();
 10278         __ mov_s(dst, src);
 10279         __ bind(L);
 10280         break;
 10281       case 0x02: //not_equal
 10282         __ beq(op1, op2, L);
 10283         __ nop();
 10284         __ mov_s(dst, src);
 10285         __ bind(L);
 10286         break;
 10287       case 0x03: //great
 10288         __ slt(AT, op2, op1);
 10289         __ beq(AT, R0, L);
 10290         __ nop();
 10291         __ mov_s(dst, src);
 10292         __ bind(L);
 10293         break;
 10294       case 0x04: //great_equal
 10295         __ slt(AT, op1, op2);
 10296         __ bne(AT, R0, L);
 10297         __ nop();
 10298         __ mov_s(dst, src);
 10299         __ bind(L);
 10300         break;
 10301       case 0x05: //less
 10302         __ slt(AT, op1, op2);
 10303         __ beq(AT, R0, L);
 10304         __ nop();
 10305         __ mov_s(dst, src);
 10306         __ bind(L);
 10307         break;
 10308       case 0x06: //less_equal
 10309         __ slt(AT, op2, op1);
 10310         __ bne(AT, R0, L);
 10311         __ nop();
 10312         __ mov_s(dst, src);
 10313         __ bind(L);
 10314        break;
 10315       default:
 10316         Unimplemented();
 10318   %}
 10320   ins_pipe( pipe_slow );
 10321 %}
 10323 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10324   match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10325   ins_cost(200);
 10326   format %{
 10327              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpI_reg_reg\n"
 10328              "\tCMOV  $dst, $src \t @cmovD_cmpI_reg_reg"
 10329          %}
 10331   ins_encode %{
 10332     Register op1 = $tmp1$$Register;
 10333     Register op2 = $tmp2$$Register;
 10334     FloatRegister dst = as_FloatRegister($dst$$reg);
 10335     FloatRegister src = as_FloatRegister($src$$reg);
 10336     int     flag = $cop$$cmpcode;
 10337     Label      L;
 10339     switch(flag) {
 10340       case 0x01: //equal
 10341         __ bne(op1, op2, L);
 10342         __ nop();
 10343         __ mov_d(dst, src);
 10344         __ bind(L);
 10345         break;
 10346       case 0x02: //not_equal
 10347         __ beq(op1, op2, L);
 10348         __ nop();
 10349         __ mov_d(dst, src);
 10350         __ bind(L);
 10351         break;
 10352       case 0x03: //great
 10353         __ slt(AT, op2, op1);
 10354         __ beq(AT, R0, L);
 10355         __ nop();
 10356         __ mov_d(dst, src);
 10357         __ bind(L);
 10358         break;
 10359       case 0x04: //great_equal
 10360         __ slt(AT, op1, op2);
 10361         __ bne(AT, R0, L);
 10362         __ nop();
 10363         __ mov_d(dst, src);
 10364         __ bind(L);
 10365         break;
 10366       case 0x05: //less
 10367         __ slt(AT, op1, op2);
 10368         __ beq(AT, R0, L);
 10369         __ nop();
 10370         __ mov_d(dst, src);
 10371         __ bind(L);
 10372         break;
 10373       case 0x06: //less_equal
 10374         __ slt(AT, op2, op1);
 10375         __ bne(AT, R0, L);
 10376         __ nop();
 10377         __ mov_d(dst, src);
 10378         __ bind(L);
 10379         break;
 10380       default:
 10381         Unimplemented();
 10383   %}
 10385   ins_pipe( pipe_slow );
 10386 %}
 10388 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
 10389   match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
 10390   ins_cost(200);
 10391   format %{
 10392              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpP_reg_reg\n"
 10393              "\tCMOV  $dst, $src \t @cmovD_cmpP_reg_reg"
 10394          %}
 10396   ins_encode %{
 10397     Register op1 = $tmp1$$Register;
 10398     Register op2 = $tmp2$$Register;
 10399     FloatRegister dst = as_FloatRegister($dst$$reg);
 10400     FloatRegister src = as_FloatRegister($src$$reg);
 10401     int     flag = $cop$$cmpcode;
 10402     Label      L;
 10404     switch(flag) {
 10405       case 0x01: //equal
 10406         __ bne(op1, op2, L);
 10407         __ nop();
 10408         __ mov_d(dst, src);
 10409         __ bind(L);
 10410         break;
 10411       case 0x02: //not_equal
 10412         __ beq(op1, op2, L);
 10413         __ nop();
 10414         __ mov_d(dst, src);
 10415         __ bind(L);
 10416         break;
 10417       case 0x03: //great
 10418         __ slt(AT, op2, op1);
 10419         __ beq(AT, R0, L);
 10420         __ nop();
 10421         __ mov_d(dst, src);
 10422         __ bind(L);
 10423         break;
 10424       case 0x04: //great_equal
 10425         __ slt(AT, op1, op2);
 10426         __ bne(AT, R0, L);
 10427         __ nop();
 10428         __ mov_d(dst, src);
 10429         __ bind(L);
 10430         break;
 10431       case 0x05: //less
 10432         __ slt(AT, op1, op2);
 10433         __ beq(AT, R0, L);
 10434         __ nop();
 10435         __ mov_d(dst, src);
 10436         __ bind(L);
 10437         break;
 10438       case 0x06: //less_equal
 10439         __ slt(AT, op2, op1);
 10440         __ bne(AT, R0, L);
 10441         __ nop();
 10442         __ mov_d(dst, src);
 10443         __ bind(L);
 10444         break;
 10445       default:
 10446         Unimplemented();
 10448   %}
 10450   ins_pipe( pipe_slow );
 10451 %}
 10453 //FIXME
 10454 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10455   match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10456   ins_cost(80);
 10457   format %{
 10458              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpF_reg_reg\n"
 10459              "\tCMOV  $dst,$src \t @cmovI_cmpF_reg_reg"
 10460          %}
 10462   ins_encode %{
 10463     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10464     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10465     Register dst = $dst$$Register;
 10466     Register src = $src$$Register;
 10467     int     flag = $cop$$cmpcode;
 10469     switch(flag) {
 10470       case 0x01: //equal
 10471         __ c_eq_s(reg_op1, reg_op2);
 10472         __ movt(dst, src);
 10473         break;
 10474       case 0x02: //not_equal
 10475         __ c_eq_s(reg_op1, reg_op2);
 10476         __ movf(dst, src);
 10477         break;
 10478       case 0x03: //greater
 10479         __ c_ole_s(reg_op1, reg_op2);
 10480         __ movf(dst, src);
 10481         break;
 10482       case 0x04: //greater_equal
 10483         __ c_olt_s(reg_op1, reg_op2);
 10484         __ movf(dst, src);
 10485         break;
 10486       case 0x05: //less
 10487         __ c_ult_s(reg_op1, reg_op2);
 10488         __ movt(dst, src);
 10489         break;
 10490       case 0x06: //less_equal
 10491         __ c_ule_s(reg_op1, reg_op2);
 10492         __ movt(dst, src);
 10493         break;
 10494       default:
 10495         Unimplemented();
 10497   %}
 10498   ins_pipe( pipe_slow );
 10499 %}
 10501 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10502   match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10503   ins_cost(200);
 10504   format %{
 10505              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpF_reg_reg\n"
 10506              "\tCMOV  $dst,$src \t @cmovF_cmpF_reg_reg"
 10507          %}
 10509   ins_encode %{
 10510     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10511     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10512     FloatRegister dst = $dst$$FloatRegister;
 10513     FloatRegister src = $src$$FloatRegister;
 10514     int    flag = $cop$$cmpcode;
 10516     switch(flag) {
 10517       case 0x01: //equal
 10518         __ c_eq_s(reg_op1, reg_op2);
 10519         __ movt_s(dst, src);
 10520         break;
 10521       case 0x02: //not_equal
 10522         __ c_eq_s(reg_op1, reg_op2);
 10523         __ movf_s(dst, src);
 10524         break;
 10525       case 0x03: //greater
 10526         __ c_ole_s(reg_op1, reg_op2);
 10527         __ movf_s(dst, src);
 10528         break;
 10529       case 0x04: //greater_equal
 10530         __ c_olt_s(reg_op1, reg_op2);
 10531         __ movf_s(dst, src);
 10532         break;
 10533       case 0x05: //less
 10534         __ c_ult_s(reg_op1, reg_op2);
 10535         __ movt_s(dst, src);
 10536         break;
 10537       case 0x06: //less_equal
 10538         __ c_ule_s(reg_op1, reg_op2);
 10539         __ movt_s(dst, src);
 10540         break;
 10541       default:
 10542         Unimplemented();
 10544   %}
 10545   ins_pipe( pipe_slow );
 10546 %}
 10548 // Manifest a CmpL result in an integer register.  Very painful.
 10549 // This is the test to avoid.
 10550 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
 10551   match(Set dst (CmpL3 src1 src2));
 10552   ins_cost(1000);
 10553   format %{ "cmpL3  $dst, $src1, $src2 @ cmpL3_reg_reg" %}
 10554   ins_encode %{
 10555     Register opr1 = as_Register($src1$$reg);
 10556     Register opr2 = as_Register($src2$$reg);
 10557     Register dst  = as_Register($dst$$reg);
 10559     Label Done;
 10561     __ subu(AT, opr1, opr2);
 10562     __ bltz(AT, Done);
 10563     __ delayed()->daddiu(dst, R0, -1);
 10565     __ move(dst, 1);
 10566     __ movz(dst, R0, AT);
 10568     __ bind(Done);
 10569   %}
 10570   ins_pipe( pipe_slow );
 10571 %}
 10573 //
 10574 // less_rsult     = -1
 10575 // greater_result =  1
 10576 // equal_result   =  0
 10577 // nan_result     = -1
 10578 //
 10579 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
 10580   match(Set dst (CmpF3 src1 src2));
 10581   ins_cost(1000);
 10582   format %{ "cmpF3  $dst, $src1, $src2 @ cmpF3_reg_reg" %}
 10583   ins_encode %{
 10584     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10585     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10586     Register dst = as_Register($dst$$reg);
 10588     Label Done;
 10590     __ c_ult_s(src1, src2);
 10591     __ bc1t(Done);
 10592     __ delayed()->daddiu(dst, R0, -1);
 10594     __ c_eq_s(src1, src2);
 10595     __ move(dst, 1);
 10596     __ movt(dst, R0);
 10598     __ bind(Done);
 10599   %}
 10600   ins_pipe( pipe_slow );
 10601 %}
 10603 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
 10604   match(Set dst (CmpD3 src1 src2));
 10605   ins_cost(1000);
 10606   format %{ "cmpD3  $dst, $src1, $src2 @ cmpD3_reg_reg" %}
 10607   ins_encode %{
 10608     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10609     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10610     Register dst = as_Register($dst$$reg);
 10612     Label Done;
 10614     __ c_ult_d(src1, src2);
 10615     __ bc1t(Done);
 10616     __ delayed()->daddiu(dst, R0, -1);
 10618     __ c_eq_d(src1, src2);
 10619     __ move(dst, 1);
 10620     __ movt(dst, R0);
 10622     __ bind(Done);
 10623   %}
 10624   ins_pipe( pipe_slow );
 10625 %}
 10627 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
 10628   match(Set dummy (ClearArray cnt base));
 10629   format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
 10630   ins_encode %{
 10631     //Assume cnt is the number of bytes in an array to be cleared,
 10632     //and base points to the starting address of the array.
 10633     Register base = $base$$Register;
 10634     Register num  = $cnt$$Register;
 10635     Label Loop, done;
 10637     __ beq(num, R0, done);
 10638     __ delayed()->daddu(AT, base, R0);
 10640     __ move(T9, num);  /* T9 = words */
 10642     __ bind(Loop);
 10643     __ sd(R0, AT, 0);
 10644     __ daddi(T9, T9, -1);
 10645     __ bne(T9, R0, Loop);
 10646     __ delayed()->daddi(AT, AT, wordSize);
 10648     __ bind(done);
 10649   %}
 10650   ins_pipe( pipe_slow );
 10651 %}
 10653 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2,  mA7RegI cnt2, no_Ax_mRegI result) %{
 10654   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 10655   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
 10657   format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
 10658   ins_encode %{
 10659     // Get the first character position in both strings
 10660     //         [8] char array, [12] offset, [16] count
 10661     Register str1   = $str1$$Register;
 10662     Register str2   = $str2$$Register;
 10663     Register cnt1   = $cnt1$$Register;
 10664     Register cnt2   = $cnt2$$Register;
 10665     Register result = $result$$Register;
 10667     Label L, Loop, haveResult, done;
 10669    // compute the and difference of lengths (in result)
 10670    __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
 10672    // compute the shorter length (in cnt1)
 10673    __ slt(AT, cnt2, cnt1);
 10674    __ movn(cnt1, cnt2, AT);
 10676    // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
 10677    __ bind(Loop);                        // Loop begin
 10678    __ beq(cnt1, R0, done);
 10679    __ delayed()->lhu(AT, str1, 0);;
 10681    // compare current character
 10682    __ lhu(cnt2, str2, 0);
 10683    __ bne(AT, cnt2, haveResult);
 10684    __ delayed()->addi(str1, str1, 2);
 10685    __ addi(str2, str2, 2);
 10686    __ b(Loop);
 10687    __ delayed()->addi(cnt1, cnt1, -1);   // Loop end
 10689    __ bind(haveResult);
 10690    __ subu(result, AT, cnt2);
 10692    __ bind(done);
 10693   %}
 10695   ins_pipe( pipe_slow );
 10696 %}
 10698 // intrinsic optimization
 10699 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
 10700   match(Set result (StrEquals (Binary str1 str2) cnt));
 10701   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
 10703   format %{ "String Equal $str1, $str2, len:$cnt  tmp:$temp -> $result @ string_equals" %}
 10704   ins_encode %{
 10705     // Get the first character position in both strings
 10706     //         [8] char array, [12] offset, [16] count
 10707     Register str1   = $str1$$Register;
 10708     Register str2   = $str2$$Register;
 10709     Register cnt    = $cnt$$Register;
 10710     Register tmp    = $temp$$Register;
 10711     Register result = $result$$Register;
 10713     Label    Loop, done;
 10716    __ beq(str1, str2, done);  // same char[] ?
 10717    __ daddiu(result, R0, 1);
 10719    __ bind(Loop);             // Loop begin
 10720    __ beq(cnt, R0, done);
 10721    __ daddiu(result, R0, 1); // count == 0
 10723    // compare current character
 10724    __ lhu(AT, str1, 0);;
 10725    __ lhu(tmp, str2, 0);
 10726    __ bne(AT, tmp, done);
 10727    __ delayed()->daddi(result, R0, 0);
 10728    __ addi(str1, str1, 2);
 10729    __ addi(str2, str2, 2);
 10730    __ b(Loop);
 10731    __ delayed()->addi(cnt, cnt, -1);  // Loop end
 10733    __ bind(done);
 10734   %}
 10736   ins_pipe( pipe_slow );
 10737 %}
 10739 //----------Arithmetic Instructions-------------------------------------------
 10740 //----------Addition Instructions---------------------------------------------
 10741 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10742   match(Set dst (AddI src1 src2));
 10744   format %{ "add   $dst, $src1, $src2 #@addI_Reg_Reg" %}
 10745   ins_encode %{
 10746     Register  dst = $dst$$Register;
 10747     Register src1 = $src1$$Register;
 10748     Register src2 = $src2$$Register;
 10749     __ addu32(dst, src1, src2);
 10750   %}
 10751   ins_pipe( ialu_regI_regI );
 10752 %}
 10754 instruct addI_Reg_imm(mRegI dst, mRegI src1,  immI src2) %{
 10755   match(Set dst (AddI src1 src2));
 10757   format %{ "add    $dst, $src1, $src2 #@addI_Reg_imm" %}
 10758   ins_encode %{
 10759     Register  dst = $dst$$Register;
 10760     Register src1 = $src1$$Register;
 10761     int       imm = $src2$$constant;
 10763     if(Assembler::is_simm16(imm)) {
 10764        __ addiu32(dst, src1, imm);
 10765     } else {
 10766        __ move(AT, imm);
 10767        __ addu32(dst, src1, AT);
 10769   %}
 10770   ins_pipe( ialu_regI_regI );
 10771 %}
 10773 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
 10774   match(Set dst (AddP src1 src2));
 10776   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg" %}
 10778   ins_encode %{
 10779     Register  dst = $dst$$Register;
 10780     Register src1 = $src1$$Register;
 10781     Register src2 = $src2$$Register;
 10782     __ daddu(dst, src1, src2);
 10783   %}
 10785   ins_pipe( ialu_regI_regI );
 10786 %}
 10788 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
 10789   match(Set dst (AddP src1 (ConvI2L src2)));
 10791   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
 10793   ins_encode %{
 10794     Register  dst = $dst$$Register;
 10795     Register src1 = $src1$$Register;
 10796     Register src2 = $src2$$Register;
 10797     __ daddu(dst, src1, src2);
 10798   %}
 10800   ins_pipe( ialu_regI_regI );
 10801 %}
 10803 instruct addP_reg_imm(mRegP dst, mRegP src1,  immL src2) %{
 10804   match(Set dst (AddP src1 src2));
 10806   format %{ "daddi   $dst, $src1, $src2 #@addP_reg_imm" %}
 10807   ins_encode %{
 10808     Register src1 = $src1$$Register;
 10809     long      src2 = $src2$$constant;
 10810     Register  dst = $dst$$Register;
 10812     if(Assembler::is_simm16(src2)) {
 10813        __ daddiu(dst, src1, src2);
 10814     } else {
 10815        __ set64(AT, src2);
 10816        __ daddu(dst, src1, AT);
 10818   %}
 10819   ins_pipe( ialu_regI_imm16 );
 10820 %}
 10822 // Add Long Register with Register
 10823 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10824   match(Set dst (AddL src1 src2));
 10825   ins_cost(200);
 10826   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
 10828   ins_encode %{
 10829     Register dst_reg = as_Register($dst$$reg);
 10830     Register src1_reg = as_Register($src1$$reg);
 10831     Register src2_reg = as_Register($src2$$reg);
 10833     __ daddu(dst_reg, src1_reg, src2_reg);
 10834   %}
 10836   ins_pipe( ialu_regL_regL );
 10837 %}
 10839 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
 10840 %{
 10841   match(Set dst (AddL src1 src2));
 10843   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_imm " %}
 10844   ins_encode %{
 10845     Register dst_reg  = as_Register($dst$$reg);
 10846     Register src1_reg = as_Register($src1$$reg);
 10847     int      src2_imm = $src2$$constant;
 10849     __ daddiu(dst_reg, src1_reg, src2_imm);
 10850   %}
 10852   ins_pipe( ialu_regL_regL );
 10853 %}
 10855 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
 10856 %{
 10857   match(Set dst (AddL (ConvI2L src1) src2));
 10859   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_imm " %}
 10860   ins_encode %{
 10861     Register dst_reg  = as_Register($dst$$reg);
 10862     Register src1_reg = as_Register($src1$$reg);
 10863     int      src2_imm = $src2$$constant;
 10865     __ daddiu(dst_reg, src1_reg, src2_imm);
 10866   %}
 10868   ins_pipe( ialu_regL_regL );
 10869 %}
 10871 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
 10872   match(Set dst (AddL (ConvI2L src1) src2));
 10873   ins_cost(200);
 10874   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
 10876   ins_encode %{
 10877     Register dst_reg = as_Register($dst$$reg);
 10878     Register src1_reg = as_Register($src1$$reg);
 10879     Register src2_reg = as_Register($src2$$reg);
 10881     __ daddu(dst_reg, src1_reg, src2_reg);
 10882   %}
 10884   ins_pipe( ialu_regL_regL );
 10885 %}
 10887 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
 10888   match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
 10889   ins_cost(200);
 10890   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
 10892   ins_encode %{
 10893     Register dst_reg = as_Register($dst$$reg);
 10894     Register src1_reg = as_Register($src1$$reg);
 10895     Register src2_reg = as_Register($src2$$reg);
 10897     __ daddu(dst_reg, src1_reg, src2_reg);
 10898   %}
 10900   ins_pipe( ialu_regL_regL );
 10901 %}
 10903 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
 10904   match(Set dst (AddL src1 (ConvI2L src2)));
 10905   ins_cost(200);
 10906   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
 10908   ins_encode %{
 10909     Register dst_reg = as_Register($dst$$reg);
 10910     Register src1_reg = as_Register($src1$$reg);
 10911     Register src2_reg = as_Register($src2$$reg);
 10913     __ daddu(dst_reg, src1_reg, src2_reg);
 10914   %}
 10916   ins_pipe( ialu_regL_regL );
 10917 %}
 10919 //----------Subtraction Instructions-------------------------------------------
 10920 // Integer Subtraction Instructions
 10921 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10922   match(Set dst (SubI src1 src2));
 10923   ins_cost(100);
 10925   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_Reg" %}
 10926   ins_encode %{
 10927     Register  dst = $dst$$Register;
 10928     Register src1 = $src1$$Register;
 10929     Register src2 = $src2$$Register;
 10930     __ subu32(dst, src1, src2);
 10931   %}
 10932   ins_pipe( ialu_regI_regI );
 10933 %}
 10935 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1,  immI16_sub src2) %{
 10936   match(Set dst (SubI src1 src2));
 10937   ins_cost(80);
 10939   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
 10940   ins_encode %{
 10941     Register  dst = $dst$$Register;
 10942     Register src1 = $src1$$Register;
 10943     __ addiu32(dst, src1, -1 * $src2$$constant);
 10944   %}
 10945   ins_pipe( ialu_regI_regI );
 10946 %}
 10948 instruct negI_Reg(mRegI dst, immI0 zero,  mRegI src) %{
 10949   match(Set dst (SubI zero src));
 10950   ins_cost(80);
 10952   format %{ "neg    $dst, $src #@negI_Reg" %}
 10953   ins_encode %{
 10954     Register  dst = $dst$$Register;
 10955     Register  src = $src$$Register;
 10956     __ subu32(dst, R0, src);
 10957   %}
 10958   ins_pipe( ialu_regI_regI );
 10959 %}
 10961 instruct negL_Reg(mRegL dst, immL0 zero,  mRegL src) %{
 10962   match(Set dst (SubL zero src));
 10963   ins_cost(80);
 10965   format %{ "neg    $dst, $src #@negL_Reg" %}
 10966   ins_encode %{
 10967     Register  dst = $dst$$Register;
 10968     Register  src = $src$$Register;
 10969     __ subu(dst, R0, src);
 10970   %}
 10971   ins_pipe( ialu_regI_regI );
 10972 %}
 10974 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1,  immL16_sub src2) %{
 10975   match(Set dst (SubL src1 src2));
 10976   ins_cost(80);
 10978   format %{ "sub    $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
 10979   ins_encode %{
 10980     Register  dst = $dst$$Register;
 10981     Register src1 = $src1$$Register;
 10982     __ daddiu(dst, src1, -1 * $src2$$constant);
 10983   %}
 10984   ins_pipe( ialu_regI_regI );
 10985 %}
 10987 // Subtract Long Register with Register.
 10988 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10989   match(Set dst (SubL src1 src2));
 10990   ins_cost(100);
 10991   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_Reg" %}
 10992   ins_encode %{
 10993     Register dst  = as_Register($dst$$reg);
 10994     Register src1 = as_Register($src1$$reg);
 10995     Register src2 = as_Register($src2$$reg);
 10997     __ subu(dst, src1, src2);
 10998   %}
 10999   ins_pipe( ialu_regL_regL );
 11000 %}
 11002 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11003   match(Set dst (SubL src1 (ConvI2L src2)));
 11004   ins_cost(100);
 11005   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
 11006   ins_encode %{
 11007     Register dst  = as_Register($dst$$reg);
 11008     Register src1 = as_Register($src1$$reg);
 11009     Register src2 = as_Register($src2$$reg);
 11011     __ subu(dst, src1, src2);
 11012   %}
 11013   ins_pipe( ialu_regL_regL );
 11014 %}
 11016 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
 11017   match(Set dst (SubL (ConvI2L src1) src2));
 11018   ins_cost(200);
 11019   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
 11020   ins_encode %{
 11021     Register dst  = as_Register($dst$$reg);
 11022     Register src1 = as_Register($src1$$reg);
 11023     Register src2 = as_Register($src2$$reg);
 11025     __ subu(dst, src1, src2);
 11026   %}
 11027   ins_pipe( ialu_regL_regL );
 11028 %}
 11030 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
 11031   match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
 11032   ins_cost(200);
 11033   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
 11034   ins_encode %{
 11035     Register dst  = as_Register($dst$$reg);
 11036     Register src1 = as_Register($src1$$reg);
 11037     Register src2 = as_Register($src2$$reg);
 11039     __ subu(dst, src1, src2);
 11040   %}
 11041   ins_pipe( ialu_regL_regL );
 11042 %}
 11044 // Integer MOD with Register
 11045 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11046   match(Set dst (ModI src1 src2));
 11047   ins_cost(300);
 11048   format %{ "modi   $dst, $src1, $src2 @ modI_Reg_Reg" %}
 11049   ins_encode %{
 11050     Register  dst = $dst$$Register;
 11051     Register src1 = $src1$$Register;
 11052     Register src2 = $src2$$Register;
 11054     //if (UseLoongsonISA) {
 11055     if (0) {
 11056       // 2016.08.10
 11057       // Experiments show that gsmod is slower that div+mfhi.
 11058       // So I just disable it here.
 11059       __ gsmod(dst, src1, src2);
 11060     } else {
 11061       __ div(src1, src2);
 11062       __ mfhi(dst);
 11064   %}
 11066   //ins_pipe( ialu_mod );
 11067   ins_pipe( ialu_regI_regI );
 11068 %}
 11070 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11071   match(Set dst (ModL src1 src2));
 11072   format %{ "modL  $dst, $src1, $src2 @modL_reg_reg" %}
 11074   ins_encode %{
 11075     Register dst = as_Register($dst$$reg);
 11076     Register op1 = as_Register($src1$$reg);
 11077     Register op2 = as_Register($src2$$reg);
 11079     if (UseLoongsonISA) {
 11080       __ gsdmod(dst, op1, op2);
 11081     } else {
 11082       __ ddiv(op1, op2);
 11083       __ mfhi(dst);
 11085   %}
 11086   ins_pipe( pipe_slow );
 11087 %}
 11089 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11090   match(Set dst (MulI src1 src2));
 11092   ins_cost(300);
 11093   format %{ "mul   $dst, $src1, $src2 @ mulI_Reg_Reg" %}
 11094   ins_encode %{
 11095      Register src1 = $src1$$Register;
 11096      Register src2 = $src2$$Register;
 11097      Register dst  = $dst$$Register;
 11099      __ mul(dst, src1, src2);
 11100   %}
 11101   ins_pipe( ialu_mult );
 11102 %}
 11104 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
 11105   match(Set dst (AddI (MulI src1 src2) src3));
 11107   ins_cost(999);
 11108   format %{ "madd   $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
 11109   ins_encode %{
 11110      Register src1 = $src1$$Register;
 11111      Register src2 = $src2$$Register;
 11112      Register src3 = $src3$$Register;
 11113      Register dst  = $dst$$Register;
 11115      __ mtlo(src3);
 11116      __ madd(src1, src2);
 11117      __ mflo(dst);
 11118   %}
 11119   ins_pipe( ialu_mult );
 11120 %}
 11122 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11123   match(Set dst (DivI src1 src2));
 11125   ins_cost(300);
 11126   format %{ "div   $dst, $src1, $src2 @ divI_Reg_Reg" %}
 11127   ins_encode %{
 11128      Register src1 = $src1$$Register;
 11129      Register src2 = $src2$$Register;
 11130      Register dst  = $dst$$Register;
 11132     /* 2012/4/21 Jin: In MIPS, div does not cause exception.
 11133        We must trap an exception manually. */
 11134     __ teq(R0, src2, 0x7);
 11136     if (UseLoongsonISA) {
 11137       __ gsdiv(dst, src1, src2);
 11138     } else {
 11139       __ div(src1, src2);
 11141       __ nop();
 11142       __ nop();
 11143       __ mflo(dst);
 11145   %}
 11146   ins_pipe( ialu_mod );
 11147 %}
 11149 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
 11150   match(Set dst (DivF src1 src2));
 11152   ins_cost(300);
 11153   format %{ "divF   $dst, $src1, $src2 @ divF_Reg_Reg" %}
 11154   ins_encode %{
 11155      FloatRegister src1 = $src1$$FloatRegister;
 11156      FloatRegister src2 = $src2$$FloatRegister;
 11157      FloatRegister dst  = $dst$$FloatRegister;
 11159     /* Here do we need to trap an exception manually ? */
 11160     __ div_s(dst, src1, src2);
 11161   %}
 11162   ins_pipe( pipe_slow );
 11163 %}
 11165 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
 11166   match(Set dst (DivD src1 src2));
 11168   ins_cost(300);
 11169   format %{ "divD   $dst, $src1, $src2 @ divD_Reg_Reg" %}
 11170   ins_encode %{
 11171      FloatRegister src1 = $src1$$FloatRegister;
 11172      FloatRegister src2 = $src2$$FloatRegister;
 11173      FloatRegister dst  = $dst$$FloatRegister;
 11175     /* Here do we need to trap an exception manually ? */
 11176     __ div_d(dst, src1, src2);
 11177   %}
 11178   ins_pipe( pipe_slow );
 11179 %}
 11181 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11182   match(Set dst (MulL src1 src2));
 11183   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_reg" %}
 11184   ins_encode %{
 11185     Register dst = as_Register($dst$$reg);
 11186     Register op1 = as_Register($src1$$reg);
 11187     Register op2 = as_Register($src2$$reg);
 11189     if (UseLoongsonISA) {
 11190       __ gsdmult(dst, op1, op2);
 11191     } else {
 11192       __ dmult(op1, op2);
 11193       __ mflo(dst);
 11195   %}
 11196   ins_pipe( pipe_slow );
 11197 %}
 11199 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11200   match(Set dst (MulL src1 (ConvI2L src2)));
 11201   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_regI2L" %}
 11202   ins_encode %{
 11203     Register dst = as_Register($dst$$reg);
 11204     Register op1 = as_Register($src1$$reg);
 11205     Register op2 = as_Register($src2$$reg);
 11207     if (UseLoongsonISA) {
 11208       __ gsdmult(dst, op1, op2);
 11209     } else {
 11210       __ dmult(op1, op2);
 11211       __ mflo(dst);
 11213   %}
 11214   ins_pipe( pipe_slow );
 11215 %}
 11217 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11218   match(Set dst (DivL src1 src2));
 11219   format %{ "divL  $dst, $src1, $src2 @divL_reg_reg" %}
 11221   ins_encode %{
 11222     Register dst = as_Register($dst$$reg);
 11223     Register op1 = as_Register($src1$$reg);
 11224     Register op2 = as_Register($src2$$reg);
 11226     if (UseLoongsonISA) {
 11227       __ gsddiv(dst, op1, op2);
 11228     } else {
 11229       __ ddiv(op1, op2);
 11230       __ mflo(dst);
 11232   %}
 11233   ins_pipe( pipe_slow );
 11234 %}
 11236 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 11237   match(Set dst (AddF src1 src2));
 11238   format %{ "AddF  $dst, $src1, $src2 @addF_reg_reg" %}
 11239   ins_encode %{
 11240     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11241     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11242     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11244     __ add_s(dst, src1, src2);
 11245   %}
 11246   ins_pipe( fpu_regF_regF );
 11247 %}
 11249 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 11250   match(Set dst (SubF src1 src2));
 11251   format %{ "SubF  $dst, $src1, $src2 @subF_reg_reg" %}
 11252   ins_encode %{
 11253     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11254     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11255     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11257     __ sub_s(dst, src1, src2);
 11258   %}
 11259   ins_pipe( fpu_regF_regF );
 11260 %}
 11261 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 11262   match(Set dst (AddD src1 src2));
 11263   format %{ "AddD  $dst, $src1, $src2 @addD_reg_reg" %}
 11264   ins_encode %{
 11265     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11266     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11267     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11269     __ add_d(dst, src1, src2);
 11270   %}
 11271   ins_pipe( fpu_regF_regF );
 11272 %}
 11274 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 11275   match(Set dst (SubD src1 src2));
 11276   format %{ "SubD  $dst, $src1, $src2 @subD_reg_reg" %}
 11277   ins_encode %{
 11278     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11279     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11280     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11282     __ sub_d(dst, src1, src2);
 11283   %}
 11284   ins_pipe( fpu_regF_regF );
 11285 %}
 11287 instruct negF_reg(regF dst, regF src) %{
 11288   match(Set dst (NegF src));
 11289   format %{ "negF  $dst, $src @negF_reg" %}
 11290   ins_encode %{
 11291     FloatRegister src = as_FloatRegister($src$$reg);
 11292     FloatRegister dst = as_FloatRegister($dst$$reg);
 11294     __ neg_s(dst, src);
 11295   %}
 11296   ins_pipe( fpu_regF_regF );
 11297 %}
 11299 instruct negD_reg(regD dst, regD src) %{
 11300   match(Set dst (NegD src));
 11301   format %{ "negD  $dst, $src @negD_reg" %}
 11302   ins_encode %{
 11303     FloatRegister src = as_FloatRegister($src$$reg);
 11304     FloatRegister dst = as_FloatRegister($dst$$reg);
 11306     __ neg_d(dst, src);
 11307   %}
 11308   ins_pipe( fpu_regF_regF );
 11309 %}
 11312 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 11313   match(Set dst (MulF src1 src2));
 11314   format %{ "MULF  $dst, $src1, $src2 @mulF_reg_reg" %}
 11315   ins_encode %{
 11316     FloatRegister src1 = $src1$$FloatRegister;
 11317     FloatRegister src2 = $src2$$FloatRegister;
 11318     FloatRegister dst  = $dst$$FloatRegister;
 11320     __ mul_s(dst, src1, src2);
 11321   %}
 11322   ins_pipe( fpu_regF_regF );
 11323 %}
 11325 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
 11326   match(Set dst (AddF (MulF src1 src2) src3));
 11327   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 11328   ins_cost(44444);
 11329   format %{ "maddF  $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
 11330   ins_encode %{
 11331     FloatRegister src1 = $src1$$FloatRegister;
 11332     FloatRegister src2 = $src2$$FloatRegister;
 11333     FloatRegister src3 = $src3$$FloatRegister;
 11334     FloatRegister dst  = $dst$$FloatRegister;
 11336     __ madd_s(dst, src1, src2, src3);
 11337   %}
 11338   ins_pipe( fpu_regF_regF );
 11339 %}
 11341 // Mul two double precision floating piont number
 11342 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 11343   match(Set dst (MulD src1 src2));
 11344   format %{ "MULD  $dst, $src1, $src2 @mulD_reg_reg" %}
 11345   ins_encode %{
 11346     FloatRegister src1 = $src1$$FloatRegister;
 11347     FloatRegister src2 = $src2$$FloatRegister;
 11348     FloatRegister dst  = $dst$$FloatRegister;
 11350     __ mul_d(dst, src1, src2);
 11351   %}
 11352   ins_pipe( fpu_regF_regF );
 11353 %}
 11355 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
 11356   match(Set dst (AddD (MulD src1 src2) src3));
 11357   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 11358   ins_cost(44444);
 11359   format %{ "maddD  $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
 11360   ins_encode %{
 11361     FloatRegister src1 = $src1$$FloatRegister;
 11362     FloatRegister src2 = $src2$$FloatRegister;
 11363     FloatRegister src3 = $src3$$FloatRegister;
 11364     FloatRegister dst  = $dst$$FloatRegister;
 11366     __ madd_d(dst, src1, src2, src3);
 11367   %}
 11368   ins_pipe( fpu_regF_regF );
 11369 %}
 11371 instruct absF_reg(regF dst, regF src) %{
 11372   match(Set dst (AbsF src));
 11373   ins_cost(100);
 11374   format %{ "absF  $dst, $src @absF_reg" %}
 11375   ins_encode %{
 11376     FloatRegister src = as_FloatRegister($src$$reg);
 11377     FloatRegister dst = as_FloatRegister($dst$$reg);
 11379     __ abs_s(dst, src);
 11380   %}
 11381   ins_pipe( fpu_regF_regF );
 11382 %}
 11385 // intrinsics for math_native.
 11386 // AbsD  SqrtD  CosD  SinD  TanD  LogD  Log10D
 11388 instruct absD_reg(regD dst, regD src) %{
 11389   match(Set dst (AbsD src));
 11390   ins_cost(100);
 11391   format %{ "absD  $dst, $src @absD_reg" %}
 11392   ins_encode %{
 11393     FloatRegister src = as_FloatRegister($src$$reg);
 11394     FloatRegister dst = as_FloatRegister($dst$$reg);
 11396     __ abs_d(dst, src);
 11397   %}
 11398   ins_pipe( fpu_regF_regF );
 11399 %}
 11401 instruct sqrtD_reg(regD dst, regD src) %{
 11402   match(Set dst (SqrtD src));
 11403   ins_cost(100);
 11404   format %{ "SqrtD  $dst, $src @sqrtD_reg" %}
 11405   ins_encode %{
 11406     FloatRegister src = as_FloatRegister($src$$reg);
 11407     FloatRegister dst = as_FloatRegister($dst$$reg);
 11409     __ sqrt_d(dst, src);
 11410   %}
 11411   ins_pipe( fpu_regF_regF );
 11412 %}
 11414 instruct sqrtF_reg(regF dst, regF src) %{
 11415   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 11416   ins_cost(100);
 11417   format %{ "SqrtF  $dst, $src @sqrtF_reg" %}
 11418   ins_encode %{
 11419     FloatRegister src = as_FloatRegister($src$$reg);
 11420     FloatRegister dst = as_FloatRegister($dst$$reg);
 11422     __ sqrt_s(dst, src);
 11423   %}
 11424   ins_pipe( fpu_regF_regF );
 11425 %}
 11426 //----------------------------------Logical Instructions----------------------
 11427 //__________________________________Integer Logical Instructions-------------
 11429 //And Instuctions
 11430 // And Register with Immediate
 11431 instruct andI_Reg_immI(mRegI dst, mRegI src1,  immI src2) %{
 11432   match(Set dst (AndI src1 src2));
 11434   format %{ "and  $dst, $src1, $src2 #@andI_Reg_immI" %}
 11435   ins_encode %{
 11436     Register dst = $dst$$Register;
 11437     Register src = $src1$$Register;
 11438     int      val = $src2$$constant;
 11440     __ move(AT, val);
 11441     __ andr(dst, src, AT);
 11442   %}
 11443   ins_pipe( ialu_regI_regI );
 11444 %}
 11446 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 11447   match(Set dst (AndI src1 src2));
 11448   ins_cost(60);
 11450   format %{ "and  $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
 11451   ins_encode %{
 11452     Register dst = $dst$$Register;
 11453     Register src = $src1$$Register;
 11454     int      val = $src2$$constant;
 11456     __ andi(dst, src, val);
 11457   %}
 11458   ins_pipe( ialu_regI_regI );
 11459 %}
 11461 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1,  immI_nonneg_mask mask) %{
 11462   match(Set dst (AndI src1 mask));
 11463   ins_cost(60);
 11465   format %{ "and  $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
 11466   ins_encode %{
 11467     Register dst = $dst$$Register;
 11468     Register src = $src1$$Register;
 11469     int     size = Assembler::is_int_mask($mask$$constant);
 11471     __ ext(dst, src, 0, size);
 11472   %}
 11473   ins_pipe( ialu_regI_regI );
 11474 %}
 11476 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1,  immL_nonneg_mask mask) %{
 11477   match(Set dst (AndL src1 mask));
 11478   ins_cost(60);
 11480   format %{ "and  $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
 11481   ins_encode %{
 11482     Register dst = $dst$$Register;
 11483     Register src = $src1$$Register;
 11484     int     size = Assembler::is_jlong_mask($mask$$constant);
 11486     __ dext(dst, src, 0, size);
 11487   %}
 11488   ins_pipe( ialu_regI_regI );
 11489 %}
 11491 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 11492   match(Set dst (XorI src1 src2));
 11493   ins_cost(60);
 11495   format %{ "xori  $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
 11496   ins_encode %{
 11497     Register dst = $dst$$Register;
 11498     Register src = $src1$$Register;
 11499     int      val = $src2$$constant;
 11501        __ xori(dst, src, val);
 11502   %}
 11503   ins_pipe( ialu_regI_regI );
 11504 %}
 11506 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1,  immI_M1 M1) %{
 11507   match(Set dst (XorI src1 M1));
 11508   predicate(UseLoongsonISA && Use3A2000);
 11509   ins_cost(60);
 11511   format %{ "xor  $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
 11512   ins_encode %{
 11513     Register dst = $dst$$Register;
 11514     Register src = $src1$$Register;
 11516     __ gsorn(dst, R0, src);
 11517   %}
 11518   ins_pipe( ialu_regI_regI );
 11519 %}
 11521 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1,  immI_M1 M1) %{
 11522   match(Set dst (XorI (ConvL2I src1) M1));
 11523   predicate(UseLoongsonISA && Use3A2000);
 11524   ins_cost(60);
 11526   format %{ "xor  $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
 11527   ins_encode %{
 11528     Register dst = $dst$$Register;
 11529     Register src = $src1$$Register;
 11531     __ gsorn(dst, R0, src);
 11532   %}
 11533   ins_pipe( ialu_regI_regI );
 11534 %}
 11536 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 11537   match(Set dst (XorL src1 src2));
 11538   ins_cost(60);
 11540   format %{ "xori  $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
 11541   ins_encode %{
 11542     Register dst = $dst$$Register;
 11543     Register src = $src1$$Register;
 11544     int      val = $src2$$constant;
 11546        __ xori(dst, src, val);
 11547   %}
 11548   ins_pipe( ialu_regI_regI );
 11549 %}
 11551 /*
 11552 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1,  immL_M1 M1) %{
 11553   match(Set dst (XorL src1 M1));
 11554   predicate(UseLoongsonISA);
 11555   ins_cost(60);
 11557   format %{ "xor  $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
 11558   ins_encode %{
 11559     Register dst = $dst$$Register;
 11560     Register src = $src1$$Register;
 11562     __ gsorn(dst, R0, src);
 11563   %}
 11564   ins_pipe( ialu_regI_regI );
 11565 %}
 11566 */
 11568 instruct lbu_and_lmask(mRegI dst, memory mem,  immI_255 mask) %{
 11569   match(Set dst (AndI mask (LoadB mem)));
 11570   ins_cost(60);
 11572   format %{ "lhu  $dst, $mem #@lbu_and_lmask" %}
 11573   ins_encode(load_UB_enc(dst, mem));
 11574   ins_pipe( ialu_loadI );
 11575 %}
 11577 instruct lbu_and_rmask(mRegI dst, memory mem,  immI_255 mask) %{
 11578   match(Set dst (AndI (LoadB mem) mask));
 11579   ins_cost(60);
 11581   format %{ "lhu  $dst, $mem #@lbu_and_rmask" %}
 11582   ins_encode(load_UB_enc(dst, mem));
 11583   ins_pipe( ialu_loadI );
 11584 %}
 11586 instruct andI_Reg_Reg(mRegI dst, mRegI src1,  mRegI src2) %{
 11587   match(Set dst (AndI src1 src2));
 11589   format %{ "and    $dst, $src1, $src2 #@andI_Reg_Reg" %}
 11590   ins_encode %{
 11591     Register dst = $dst$$Register;
 11592     Register src1 = $src1$$Register;
 11593     Register src2 = $src2$$Register;
 11594     __ andr(dst, src1, src2);
 11595   %}
 11596   ins_pipe( ialu_regI_regI );
 11597 %}
 11599 instruct andnI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11600   match(Set dst (AndI src1 (XorI src2 M1)));
 11601   predicate(UseLoongsonISA && Use3A2000);
 11603   format %{ "andn   $dst, $src1, $src2 #@andnI_Reg_nReg" %}
 11604   ins_encode %{
 11605     Register dst = $dst$$Register;
 11606     Register src1 = $src1$$Register;
 11607     Register src2 = $src2$$Register;
 11609     __ gsandn(dst, src1, src2);
 11610   %}
 11611   ins_pipe( ialu_regI_regI );
 11612 %}
 11614 instruct ornI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11615   match(Set dst (OrI src1 (XorI src2 M1)));
 11616   predicate(UseLoongsonISA && Use3A2000);
 11618   format %{ "orn    $dst, $src1, $src2 #@ornI_Reg_nReg" %}
 11619   ins_encode %{
 11620     Register dst = $dst$$Register;
 11621     Register src1 = $src1$$Register;
 11622     Register src2 = $src2$$Register;
 11624     __ gsorn(dst, src1, src2);
 11625   %}
 11626   ins_pipe( ialu_regI_regI );
 11627 %}
 11629 instruct andnI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11630   match(Set dst (AndI (XorI src1 M1) src2));
 11631   predicate(UseLoongsonISA && Use3A2000);
 11633   format %{ "andn   $dst, $src2, $src1 #@andnI_nReg_Reg" %}
 11634   ins_encode %{
 11635     Register dst = $dst$$Register;
 11636     Register src1 = $src1$$Register;
 11637     Register src2 = $src2$$Register;
 11639     __ gsandn(dst, src2, src1);
 11640   %}
 11641   ins_pipe( ialu_regI_regI );
 11642 %}
 11644 instruct ornI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11645   match(Set dst (OrI (XorI src1 M1) src2));
 11646   predicate(UseLoongsonISA && Use3A2000);
 11648   format %{ "orn    $dst, $src2, $src1 #@ornI_nReg_Reg" %}
 11649   ins_encode %{
 11650     Register dst = $dst$$Register;
 11651     Register src1 = $src1$$Register;
 11652     Register src2 = $src2$$Register;
 11654     __ gsorn(dst, src2, src1);
 11655   %}
 11656   ins_pipe( ialu_regI_regI );
 11657 %}
 11659 // And Long Register with Register
 11660 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11661   match(Set dst (AndL src1 src2));
 11662   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
 11663   ins_encode %{
 11664     Register dst_reg = as_Register($dst$$reg);
 11665     Register src1_reg = as_Register($src1$$reg);
 11666     Register src2_reg = as_Register($src2$$reg);
 11668     __ andr(dst_reg, src1_reg, src2_reg);
 11669   %}
 11670   ins_pipe( ialu_regL_regL );
 11671 %}
 11673 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11674   match(Set dst (AndL src1 (ConvI2L src2)));
 11675   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
 11676   ins_encode %{
 11677     Register dst_reg = as_Register($dst$$reg);
 11678     Register src1_reg = as_Register($src1$$reg);
 11679     Register src2_reg = as_Register($src2$$reg);
 11681     __ andr(dst_reg, src1_reg, src2_reg);
 11682   %}
 11683   ins_pipe( ialu_regL_regL );
 11684 %}
 11686 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 11687   match(Set dst (AndL src1 src2));
 11688   ins_cost(60);
 11690   format %{ "and  $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
 11691   ins_encode %{
 11692     Register dst = $dst$$Register;
 11693     Register src = $src1$$Register;
 11694     long     val = $src2$$constant;
 11696        __ andi(dst, src, val);
 11697   %}
 11698   ins_pipe( ialu_regI_regI );
 11699 %}
 11701 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1,  immL_0_65535 src2) %{
 11702   match(Set dst (ConvL2I (AndL src1 src2)));
 11703   ins_cost(60);
 11705   format %{ "and  $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
 11706   ins_encode %{
 11707     Register dst = $dst$$Register;
 11708     Register src = $src1$$Register;
 11709     long     val = $src2$$constant;
 11711        __ andi(dst, src, val);
 11712   %}
 11713   ins_pipe( ialu_regI_regI );
 11714 %}
 11716 /*
 11717 instruct andnL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11718   match(Set dst (AndL src1 (XorL src2 M1)));
 11719   predicate(UseLoongsonISA);
 11721   format %{ "andn   $dst, $src1, $src2 #@andnL_Reg_nReg" %}
 11722   ins_encode %{
 11723     Register dst = $dst$$Register;
 11724     Register src1 = $src1$$Register;
 11725     Register src2 = $src2$$Register;
 11727     __ gsandn(dst, src1, src2);
 11728   %}
 11729   ins_pipe( ialu_regI_regI );
 11730 %}
 11731 */
 11733 /*
 11734 instruct ornL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11735   match(Set dst (OrL src1 (XorL src2 M1)));
 11736   predicate(UseLoongsonISA);
 11738   format %{ "orn    $dst, $src1, $src2 #@ornL_Reg_nReg" %}
 11739   ins_encode %{
 11740     Register dst = $dst$$Register;
 11741     Register src1 = $src1$$Register;
 11742     Register src2 = $src2$$Register;
 11744     __ gsorn(dst, src1, src2);
 11745   %}
 11746   ins_pipe( ialu_regI_regI );
 11747 %}
 11748 */
 11750 /*
 11751 instruct andnL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11752   match(Set dst (AndL (XorL src1 M1) src2));
 11753   predicate(UseLoongsonISA);
 11755   format %{ "andn   $dst, $src2, $src1 #@andnL_nReg_Reg" %}
 11756   ins_encode %{
 11757     Register dst = $dst$$Register;
 11758     Register src1 = $src1$$Register;
 11759     Register src2 = $src2$$Register;
 11761     __ gsandn(dst, src2, src1);
 11762   %}
 11763   ins_pipe( ialu_regI_regI );
 11764 %}
 11765 */
 11767 /*
 11768 instruct ornL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11769   match(Set dst (OrL (XorL src1 M1) src2));
 11770   predicate(UseLoongsonISA);
 11772   format %{ "orn    $dst, $src2, $src1 #@ornL_nReg_Reg" %}
 11773   ins_encode %{
 11774     Register dst = $dst$$Register;
 11775     Register src1 = $src1$$Register;
 11776     Register src2 = $src2$$Register;
 11778     __ gsorn(dst, src2, src1);
 11779   %}
 11780   ins_pipe( ialu_regI_regI );
 11781 %}
 11782 */
 11784 instruct andL_Reg_immL_M8(mRegL dst,  immL_M8 M8) %{
 11785   match(Set dst (AndL dst M8));
 11786   ins_cost(60);
 11788   format %{ "and  $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
 11789   ins_encode %{
 11790     Register dst = $dst$$Register;
 11792     __ dins(dst, R0, 0, 3);
 11793   %}
 11794   ins_pipe( ialu_regI_regI );
 11795 %}
 11797 instruct andL_Reg_immL_M5(mRegL dst,  immL_M5 M5) %{
 11798   match(Set dst (AndL dst M5));
 11799   ins_cost(60);
 11801   format %{ "and  $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
 11802   ins_encode %{
 11803     Register dst = $dst$$Register;
 11805     __ dins(dst, R0, 2, 1);
 11806   %}
 11807   ins_pipe( ialu_regI_regI );
 11808 %}
 11810 instruct andL_Reg_immL_M7(mRegL dst,  immL_M7 M7) %{
 11811   match(Set dst (AndL dst M7));
 11812   ins_cost(60);
 11814   format %{ "and  $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
 11815   ins_encode %{
 11816     Register dst = $dst$$Register;
 11818     __ dins(dst, R0, 1, 2);
 11819   %}
 11820   ins_pipe( ialu_regI_regI );
 11821 %}
 11823 instruct andL_Reg_immL_M4(mRegL dst,  immL_M4 M4) %{
 11824   match(Set dst (AndL dst M4));
 11825   ins_cost(60);
 11827   format %{ "and  $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
 11828   ins_encode %{
 11829     Register dst = $dst$$Register;
 11831     __ dins(dst, R0, 0, 2);
 11832   %}
 11833   ins_pipe( ialu_regI_regI );
 11834 %}
 11836 instruct andL_Reg_immL_M121(mRegL dst,  immL_M121 M121) %{
 11837   match(Set dst (AndL dst M121));
 11838   ins_cost(60);
 11840   format %{ "and  $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
 11841   ins_encode %{
 11842     Register dst = $dst$$Register;
 11844     __ dins(dst, R0, 3, 4);
 11845   %}
 11846   ins_pipe( ialu_regI_regI );
 11847 %}
 11849 // Or Long Register with Register
 11850 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11851   match(Set dst (OrL src1 src2));
 11852   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
 11853   ins_encode %{
 11854     Register dst_reg  = $dst$$Register;
 11855     Register src1_reg = $src1$$Register;
 11856     Register src2_reg = $src2$$Register;
 11858     __ orr(dst_reg, src1_reg, src2_reg);
 11859   %}
 11860   ins_pipe( ialu_regL_regL );
 11861 %}
 11863 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
 11864   match(Set dst (OrL (CastP2X src1) src2));
 11865   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
 11866   ins_encode %{
 11867     Register dst_reg  = $dst$$Register;
 11868     Register src1_reg = $src1$$Register;
 11869     Register src2_reg = $src2$$Register;
 11871     __ orr(dst_reg, src1_reg, src2_reg);
 11872   %}
 11873   ins_pipe( ialu_regL_regL );
 11874 %}
 11876 // Xor Long Register with Register
 11877 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11878   match(Set dst (XorL src1 src2));
 11879   format %{ "XOR    $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
 11880   ins_encode %{
 11881     Register dst_reg = as_Register($dst$$reg);
 11882     Register src1_reg = as_Register($src1$$reg);
 11883     Register src2_reg = as_Register($src2$$reg);
 11885     __ xorr(dst_reg, src1_reg, src2_reg);
 11886   %}
 11887   ins_pipe( ialu_regL_regL );
 11888 %}
 11890 // Shift Left by 8-bit immediate
 11891 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 11892   match(Set dst (LShiftI src shift));
 11894   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm" %}
 11895   ins_encode %{
 11896     Register src = $src$$Register;
 11897     Register dst = $dst$$Register;
 11898     int    shamt = $shift$$constant;
 11900     __ sll(dst, src, shamt);
 11901   %}
 11902   ins_pipe( ialu_regI_regI );
 11903 %}
 11905 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
 11906   match(Set dst (LShiftI (ConvL2I src) shift));
 11908   format %{ "SHL    $dst, $src, $shift #@salL2I_Reg_imm" %}
 11909   ins_encode %{
 11910     Register src = $src$$Register;
 11911     Register dst = $dst$$Register;
 11912     int    shamt = $shift$$constant;
 11914     __ sll(dst, src, shamt);
 11915   %}
 11916   ins_pipe( ialu_regI_regI );
 11917 %}
 11919 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
 11920   match(Set dst (AndI (LShiftI src shift) mask));
 11922   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
 11923   ins_encode %{
 11924     Register src = $src$$Register;
 11925     Register dst = $dst$$Register;
 11927     __ sll(dst, src, 16);
 11928   %}
 11929   ins_pipe( ialu_regI_regI );
 11930 %}
 11932 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
 11933 %{
 11934   match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
 11936   format %{ "andi  $dst, $src, 7\t# @land7_2_s" %}
 11937   ins_encode %{
 11938     Register src = $src$$Register;
 11939     Register dst = $dst$$Register;
 11941     __ andi(dst, src, 7);
 11942   %}
 11943   ins_pipe(ialu_regI_regI);
 11944 %}
 11946 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
 11947 %{
 11948   match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
 11950   format %{ "ori  $dst, $src1, $src2\t# @ori2s" %}
 11951   ins_encode %{
 11952     Register src = $src1$$Register;
 11953     int      val = $src2$$constant;
 11954     Register dst = $dst$$Register;
 11956     __ ori(dst, src, val);
 11957   %}
 11958   ins_pipe(ialu_regI_regI);
 11959 %}
 11961 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
 11962 // This idiom is used by the compiler the i2s bytecode.
 11963 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
 11964 %{
 11965   match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
 11967   format %{ "i2s  $dst, $src\t# @i2s" %}
 11968   ins_encode %{
 11969     Register src = $src$$Register;
 11970     Register dst = $dst$$Register;
 11972     __ seh(dst, src);
 11973   %}
 11974   ins_pipe(ialu_regI_regI);
 11975 %}
 11977 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 11978 // This idiom is used by the compiler for the i2b bytecode.
 11979 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
 11980 %{
 11981   match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
 11983   format %{ "i2b  $dst, $src\t# @i2b" %}
 11984   ins_encode %{
 11985     Register src = $src$$Register;
 11986     Register dst = $dst$$Register;
 11988     __ seb(dst, src);
 11989   %}
 11990   ins_pipe(ialu_regI_regI);
 11991 %}
 11994 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
 11995   match(Set dst (LShiftI (ConvL2I src) shift));
 11997   format %{ "SHL    $dst, $src, $shift #@salI_RegL2I_imm" %}
 11998   ins_encode %{
 11999     Register src = $src$$Register;
 12000     Register dst = $dst$$Register;
 12001     int    shamt = $shift$$constant;
 12003     __ sll(dst, src, shamt);
 12004   %}
 12005   ins_pipe( ialu_regI_regI );
 12006 %}
 12008 // Shift Left by 8-bit immediate
 12009 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12010   match(Set dst (LShiftI src shift));
 12012   format %{ "SHL    $dst, $src, $shift #@salI_Reg_Reg" %}
 12013   ins_encode %{
 12014     Register src = $src$$Register;
 12015     Register dst = $dst$$Register;
 12016     Register shamt = $shift$$Register;
 12017     __ sllv(dst, src, shamt);
 12018   %}
 12019   ins_pipe( ialu_regI_regI );
 12020 %}
 12023 // Shift Left Long
 12024 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 12025   //predicate(UseNewLongLShift);
 12026   match(Set dst (LShiftL src shift));
 12027   ins_cost(100);
 12028   format %{ "salL    $dst, $src, $shift @ salL_Reg_imm" %}
 12029   ins_encode %{
 12030     Register src_reg = as_Register($src$$reg);
 12031     Register dst_reg = as_Register($dst$$reg);
 12032     int      shamt = $shift$$constant;
 12034     if (__ is_simm(shamt, 5))
 12035         __ dsll(dst_reg, src_reg, shamt);
 12036     else {
 12037       int sa = Assembler::low(shamt, 6);
 12038       if (sa < 32) {
 12039         __ dsll(dst_reg, src_reg, sa);
 12040       } else {
 12041         __ dsll32(dst_reg, src_reg, sa - 32);
 12044   %}
 12045   ins_pipe( ialu_regL_regL );
 12046 %}
 12048 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
 12049   //predicate(UseNewLongLShift);
 12050   match(Set dst (LShiftL (ConvI2L src) shift));
 12051   ins_cost(100);
 12052   format %{ "salL    $dst, $src, $shift @ salL_RegI2L_imm" %}
 12053   ins_encode %{
 12054     Register src_reg = as_Register($src$$reg);
 12055     Register dst_reg = as_Register($dst$$reg);
 12056     int      shamt = $shift$$constant;
 12058     if (__ is_simm(shamt, 5))
 12059         __ dsll(dst_reg, src_reg, shamt);
 12060     else {
 12061       int sa = Assembler::low(shamt, 6);
 12062       if (sa < 32) {
 12063         __ dsll(dst_reg, src_reg, sa);
 12064       } else {
 12065         __ dsll32(dst_reg, src_reg, sa - 32);
 12068   %}
 12069   ins_pipe( ialu_regL_regL );
 12070 %}
 12072 // Shift Left Long
 12073 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12074   //predicate(UseNewLongLShift);
 12075   match(Set dst (LShiftL src shift));
 12076   ins_cost(100);
 12077   format %{ "salL    $dst, $src, $shift @ salL_Reg_Reg" %}
 12078   ins_encode %{
 12079     Register src_reg = as_Register($src$$reg);
 12080     Register dst_reg = as_Register($dst$$reg);
 12082     __ dsllv(dst_reg, src_reg, $shift$$Register);
 12083   %}
 12084   ins_pipe( ialu_regL_regL );
 12085 %}
 12087 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
 12088   match(Set dst (LShiftL (ConvI2L src) shift));
 12089   ins_cost(100);
 12090   format %{ "salL    $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
 12091   ins_encode %{
 12092     Register src_reg = as_Register($src$$reg);
 12093     Register dst_reg = as_Register($dst$$reg);
 12094     int      shamt = $shift$$constant;
 12096     if (__ is_simm(shamt, 5)) {
 12097       __ dsll(dst_reg, src_reg, shamt);
 12098     } else {
 12099       int sa = Assembler::low(shamt, 6);
 12100       if (sa < 32) {
 12101         __ dsll(dst_reg, src_reg, sa);
 12102       } else {
 12103         __ dsll32(dst_reg, src_reg, sa - 32);
 12106     %}
 12107   ins_pipe( ialu_regL_regL );
 12108 %}
 12110 // Shift Right Long
 12111 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 12112   match(Set dst (RShiftL src shift));
 12113   ins_cost(100);
 12114   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_imm" %}
 12115   ins_encode %{
 12116     Register src_reg = as_Register($src$$reg);
 12117     Register dst_reg = as_Register($dst$$reg);
 12118     int      shamt = ($shift$$constant & 0x3f);
 12119     if (__  is_simm(shamt, 5))
 12120       __ dsra(dst_reg, src_reg, shamt);
 12121     else {
 12122       int sa = Assembler::low(shamt, 6);
 12123       if (sa < 32) {
 12124         __ dsra(dst_reg, src_reg, sa);
 12125       } else {
 12126         __ dsra32(dst_reg, src_reg, sa - 32);
 12129   %}
 12130   ins_pipe( ialu_regL_regL );
 12131 %}
 12133 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
 12134   match(Set dst (ConvL2I (RShiftL src shift)));
 12135   ins_cost(100);
 12136   format %{ "sarL    $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
 12137   ins_encode %{
 12138     Register src_reg = as_Register($src$$reg);
 12139     Register dst_reg = as_Register($dst$$reg);
 12140     int      shamt   = $shift$$constant;
 12142     __ dsra32(dst_reg, src_reg, shamt - 32);
 12143   %}
 12144   ins_pipe( ialu_regL_regL );
 12145 %}
 12147 // Shift Right Long arithmetically
 12148 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12149   //predicate(UseNewLongLShift);
 12150   match(Set dst (RShiftL src shift));
 12151   ins_cost(100);
 12152   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_Reg" %}
 12153   ins_encode %{
 12154     Register src_reg = as_Register($src$$reg);
 12155     Register dst_reg = as_Register($dst$$reg);
 12157     __ dsrav(dst_reg, src_reg, $shift$$Register);
 12158   %}
 12159   ins_pipe( ialu_regL_regL );
 12160 %}
 12162 // Shift Right Long logically
 12163 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12164   match(Set dst (URShiftL src shift));
 12165   ins_cost(100);
 12166   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_Reg" %}
 12167   ins_encode %{
 12168     Register src_reg = as_Register($src$$reg);
 12169     Register dst_reg = as_Register($dst$$reg);
 12171     __ dsrlv(dst_reg, src_reg, $shift$$Register);
 12172   %}
 12173   ins_pipe( ialu_regL_regL );
 12174 %}
 12176 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
 12177   match(Set dst (URShiftL src shift));
 12178   ins_cost(80);
 12179   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
 12180   ins_encode %{
 12181     Register src_reg = as_Register($src$$reg);
 12182     Register dst_reg = as_Register($dst$$reg);
 12183     int        shamt = $shift$$constant;
 12185     __ dsrl(dst_reg, src_reg, shamt);
 12186   %}
 12187   ins_pipe( ialu_regL_regL );
 12188 %}
 12190 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
 12191   match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
 12192   ins_cost(80);
 12193   format %{ "dext    $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
 12194   ins_encode %{
 12195     Register src_reg = as_Register($src$$reg);
 12196     Register dst_reg = as_Register($dst$$reg);
 12197     int        shamt = $shift$$constant;
 12199     __ dext(dst_reg, src_reg, shamt, 31);
 12200   %}
 12201   ins_pipe( ialu_regL_regL );
 12202 %}
 12204 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
 12205   match(Set dst (URShiftL (CastP2X src) shift));
 12206   ins_cost(80);
 12207   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
 12208   ins_encode %{
 12209     Register src_reg = as_Register($src$$reg);
 12210     Register dst_reg = as_Register($dst$$reg);
 12211     int        shamt = $shift$$constant;
 12213     __ dsrl(dst_reg, src_reg, shamt);
 12214   %}
 12215   ins_pipe( ialu_regL_regL );
 12216 %}
 12218 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
 12219   match(Set dst (URShiftL src shift));
 12220   ins_cost(80);
 12221   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
 12222   ins_encode %{
 12223     Register src_reg = as_Register($src$$reg);
 12224     Register dst_reg = as_Register($dst$$reg);
 12225     int        shamt = $shift$$constant;
 12227     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12228   %}
 12229   ins_pipe( ialu_regL_regL );
 12230 %}
 12232 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
 12233   match(Set dst (ConvL2I (URShiftL src shift)));
 12234   predicate(n->in(1)->in(2)->get_int() > 32);
 12235   ins_cost(80);
 12236   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
 12237   ins_encode %{
 12238     Register src_reg = as_Register($src$$reg);
 12239     Register dst_reg = as_Register($dst$$reg);
 12240     int        shamt = $shift$$constant;
 12242     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12243   %}
 12244   ins_pipe( ialu_regL_regL );
 12245 %}
 12247 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
 12248   match(Set dst (URShiftL (CastP2X src) shift));
 12249   ins_cost(80);
 12250   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
 12251   ins_encode %{
 12252     Register src_reg = as_Register($src$$reg);
 12253     Register dst_reg = as_Register($dst$$reg);
 12254     int        shamt = $shift$$constant;
 12256     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12257   %}
 12258   ins_pipe( ialu_regL_regL );
 12259 %}
 12261 // Xor Instructions
 12262 // Xor Register with Register
 12263 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 12264   match(Set dst (XorI src1 src2));
 12266   format %{ "XOR    $dst, $src1, $src2 #@xorI_Reg_Reg" %}
 12268   ins_encode %{
 12269     Register  dst = $dst$$Register;
 12270     Register src1 = $src1$$Register;
 12271     Register src2 = $src2$$Register;
 12272     __ xorr(dst, src1, src2);
 12273     __ sll(dst, dst, 0); /* long -> int */
 12274   %}
 12276   ins_pipe( ialu_regI_regI );
 12277 %}
 12279 // Or Instructions
 12280 // Or Register with Register
 12281 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 12282   match(Set dst (OrI src1 src2));
 12284   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_Reg" %}
 12285   ins_encode %{
 12286     Register  dst = $dst$$Register;
 12287     Register src1 = $src1$$Register;
 12288     Register src2 = $src2$$Register;
 12289     __ orr(dst, src1, src2);
 12290   %}
 12292   ins_pipe( ialu_regI_regI );
 12293 %}
 12295 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
 12296   match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
 12297   predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
 12299   format %{ "rotr     $dst, $src, 1 ...\n\t"
 12300             "srl      $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
 12301   ins_encode %{
 12302     Register   dst = $dst$$Register;
 12303     Register   src = $src$$Register;
 12304     int     rshift = $rshift$$constant;
 12306     __ rotr(dst, src, 1);
 12307     if (rshift - 1) {
 12308       __ srl(dst, dst, rshift - 1);
 12310   %}
 12312   ins_pipe( ialu_regI_regI );
 12313 %}
 12315 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
 12316   match(Set dst (OrI src1 (CastP2X src2)));
 12318   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_castP2X" %}
 12319   ins_encode %{
 12320     Register  dst = $dst$$Register;
 12321     Register src1 = $src1$$Register;
 12322     Register src2 = $src2$$Register;
 12323     __ orr(dst, src1, src2);
 12324   %}
 12326   ins_pipe( ialu_regI_regI );
 12327 %}
 12329 // Logical Shift Right by 8-bit immediate
 12330 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 12331   match(Set dst (URShiftI src shift));
 12332   //effect(KILL cr);
 12334   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_imm" %}
 12335   ins_encode %{
 12336     Register src = $src$$Register;
 12337     Register dst = $dst$$Register;
 12338     int    shift = $shift$$constant;
 12340     __ srl(dst, src, shift);
 12341   %}
 12342   ins_pipe( ialu_regI_regI );
 12343 %}
 12345 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
 12346   match(Set dst (AndI (URShiftI src shift) mask));
 12348   format %{ "ext    $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
 12349   ins_encode %{
 12350     Register src = $src$$Register;
 12351     Register dst = $dst$$Register;
 12352     int      pos = $shift$$constant;
 12353     int     size = Assembler::is_int_mask($mask$$constant);
 12355     __ ext(dst, src, pos, size);
 12356   %}
 12357   ins_pipe( ialu_regI_regI );
 12358 %}
 12360 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
 12361 %{
 12362   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 12363   match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
 12365   ins_cost(100);
 12366   format %{ "rotr    $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
 12367   ins_encode %{
 12368     Register dst = $dst$$Register;
 12369     int      sa  = $rshift$$constant;
 12371     __ rotr(dst, dst, sa);
 12372   %}
 12373   ins_pipe( ialu_regI_regI );
 12374 %}
 12376 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
 12377 %{
 12378   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12379   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 12381   ins_cost(100);
 12382   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
 12383   ins_encode %{
 12384     Register dst = $dst$$Register;
 12385     int      sa  = $rshift$$constant;
 12387     __ drotr(dst, dst, sa);
 12388   %}
 12389   ins_pipe( ialu_regI_regI );
 12390 %}
 12392 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
 12393 %{
 12394   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12395   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 12397   ins_cost(100);
 12398   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
 12399   ins_encode %{
 12400     Register dst = $dst$$Register;
 12401     int      sa  = $rshift$$constant;
 12403     __ drotr32(dst, dst, sa - 32);
 12404   %}
 12405   ins_pipe( ialu_regI_regI );
 12406 %}
 12408 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
 12409 %{
 12410   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 12411   match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
 12413   ins_cost(100);
 12414   format %{ "rotr    $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
 12415   ins_encode %{
 12416     Register dst = $dst$$Register;
 12417     int      sa  = $rshift$$constant;
 12419     __ rotr(dst, dst, sa);
 12420   %}
 12421   ins_pipe( ialu_regI_regI );
 12422 %}
 12424 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
 12425 %{
 12426   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12427   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 12429   ins_cost(100);
 12430   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
 12431   ins_encode %{
 12432     Register dst = $dst$$Register;
 12433     int      sa  = $rshift$$constant;
 12435     __ drotr(dst, dst, sa);
 12436   %}
 12437   ins_pipe( ialu_regI_regI );
 12438 %}
 12440 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
 12441 %{
 12442   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12443   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 12445   ins_cost(100);
 12446   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
 12447   ins_encode %{
 12448     Register dst = $dst$$Register;
 12449     int      sa  = $rshift$$constant;
 12451     __ drotr32(dst, dst, sa - 32);
 12452   %}
 12453   ins_pipe( ialu_regI_regI );
 12454 %}
 12456 // Logical Shift Right
 12457 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12458   match(Set dst (URShiftI src shift));
 12460   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_Reg" %}
 12461   ins_encode %{
 12462     Register src = $src$$Register;
 12463     Register dst = $dst$$Register;
 12464     Register shift = $shift$$Register;
 12465     __ srlv(dst, src, shift);
 12466   %}
 12467   ins_pipe( ialu_regI_regI );
 12468 %}
 12471 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 12472   match(Set dst (RShiftI src shift));
 12473  // effect(KILL cr);
 12475   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_imm" %}
 12476   ins_encode %{
 12477     Register src = $src$$Register;
 12478     Register dst = $dst$$Register;
 12479     int    shift = $shift$$constant;
 12480     __ sra(dst, src, shift);
 12481   %}
 12482   ins_pipe( ialu_regI_regI );
 12483 %}
 12485 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12486   match(Set dst (RShiftI src shift));
 12487  // effect(KILL cr);
 12489   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_Reg" %}
 12490   ins_encode %{
 12491     Register src = $src$$Register;
 12492     Register dst = $dst$$Register;
 12493     Register shift = $shift$$Register;
 12494     __ srav(dst, src, shift);
 12495   %}
 12496   ins_pipe( ialu_regI_regI );
 12497 %}
 12499 //----------Convert Int to Boolean---------------------------------------------
 12501 instruct convI2B(mRegI dst, mRegI src) %{
 12502   match(Set dst (Conv2B src));
 12504   ins_cost(100);
 12505   format %{ "convI2B    $dst, $src @ convI2B"  %}
 12506   ins_encode %{
 12507     Register dst = as_Register($dst$$reg);
 12508     Register src = as_Register($src$$reg);
 12510     if (dst != src) {
 12511       __ daddiu(dst, R0, 1);
 12512       __ movz(dst, R0, src);
 12513     } else {
 12514       __ move(AT, src);
 12515       __ daddiu(dst, R0, 1);
 12516       __ movz(dst, R0, AT);
 12518   %}
 12520   ins_pipe( ialu_regL_regL );
 12521 %}
 12523 instruct convI2L_reg( mRegL dst, mRegI src) %{
 12524   match(Set dst (ConvI2L src));
 12526   ins_cost(100);
 12527   format %{ "SLL    $dst, $src @ convI2L_reg\t"  %}
 12528   ins_encode %{
 12529     Register dst = as_Register($dst$$reg);
 12530     Register src = as_Register($src$$reg);
 12532     if(dst != src) __ sll(dst, src, 0);
 12533   %}
 12534   ins_pipe( ialu_regL_regL );
 12535 %}
 12538 instruct convL2I_reg( mRegI dst, mRegL src ) %{
 12539   match(Set dst (ConvL2I src));
 12541   format %{ "MOV    $dst, $src @ convL2I_reg" %}
 12542   ins_encode %{
 12543     Register dst = as_Register($dst$$reg);
 12544     Register src = as_Register($src$$reg);
 12546     __ sll(dst, src, 0);
 12547   %}
 12549   ins_pipe( ialu_regI_regI );
 12550 %}
 12552 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
 12553   match(Set dst (ConvI2L (ConvL2I src)));
 12555   format %{ "sll    $dst, $src, 0 @ convL2I2L_reg" %}
 12556   ins_encode %{
 12557     Register dst = as_Register($dst$$reg);
 12558     Register src = as_Register($src$$reg);
 12560     __ sll(dst, src, 0);
 12561   %}
 12563   ins_pipe( ialu_regI_regI );
 12564 %}
 12566 instruct convL2D_reg( regD dst, mRegL src ) %{
 12567   match(Set dst (ConvL2D src));
 12568   format %{ "convL2D    $dst, $src @ convL2D_reg" %}
 12569   ins_encode %{
 12570     Register src = as_Register($src$$reg);
 12571     FloatRegister dst = as_FloatRegister($dst$$reg);
 12573     __ dmtc1(src, dst);
 12574     __ cvt_d_l(dst, dst);
 12575   %}
 12577   ins_pipe( pipe_slow );
 12578 %}
 12581 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
 12582   match(Set dst (ConvD2L src));
 12583   ins_cost(150);
 12584   format %{ "convD2L    $dst, $src @ convD2L_reg_fast" %}
 12585   ins_encode %{
 12586     Register dst = as_Register($dst$$reg);
 12587     FloatRegister src = as_FloatRegister($src$$reg);
 12589     Label Done;
 12591     __ trunc_l_d(F30, src);
 12592     // max_long:    0x7fffffffffffffff
 12593     // __ set64(AT, 0x7fffffffffffffff);
 12594     __ daddiu(AT, R0, -1);
 12595     __ dsrl(AT, AT, 1);
 12596     __ dmfc1(dst, F30);
 12598     __ bne(dst, AT, Done);
 12599     __ delayed()->mtc1(R0, F30);
 12601     __ cvt_d_w(F30, F30);
 12602     __ c_ult_d(src, F30);
 12603     __ bc1f(Done);
 12604     __ delayed()->daddiu(T9, R0, -1);
 12606     __ c_un_d(src, src);    //NaN?
 12607     __ subu(dst, T9, AT);
 12608     __ movt(dst, R0);
 12610     __ bind(Done);
 12611   %}
 12613   ins_pipe( pipe_slow );
 12614 %}
 12617 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
 12618   match(Set dst (ConvD2L src));
 12619   ins_cost(250);
 12620   format %{ "convD2L    $dst, $src @ convD2L_reg_slow" %}
 12621   ins_encode %{
 12622     Register dst = as_Register($dst$$reg);
 12623     FloatRegister src = as_FloatRegister($src$$reg);
 12625     Label L;
 12627     __ c_un_d(src, src);    //NaN?
 12628     __ bc1t(L);
 12629     __ delayed();
 12630     __ move(dst, R0);
 12632     __ trunc_l_d(F30, src);
 12633     __ cfc1(AT, 31);
 12634     __ li(T9, 0x10000);
 12635     __ andr(AT, AT, T9);
 12636     __ beq(AT, R0, L);
 12637     __ delayed()->dmfc1(dst, F30);
 12639     __ mov_d(F12, src);
 12640     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
 12641     __ move(dst, V0);
 12642     __ bind(L);
 12643   %}
 12645   ins_pipe( pipe_slow );
 12646 %}
 12649 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
 12650   match(Set dst (ConvF2I src));
 12651   ins_cost(150);
 12652   format %{ "convf2i    $dst, $src @ convF2I_reg_fast" %}
 12653   ins_encode %{
 12654     Register      dreg = $dst$$Register;
 12655     FloatRegister fval = $src$$FloatRegister;
 12656     Label L;
 12658     __ trunc_w_s(F30, fval);
 12659     __ move(AT, 0x7fffffff);
 12660     __ mfc1(dreg, F30);
 12661     __ c_un_s(fval, fval);    //NaN?
 12662     __ movt(dreg, R0);
 12664     __ bne(AT, dreg, L);
 12665     __ delayed()->lui(T9, 0x8000);
 12667     __ mfc1(AT, fval);
 12668     __ andr(AT, AT, T9);
 12670     __ movn(dreg, T9, AT);
 12672     __ bind(L);
 12674   %}
 12676   ins_pipe( pipe_slow );
 12677 %}
 12681 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
 12682   match(Set dst (ConvF2I src));
 12683   ins_cost(250);
 12684   format %{ "convf2i    $dst, $src @ convF2I_reg_slow" %}
 12685   ins_encode %{
 12686     Register      dreg = $dst$$Register;
 12687     FloatRegister fval = $src$$FloatRegister;
 12688     Label L;
 12690     __ c_un_s(fval, fval);    //NaN?
 12691     __ bc1t(L);
 12692     __ delayed();
 12693     __ move(dreg, R0);
 12695     __ trunc_w_s(F30, fval);
 12697     /* Call SharedRuntime:f2i() to do valid convention */
 12698     __ cfc1(AT, 31);
 12699     __ li(T9, 0x10000);
 12700     __ andr(AT, AT, T9);
 12701     __ beq(AT, R0, L);
 12702     __ delayed()->mfc1(dreg, F30);
 12704     __ mov_s(F12, fval);
 12706     /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
 12707      *    J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
 12709      * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
 12710      * V0 is corrupted during call_VM_leaf(), and should be preserved.
 12711      */
 12712     __ push(fval);
 12713     if(dreg != V0) {
 12714       __ push(V0);
 12716     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
 12717     if(dreg != V0) {
 12718       __ move(dreg, V0);
 12719       __ pop(V0);
 12721     __ pop(fval);
 12722     __ bind(L);
 12723   %}
 12725   ins_pipe( pipe_slow );
 12726 %}
 12729 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
 12730   match(Set dst (ConvF2L src));
 12731   ins_cost(150);
 12732   format %{ "convf2l    $dst, $src @ convF2L_reg_fast" %}
 12733   ins_encode %{
 12734     Register      dreg = $dst$$Register;
 12735     FloatRegister fval = $src$$FloatRegister;
 12736     Label L;
 12738     __ trunc_l_s(F30, fval);
 12739     __ daddiu(AT, R0, -1);
 12740     __ dsrl(AT, AT, 1);
 12741     __ dmfc1(dreg, F30);
 12742     __ c_un_s(fval, fval);    //NaN?
 12743     __ movt(dreg, R0);
 12745     __ bne(AT, dreg, L);
 12746     __ delayed()->lui(T9, 0x8000);
 12748     __ mfc1(AT, fval);
 12749     __ andr(AT, AT, T9);
 12751     __ dsll32(T9, T9, 0);
 12752     __ movn(dreg, T9, AT);
 12754     __ bind(L);
 12755   %}
 12757   ins_pipe( pipe_slow );
 12758 %}
 12761 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
 12762   match(Set dst (ConvF2L src));
 12763   ins_cost(250);
 12764   format %{ "convf2l    $dst, $src @ convF2L_reg_slow" %}
 12765   ins_encode %{
 12766     Register dst = as_Register($dst$$reg);
 12767     FloatRegister fval = $src$$FloatRegister;
 12768     Label L;
 12770     __ c_un_s(fval, fval);    //NaN?
 12771     __ bc1t(L);
 12772     __ delayed();
 12773     __ move(dst, R0);
 12775     __ trunc_l_s(F30, fval);
 12776     __ cfc1(AT, 31);
 12777     __ li(T9, 0x10000);
 12778     __ andr(AT, AT, T9);
 12779     __ beq(AT, R0, L);
 12780     __ delayed()->dmfc1(dst, F30);
 12782     __ mov_s(F12, fval);
 12783     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
 12784     __ move(dst, V0);
 12785     __ bind(L);
 12786   %}
 12788   ins_pipe( pipe_slow );
 12789 %}
 12791 instruct convL2F_reg( regF dst, mRegL src ) %{
 12792   match(Set dst (ConvL2F src));
 12793   format %{ "convl2f    $dst, $src @ convL2F_reg" %}
 12794   ins_encode %{
 12795     FloatRegister dst = $dst$$FloatRegister;
 12796     Register src = as_Register($src$$reg);
 12797     Label L;
 12799     __ dmtc1(src, dst);
 12800     __ cvt_s_l(dst, dst);
 12801   %}
 12803   ins_pipe( pipe_slow );
 12804 %}
 12806 instruct convI2F_reg( regF dst, mRegI src ) %{
 12807   match(Set dst (ConvI2F src));
 12808   format %{ "convi2f    $dst, $src @ convI2F_reg" %}
 12809   ins_encode %{
 12810     Register      src = $src$$Register;
 12811     FloatRegister dst = $dst$$FloatRegister;
 12813     __ mtc1(src, dst);
 12814     __ cvt_s_w(dst, dst);
 12815   %}
 12817   ins_pipe( fpu_regF_regF );
 12818 %}
 12820 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
 12821   match(Set dst (CmpLTMask p zero));
 12822   ins_cost(100);
 12824   format %{ "sra    $dst, $p, 31 @ cmpLTMask_immI0" %}
 12825     ins_encode %{
 12826        Register src = $p$$Register;
 12827        Register dst = $dst$$Register;
 12829        __ sra(dst, src, 31);
 12830     %}
 12831     ins_pipe( pipe_slow );
 12832 %}
 12835 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
 12836   match(Set dst (CmpLTMask p q));
 12837   ins_cost(400);
 12839   format %{ "cmpLTMask    $dst, $p, $q @ cmpLTMask" %}
 12840   ins_encode %{
 12841     Register p   = $p$$Register;
 12842     Register q   = $q$$Register;
 12843     Register dst = $dst$$Register;
 12845     __ slt(dst, p, q);
 12846     __ subu(dst, R0, dst);
 12847     %}
 12848   ins_pipe( pipe_slow );
 12849 %}
 12851 instruct convP2B(mRegI dst, mRegP src) %{
 12852   match(Set dst (Conv2B src));
 12854   ins_cost(100);
 12855   format %{ "convP2B    $dst, $src @ convP2B"  %}
 12856   ins_encode %{
 12857     Register dst = as_Register($dst$$reg);
 12858     Register src = as_Register($src$$reg);
 12860     if (dst != src) {
 12861       __ daddiu(dst, R0, 1);
 12862       __ movz(dst, R0, src);
 12863     } else {
 12864       __ move(AT, src);
 12865       __ daddiu(dst, R0, 1);
 12866       __ movz(dst, R0, AT);
 12868   %}
 12870   ins_pipe( ialu_regL_regL );
 12871 %}
 12874 instruct convI2D_reg_reg(regD dst, mRegI src) %{
 12875   match(Set dst (ConvI2D src));
 12876   format %{ "conI2D $dst, $src @convI2D_reg" %}
 12877   ins_encode %{
 12878     Register      src = $src$$Register;
 12879     FloatRegister dst = $dst$$FloatRegister;
 12880     __ mtc1(src, dst);
 12881     __ cvt_d_w(dst, dst);
 12882     %}
 12883   ins_pipe( fpu_regF_regF );
 12884 %}
 12886 instruct convF2D_reg_reg(regD dst, regF src) %{
 12887   match(Set dst (ConvF2D src));
 12888   format %{ "convF2D  $dst, $src\t# @convF2D_reg_reg" %}
 12889   ins_encode %{
 12890     FloatRegister dst = $dst$$FloatRegister;
 12891     FloatRegister src = $src$$FloatRegister;
 12893     __ cvt_d_s(dst, src);
 12894   %}
 12895   ins_pipe( fpu_regF_regF );
 12896 %}
 12898 instruct convD2F_reg_reg(regF dst, regD src) %{
 12899   match(Set dst (ConvD2F src));
 12900   format %{ "convD2F  $dst, $src\t# @convD2F_reg_reg" %}
 12901   ins_encode %{
 12902     FloatRegister dst = $dst$$FloatRegister;
 12903     FloatRegister src = $src$$FloatRegister;
 12905     __ cvt_s_d(dst, src);
 12906   %}
 12907   ins_pipe( fpu_regF_regF );
 12908 %}
 12911 // Convert a double to an int.  If the double is a NAN, stuff a zero in instead.
 12912 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
 12913   match(Set dst (ConvD2I src));
 12915   ins_cost(150);
 12916   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
 12918   ins_encode %{
 12919     FloatRegister src = $src$$FloatRegister;
 12920     Register      dst = $dst$$Register;
 12922     Label Done;
 12924     __ trunc_w_d(F30, src);
 12925     // max_int: 2147483647
 12926     __ move(AT, 0x7fffffff);
 12927     __ mfc1(dst, F30);
 12929     __ bne(dst, AT, Done);
 12930     __ delayed()->mtc1(R0, F30);
 12932     __ cvt_d_w(F30, F30);
 12933     __ c_ult_d(src, F30);
 12934     __ bc1f(Done);
 12935     __ delayed()->addiu(T9, R0, -1);
 12937     __ c_un_d(src, src);    //NaN?
 12938     __ subu32(dst, T9, AT);
 12939     __ movt(dst, R0);
 12941     __ bind(Done);
 12942   %}
 12943   ins_pipe( pipe_slow );
 12944 %}
 12947 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
 12948   match(Set dst (ConvD2I src));
 12950   ins_cost(250);
 12951   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
 12953   ins_encode %{
 12954     FloatRegister src = $src$$FloatRegister;
 12955     Register      dst = $dst$$Register;
 12956     Label L;
 12958     __ trunc_w_d(F30, src);
 12959     __ cfc1(AT, 31);
 12960     __ li(T9, 0x10000);
 12961     __ andr(AT, AT, T9);
 12962     __ beq(AT, R0, L);
 12963     __ delayed()->mfc1(dst, F30);
 12965     __ mov_d(F12, src);
 12966     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
 12967     __ move(dst, V0);
 12968     __ bind(L);
 12970   %}
 12971   ins_pipe( pipe_slow );
 12972 %}
 12974 // Convert oop pointer into compressed form
 12975 instruct encodeHeapOop(mRegN dst, mRegP src) %{
 12976   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 12977   match(Set dst (EncodeP src));
 12978   format %{ "encode_heap_oop $dst,$src" %}
 12979   ins_encode %{
 12980     Register src = $src$$Register;
 12981     Register dst = $dst$$Register;
 12983     __ encode_heap_oop(dst, src);
 12984   %}
 12985   ins_pipe( ialu_regL_regL );
 12986 %}
 12988 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
 12989   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
 12990   match(Set dst (EncodeP src));
 12991   format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
 12992   ins_encode %{
 12993     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
 12994   %}
 12995   ins_pipe( ialu_regL_regL );
 12996 %}
 12998 instruct decodeHeapOop(mRegP dst, mRegN src) %{
 12999   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
 13000             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
 13001   match(Set dst (DecodeN src));
 13002   format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
 13003   ins_encode %{
 13004     Register s = $src$$Register;
 13005     Register d = $dst$$Register;
 13007     __ decode_heap_oop(d, s);
 13008   %}
 13009   ins_pipe( ialu_regL_regL );
 13010 %}
 13012 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
 13013   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
 13014             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
 13015   match(Set dst (DecodeN src));
 13016   format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
 13017   ins_encode %{
 13018     Register s = $src$$Register;
 13019     Register d = $dst$$Register;
 13020     if (s != d) {
 13021       __ decode_heap_oop_not_null(d, s);
 13022     } else {
 13023       __ decode_heap_oop_not_null(d);
 13025   %}
 13026   ins_pipe( ialu_regL_regL );
 13027 %}
 13029 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
 13030   match(Set dst (EncodePKlass src));
 13031   format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
 13032   ins_encode %{
 13033     __ encode_klass_not_null($dst$$Register, $src$$Register);
 13034   %}
 13035   ins_pipe( ialu_regL_regL );
 13036 %}
 13038 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
 13039   match(Set dst (DecodeNKlass src));
 13040   format %{ "decode_heap_klass_not_null $dst,$src" %}
 13041   ins_encode %{
 13042     Register s = $src$$Register;
 13043     Register d = $dst$$Register;
 13044     if (s != d) {
 13045       __ decode_klass_not_null(d, s);
 13046     } else {
 13047       __ decode_klass_not_null(d);
 13049   %}
 13050   ins_pipe( ialu_regL_regL );
 13051 %}
 13053 //FIXME
 13054 instruct tlsLoadP(mRegP dst) %{
 13055   match(Set dst (ThreadLocal));
 13057   ins_cost(0);
 13058   format %{ " get_thread in $dst #@tlsLoadP" %}
 13059   ins_encode %{
 13060     Register dst = $dst$$Register;
 13061 #ifdef OPT_THREAD
 13062     __ move(dst, TREG);
 13063 #else
 13064     __ get_thread(dst);
 13065 #endif
 13066   %}
 13068   ins_pipe( ialu_loadI );
 13069 %}
 13072 instruct checkCastPP( mRegP dst ) %{
 13073   match(Set dst (CheckCastPP dst));
 13075   format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
 13076   ins_encode( /*empty encoding*/ );
 13077   ins_pipe( empty );
 13078 %}
 13080 instruct castPP(mRegP dst)
 13081 %{
 13082   match(Set dst (CastPP dst));
 13084   size(0);
 13085   format %{ "# castPP of $dst" %}
 13086   ins_encode(/* empty encoding */);
 13087   ins_pipe(empty);
 13088 %}
 13090 instruct castII( mRegI dst ) %{
 13091   match(Set dst (CastII dst));
 13092   format %{ "#castII of $dst  empty encoding" %}
 13093   ins_encode( /*empty encoding*/ );
 13094   ins_cost(0);
 13095   ins_pipe( empty );
 13096 %}
 13098 // Return Instruction
 13099 // Remove the return address & jump to it.
 13100 instruct Ret() %{
 13101   match(Return);
 13102   format %{ "RET #@Ret" %}
 13104   ins_encode %{
 13105    __ jr(RA);
 13106    __ nop();
 13107   %}
 13109   ins_pipe( pipe_jump );
 13110 %}
 13112 /*
 13113 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
 13114 instruct jumpXtnd(mRegL switch_val) %{
 13115   match(Jump switch_val);
 13117   ins_cost(350);
 13119   format %{  "load   T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
 13120              "jr     T9\n\t"
 13121              "nop" %}
 13122   ins_encode %{
 13123     Register table_base = $constanttablebase;
 13124     int      con_offset = $constantoffset;
 13125     Register switch_reg = $switch_val$$Register;
 13127     if (UseLoongsonISA) {
 13128        if (Assembler::is_simm(con_offset, 8)) {
 13129          __ gsldx(T9, table_base, switch_reg, con_offset);
 13130        } else if (Assembler::is_simm16(con_offset)) {
 13131          __ daddu(T9, table_base, switch_reg);
 13132          __ ld(T9, T9, con_offset);
 13133        } else {
 13134          __ move(T9, con_offset);
 13135          __ daddu(AT, table_base, switch_reg);
 13136          __ gsldx(T9, AT, T9, 0);
 13138     } else {
 13139        if (Assembler::is_simm16(con_offset)) {
 13140          __ daddu(T9, table_base, switch_reg);
 13141          __ ld(T9, T9, con_offset);
 13142        } else {
 13143          __ move(T9, con_offset);
 13144          __ daddu(AT, table_base, switch_reg);
 13145          __ daddu(AT, T9, AT);
 13146          __ ld(T9, AT, 0);
 13150     __ jr(T9);
 13151     __ nop();
 13153   %}
 13154   ins_pipe(pipe_jump);
 13155 %}
 13156 */
 13159 // Tail Jump; remove the return address; jump to target.
 13160 // TailCall above leaves the return address around.
 13161 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 13162 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 13163 // "restore" before this instruction (in Epilogue), we need to materialize it
 13164 // in %i0.
 13165 //FIXME
 13166 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
 13167   match( TailJump jump_target ex_oop );
 13168   ins_cost(200);
 13169   format %{ "Jmp     $jump_target  ; ex_oop = $ex_oop #@tailjmpInd" %}
 13170   ins_encode %{
 13171     Register target = $jump_target$$Register;
 13173     /* 2012/9/14 Jin: V0, V1 are indicated in:
 13174      *      [stubGenerator_mips.cpp] generate_forward_exception()
 13175      *      [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
 13176      */
 13177     Register oop  = $ex_oop$$Register;
 13178     Register exception_oop = V0;
 13179     Register exception_pc = V1;
 13181     __ move(exception_pc, RA);
 13182     __ move(exception_oop, oop);
 13184     __ jr(target);
 13185     __ nop();
 13186   %}
 13187   ins_pipe( pipe_jump );
 13188 %}
 13190 // ============================================================================
 13191 // Procedure Call/Return Instructions
 13192 // Call Java Static Instruction
 13193 // Note: If this code changes, the corresponding ret_addr_offset() and
 13194 //       compute_padding() functions will have to be adjusted.
 13195 instruct CallStaticJavaDirect(method meth) %{
 13196   match(CallStaticJava);
 13197   effect(USE meth);
 13199   ins_cost(300);
 13200   format %{ "CALL,static #@CallStaticJavaDirect " %}
 13201   ins_encode( Java_Static_Call( meth ) );
 13202   ins_pipe( pipe_slow );
 13203   ins_pc_relative(1);
 13204 %}
 13206 // Call Java Dynamic Instruction
 13207 // Note: If this code changes, the corresponding ret_addr_offset() and
 13208 //       compute_padding() functions will have to be adjusted.
 13209 instruct CallDynamicJavaDirect(method meth) %{
 13210   match(CallDynamicJava);
 13211   effect(USE meth);
 13213   ins_cost(300);
 13214   format %{"MOV IC_Klass, (oop)-1\n\t"
 13215            "CallDynamic @ CallDynamicJavaDirect" %}
 13216   ins_encode( Java_Dynamic_Call( meth ) );
 13217   ins_pipe( pipe_slow );
 13218   ins_pc_relative(1);
 13219 %}
 13221 instruct CallLeafNoFPDirect(method meth) %{
 13222   match(CallLeafNoFP);
 13223   effect(USE meth);
 13225   ins_cost(300);
 13226   format %{ "CALL_LEAF_NOFP,runtime " %}
 13227   ins_encode(Java_To_Runtime(meth));
 13228   ins_pipe( pipe_slow );
 13229   ins_pc_relative(1);
 13230   ins_alignment(16);
 13231 %}
 13233 // Prefetch instructions.
 13235 instruct prefetchrNTA( memory mem ) %{
 13236   match(PrefetchRead mem);
 13237   ins_cost(125);
 13239   format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
 13240   ins_encode %{
 13241     int  base = $mem$$base;
 13242     int  index = $mem$$index;
 13243     int  scale = $mem$$scale;
 13244     int  disp = $mem$$disp;
 13246     if( index != 0 ) {
 13247       if (scale == 0) {
 13248         __ daddu(AT, as_Register(base), as_Register(index));
 13249       } else {
 13250         __ dsll(AT, as_Register(index), scale);
 13251         __ daddu(AT, as_Register(base), AT);
 13253     } else {
 13254       __ move(AT, as_Register(base));
 13256     if( Assembler::is_simm16(disp) ) {
 13257       __ daddiu(AT, as_Register(base), disp);
 13258       __ daddiu(AT, AT, disp);
 13259     } else {
 13260       __ move(T9, disp);
 13261       __ daddu(AT, as_Register(base), T9);
 13263     __ pref(0, AT, 0); //hint: 0:load
 13264   %}
 13265   ins_pipe(pipe_slow);
 13266 %}
 13268 instruct prefetchwNTA( memory mem ) %{
 13269   match(PrefetchWrite mem);
 13270   ins_cost(125);
 13271   format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
 13272   ins_encode %{
 13273     int  base = $mem$$base;
 13274     int  index = $mem$$index;
 13275     int  scale = $mem$$scale;
 13276     int  disp = $mem$$disp;
 13278     if( index != 0 ) {
 13279       if (scale == 0) {
 13280         __ daddu(AT, as_Register(base), as_Register(index));
 13281       } else {
 13282         __ dsll(AT, as_Register(index), scale);
 13283         __ daddu(AT, as_Register(base), AT);
 13285     } else {
 13286       __ move(AT, as_Register(base));
 13288     if( Assembler::is_simm16(disp) ) {
 13289       __ daddiu(AT, as_Register(base), disp);
 13290       __ daddiu(AT, AT, disp);
 13291     } else {
 13292       __ move(T9, disp);
 13293       __ daddu(AT, as_Register(base), T9);
 13295      __ pref(1, AT, 0); //hint: 1:store
 13296   %}
 13297   ins_pipe(pipe_slow);
 13298 %}
 13300 // Prefetch instructions for allocation.
 13302 instruct prefetchAllocNTA( memory mem ) %{
 13303   match(PrefetchAllocation mem);
 13304   ins_cost(125);
 13305   format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
 13306   ins_encode %{
 13307     int  base = $mem$$base;
 13308     int  index = $mem$$index;
 13309     int  scale = $mem$$scale;
 13310     int  disp = $mem$$disp;
 13312     Register dst = R0;
 13314     if( index != 0 ) {
 13315       if( Assembler::is_simm16(disp) ) {
 13316         if( UseLoongsonISA ) {
 13317           if (scale == 0) {
 13318             __ gslbx(dst, as_Register(base), as_Register(index), disp);
 13319           } else {
 13320             __ dsll(AT, as_Register(index), scale);
 13321             __ gslbx(dst, as_Register(base), AT, disp);
 13323         } else {
 13324           if (scale == 0) {
 13325             __ addu(AT, as_Register(base), as_Register(index));
 13326           } else {
 13327             __ dsll(AT, as_Register(index), scale);
 13328             __ addu(AT, as_Register(base), AT);
 13330           __ lb(dst, AT, disp);
 13332       } else {
 13333         if (scale == 0) {
 13334           __ addu(AT, as_Register(base), as_Register(index));
 13335         } else {
 13336           __ dsll(AT, as_Register(index), scale);
 13337           __ addu(AT, as_Register(base), AT);
 13339         __ move(T9, disp);
 13340         if( UseLoongsonISA ) {
 13341           __ gslbx(dst, AT, T9, 0);
 13342         } else {
 13343           __ addu(AT, AT, T9);
 13344           __ lb(dst, AT, 0);
 13347     } else {
 13348       if( Assembler::is_simm16(disp) ) {
 13349         __ lb(dst, as_Register(base), disp);
 13350       } else {
 13351         __ move(T9, disp);
 13352         if( UseLoongsonISA ) {
 13353           __ gslbx(dst, as_Register(base), T9, 0);
 13354         } else {
 13355           __ addu(AT, as_Register(base), T9);
 13356           __ lb(dst, AT, 0);
 13360   %}
 13361   ins_pipe(pipe_slow);
 13362 %}
 13365 // Call runtime without safepoint
 13366 instruct CallLeafDirect(method meth) %{
 13367   match(CallLeaf);
 13368   effect(USE meth);
 13370   ins_cost(300);
 13371   format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
 13372   ins_encode(Java_To_Runtime(meth));
 13373   ins_pipe( pipe_slow );
 13374   ins_pc_relative(1);
 13375   ins_alignment(16);
 13376 %}
 13378 // Load Char (16bit unsigned)
 13379 instruct loadUS(mRegI dst, memory mem) %{
 13380   match(Set dst (LoadUS mem));
 13382   ins_cost(125);
 13383   format %{ "loadUS  $dst,$mem @ loadC" %}
 13384   ins_encode(load_C_enc(dst, mem));
 13385   ins_pipe( ialu_loadI );
 13386 %}
 13388 instruct loadUS_convI2L(mRegL dst, memory mem) %{
 13389   match(Set dst (ConvI2L (LoadUS mem)));
 13391   ins_cost(125);
 13392   format %{ "loadUS  $dst,$mem @ loadUS_convI2L" %}
 13393   ins_encode(load_C_enc(dst, mem));
 13394   ins_pipe( ialu_loadI );
 13395 %}
 13397 // Store Char (16bit unsigned)
 13398 instruct storeC(memory mem, mRegI src) %{
 13399   match(Set mem (StoreC mem src));
 13401   ins_cost(125);
 13402   format %{ "storeC  $src, $mem @ storeC" %}
 13403   ins_encode(store_C_reg_enc(mem, src));
 13404   ins_pipe( ialu_loadI );
 13405 %}
 13407 instruct storeC0(memory mem, immI0 zero) %{
 13408   match(Set mem (StoreC mem zero));
 13410   ins_cost(125);
 13411   format %{ "storeC  $zero, $mem @ storeC0" %}
 13412   ins_encode(store_C0_enc(mem));
 13413   ins_pipe( ialu_loadI );
 13414 %}
 13417 instruct loadConF0(regF dst, immF0 zero) %{
 13418   match(Set dst zero);
 13419   ins_cost(100);
 13421   format %{ "mov  $dst, zero @ loadConF0\n"%}
 13422   ins_encode %{
 13423     FloatRegister dst = $dst$$FloatRegister;
 13425     __ mtc1(R0, dst);
 13426   %}
 13427   ins_pipe( fpu_loadF );
 13428 %}
 13431 instruct loadConF(regF dst, immF src) %{
 13432   match(Set dst src);
 13433   ins_cost(125);
 13435   format %{ "lwc1  $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
 13436   ins_encode %{
 13437     int con_offset = $constantoffset($src);
 13439     if (Assembler::is_simm16(con_offset)) {
 13440       __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
 13441     } else {
 13442       __ set64(AT, con_offset);
 13443       if (UseLoongsonISA) {
 13444         __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 13445       } else {
 13446         __ daddu(AT, $constanttablebase, AT);
 13447         __ lwc1($dst$$FloatRegister, AT, 0);
 13450   %}
 13451   ins_pipe( fpu_loadF );
 13452 %}
 13455 instruct loadConD0(regD dst, immD0 zero) %{
 13456   match(Set dst zero);
 13457   ins_cost(100);
 13459   format %{ "mov  $dst, zero @ loadConD0"%}
 13460   ins_encode %{
 13461     FloatRegister dst = as_FloatRegister($dst$$reg);
 13463     __ dmtc1(R0, dst);
 13464   %}
 13465   ins_pipe( fpu_loadF );
 13466 %}
 13468 instruct loadConD(regD dst, immD src) %{
 13469   match(Set dst src);
 13470   ins_cost(125);
 13472   format %{ "ldc1  $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
 13473   ins_encode %{
 13474     int con_offset = $constantoffset($src);
 13476     if (Assembler::is_simm16(con_offset)) {
 13477       __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
 13478     } else {
 13479       __ set64(AT, con_offset);
 13480       if (UseLoongsonISA) {
 13481         __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 13482       } else {
 13483         __ daddu(AT, $constanttablebase, AT);
 13484         __ ldc1($dst$$FloatRegister, AT, 0);
 13487   %}
 13488   ins_pipe( fpu_loadF );
 13489 %}
 13491 // Store register Float value (it is faster than store from FPU register)
 13492 instruct storeF_reg( memory mem, regF src) %{
 13493   match(Set mem (StoreF mem src));
 13495   ins_cost(50);
 13496   format %{ "store   $mem, $src\t# store float @ storeF_reg" %}
 13497   ins_encode(store_F_reg_enc(mem, src));
 13498   ins_pipe( fpu_storeF );
 13499 %}
 13501 instruct storeF_imm0( memory mem, immF0 zero) %{
 13502   match(Set mem (StoreF mem zero));
 13504   ins_cost(40);
 13505   format %{ "store   $mem, zero\t# store float @ storeF_imm0" %}
 13506   ins_encode %{
 13507     int      base = $mem$$base;
 13508     int     index = $mem$$index;
 13509     int     scale = $mem$$scale;
 13510     int      disp = $mem$$disp;
 13512     if( index != 0 ) {
 13513       if ( UseLoongsonISA ) {
 13514         if ( Assembler::is_simm(disp, 8) ) {
 13515           if ( scale == 0 ) {
 13516             __ gsswx(R0, as_Register(base), as_Register(index), disp);
 13517           } else {
 13518             __ dsll(T9, as_Register(index), scale);
 13519             __ gsswx(R0, as_Register(base), T9, disp);
 13521         } else if ( Assembler::is_simm16(disp) ) {
 13522           if ( scale == 0 ) {
 13523             __ daddu(AT, as_Register(base), as_Register(index));
 13524           } else {
 13525             __ dsll(T9, as_Register(index), scale);
 13526             __ daddu(AT, as_Register(base), T9);
 13528           __ sw(R0, AT, disp);
 13529         } else {
 13530           if ( scale == 0 ) {
 13531             __ move(T9, disp);
 13532             __ daddu(AT, as_Register(index), T9);
 13533             __ gsswx(R0, as_Register(base), AT, 0);
 13534           } else {
 13535             __ dsll(T9, as_Register(index), scale);
 13536             __ move(AT, disp);
 13537             __ daddu(AT, AT, T9);
 13538             __ gsswx(R0, as_Register(base), AT, 0);
 13541       } else { //not use loongson isa
 13542         if(scale != 0) {
 13543           __ dsll(T9, as_Register(index), scale);
 13544           __ daddu(AT, as_Register(base), T9);
 13545         } else {
 13546           __ daddu(AT, as_Register(base), as_Register(index));
 13548         if( Assembler::is_simm16(disp) ) {
 13549           __ sw(R0, AT, disp);
 13550         } else {
 13551           __ move(T9, disp);
 13552           __ daddu(AT, AT, T9);
 13553           __ sw(R0, AT, 0);
 13556     } else { //index is 0
 13557       if ( UseLoongsonISA ) {
 13558         if ( Assembler::is_simm16(disp) ) {
 13559           __ sw(R0, as_Register(base), disp);
 13560         } else {
 13561           __ move(T9, disp);
 13562           __ gsswx(R0, as_Register(base), T9, 0);
 13564       } else {
 13565         if( Assembler::is_simm16(disp) ) {
 13566           __ sw(R0, as_Register(base), disp);
 13567         } else {
 13568           __ move(T9, disp);
 13569           __ daddu(AT, as_Register(base), T9);
 13570           __ sw(R0, AT, 0);
 13574   %}
 13575   ins_pipe( ialu_storeI );
 13576 %}
 13578 // Load Double
 13579 instruct loadD(regD dst, memory mem) %{
 13580   match(Set dst (LoadD mem));
 13582   ins_cost(150);
 13583   format %{ "loadD   $dst, $mem #@loadD" %}
 13584   ins_encode(load_D_enc(dst, mem));
 13585   ins_pipe( ialu_loadI );
 13586 %}
 13588 // Load Double - UNaligned
 13589 instruct loadD_unaligned(regD dst, memory mem ) %{
 13590   match(Set dst (LoadD_unaligned mem));
 13591   ins_cost(250);
 13592   // FIXME: Jin: Need more effective ldl/ldr
 13593   format %{ "loadD_unaligned   $dst, $mem #@loadD_unaligned" %}
 13594   ins_encode(load_D_enc(dst, mem));
 13595   ins_pipe( ialu_loadI );
 13596 %}
 13598 instruct storeD_reg( memory mem, regD src) %{
 13599   match(Set mem (StoreD mem src));
 13601   ins_cost(50);
 13602   format %{ "store   $mem, $src\t# store float @ storeD_reg" %}
 13603   ins_encode(store_D_reg_enc(mem, src));
 13604   ins_pipe( fpu_storeF );
 13605 %}
 13607 instruct storeD_imm0( memory mem, immD0 zero) %{
 13608   match(Set mem (StoreD mem zero));
 13610   ins_cost(40);
 13611   format %{ "store   $mem, zero\t# store float @ storeD_imm0" %}
 13612   ins_encode %{
 13613     int      base = $mem$$base;
 13614     int     index = $mem$$index;
 13615     int     scale = $mem$$scale;
 13616     int      disp = $mem$$disp;
 13618     __ mtc1(R0, F30);
 13619     __ cvt_d_w(F30, F30);
 13621     if( index != 0 ) {
 13622     if ( UseLoongsonISA ) {
 13623       if ( Assembler::is_simm(disp, 8) ) {
 13624         if (scale == 0) {
 13625           __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
 13626         } else {
 13627           __ dsll(T9, as_Register(index), scale);
 13628           __ gssdxc1(F30, as_Register(base), T9, disp);
 13630       } else if ( Assembler::is_simm16(disp) ) {
 13631         if (scale == 0) {
 13632           __ daddu(AT, as_Register(base), as_Register(index));
 13633           __ sdc1(F30, AT, disp);
 13634         } else {
 13635           __ dsll(T9, as_Register(index), scale);
 13636           __ daddu(AT, as_Register(base), T9);
 13637           __ sdc1(F30, AT, disp);
 13639       } else {
 13640         if (scale == 0) {
 13641           __ move(T9, disp);
 13642           __ daddu(AT, as_Register(index), T9);
 13643           __ gssdxc1(F30, as_Register(base), AT, 0);
 13644         } else {
 13645           __ move(T9, disp);
 13646           __ dsll(AT, as_Register(index), scale);
 13647           __ daddu(AT, AT, T9);
 13648           __ gssdxc1(F30, as_Register(base), AT, 0);
 13651     } else { // not use loongson isa
 13652         if(scale != 0) {
 13653            __ dsll(T9, as_Register(index), scale);
 13654            __ daddu(AT, as_Register(base), T9);
 13655         } else {
 13656            __ daddu(AT, as_Register(base), as_Register(index));
 13658        if( Assembler::is_simm16(disp) ) {
 13659           __ sdc1(F30, AT, disp);
 13660        } else {
 13661           __ move(T9, disp);
 13662           __ daddu(AT, AT, T9);
 13663           __ sdc1(F30, AT, 0);
 13666     } else {// index is 0
 13667     if ( UseLoongsonISA ) {
 13668       if ( Assembler::is_simm16(disp) ) {
 13669         __ sdc1(F30, as_Register(base), disp);
 13670       } else {
 13671         __ move(T9, disp);
 13672         __ gssdxc1(F30, as_Register(base), T9, 0);
 13674     } else {
 13675        if( Assembler::is_simm16(disp) ) {
 13676           __ sdc1(F30, as_Register(base), disp);
 13677        } else {
 13678           __ move(T9, disp);
 13679           __ daddu(AT, as_Register(base), T9);
 13680           __ sdc1(F30, AT, 0);
 13684   %}
 13685   ins_pipe( ialu_storeI );
 13686 %}
 13688 instruct loadSSI(mRegI dst, stackSlotI src)
 13689 %{
 13690   match(Set dst src);
 13692   ins_cost(125);
 13693   format %{ "lw    $dst, $src\t# int stk @ loadSSI" %}
 13694   ins_encode %{
 13695     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
 13696     __ lw($dst$$Register, SP, $src$$disp);
 13697   %}
 13698   ins_pipe(ialu_loadI);
 13699 %}
 13701 instruct storeSSI(stackSlotI dst, mRegI src)
 13702 %{
 13703   match(Set dst src);
 13705   ins_cost(100);
 13706   format %{ "sw    $dst, $src\t# int stk @ storeSSI" %}
 13707   ins_encode %{
 13708     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
 13709     __ sw($src$$Register, SP, $dst$$disp);
 13710   %}
 13711   ins_pipe(ialu_storeI);
 13712 %}
 13714 instruct loadSSL(mRegL dst, stackSlotL src)
 13715 %{
 13716   match(Set dst src);
 13718   ins_cost(125);
 13719   format %{ "ld    $dst, $src\t# long stk @ loadSSL" %}
 13720   ins_encode %{
 13721     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
 13722     __ ld($dst$$Register, SP, $src$$disp);
 13723   %}
 13724   ins_pipe(ialu_loadI);
 13725 %}
 13727 instruct storeSSL(stackSlotL dst, mRegL src)
 13728 %{
 13729   match(Set dst src);
 13731   ins_cost(100);
 13732   format %{ "sd    $dst, $src\t# long stk @ storeSSL" %}
 13733   ins_encode %{
 13734     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
 13735     __ sd($src$$Register, SP, $dst$$disp);
 13736   %}
 13737   ins_pipe(ialu_storeI);
 13738 %}
 13740 instruct loadSSP(mRegP dst, stackSlotP src)
 13741 %{
 13742   match(Set dst src);
 13744   ins_cost(125);
 13745   format %{ "ld    $dst, $src\t# ptr stk @ loadSSP" %}
 13746   ins_encode %{
 13747     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
 13748     __ ld($dst$$Register, SP, $src$$disp);
 13749   %}
 13750   ins_pipe(ialu_loadI);
 13751 %}
 13753 instruct storeSSP(stackSlotP dst, mRegP src)
 13754 %{
 13755   match(Set dst src);
 13757   ins_cost(100);
 13758   format %{ "sd    $dst, $src\t# ptr stk @ storeSSP" %}
 13759   ins_encode %{
 13760     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
 13761     __ sd($src$$Register, SP, $dst$$disp);
 13762   %}
 13763   ins_pipe(ialu_storeI);
 13764 %}
 13766 instruct loadSSF(regF dst, stackSlotF src)
 13767 %{
 13768   match(Set dst src);
 13770   ins_cost(125);
 13771   format %{ "lwc1   $dst, $src\t# float stk @ loadSSF" %}
 13772   ins_encode %{
 13773     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
 13774     __ lwc1($dst$$FloatRegister, SP, $src$$disp);
 13775   %}
 13776   ins_pipe(ialu_loadI);
 13777 %}
 13779 instruct storeSSF(stackSlotF dst, regF src)
 13780 %{
 13781   match(Set dst src);
 13783   ins_cost(100);
 13784   format %{ "swc1    $dst, $src\t# float stk @ storeSSF" %}
 13785   ins_encode %{
 13786     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
 13787     __ swc1($src$$FloatRegister, SP, $dst$$disp);
 13788   %}
 13789   ins_pipe(fpu_storeF);
 13790 %}
 13792 // Use the same format since predicate() can not be used here.
 13793 instruct loadSSD(regD dst, stackSlotD src)
 13794 %{
 13795   match(Set dst src);
 13797   ins_cost(125);
 13798   format %{ "ldc1   $dst, $src\t# double stk @ loadSSD" %}
 13799   ins_encode %{
 13800     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
 13801     __ ldc1($dst$$FloatRegister, SP, $src$$disp);
 13802   %}
 13803   ins_pipe(ialu_loadI);
 13804 %}
 13806 instruct storeSSD(stackSlotD dst, regD src)
 13807 %{
 13808   match(Set dst src);
 13810   ins_cost(100);
 13811   format %{ "sdc1    $dst, $src\t# double stk @ storeSSD" %}
 13812   ins_encode %{
 13813     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
 13814     __ sdc1($src$$FloatRegister, SP, $dst$$disp);
 13815   %}
 13816   ins_pipe(fpu_storeF);
 13817 %}
 13819 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
 13820   match( Set cr (FastLock object box) );
 13821   effect( TEMP tmp, TEMP scr, USE_KILL box );
 13822   ins_cost(300);
 13823   format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
 13824   ins_encode %{
 13825     __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
 13826   %}
 13828   ins_pipe( pipe_slow );
 13829   ins_pc_relative(1);
 13830 %}
 13832 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
 13833   match( Set cr (FastUnlock object box) );
 13834   effect( TEMP tmp, USE_KILL box );
 13835   ins_cost(300);
 13836   format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
 13837   ins_encode %{
 13838     __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
 13839   %}
 13841   ins_pipe( pipe_slow );
 13842   ins_pc_relative(1);
 13843 %}
 13845 // Store CMS card-mark Immediate
 13846 instruct storeImmCM(memory mem, immI8 src) %{
 13847   match(Set mem (StoreCM mem src));
 13849   ins_cost(150);
 13850   format %{ "MOV8   $mem,$src\t! CMS card-mark imm0" %}
 13851 //  opcode(0xC6);
 13852   ins_encode(store_B_immI_enc_sync(mem, src));
 13853   ins_pipe( ialu_storeI );
 13854 %}
 13856 // Die now
 13857 instruct ShouldNotReachHere( )
 13858 %{
 13859   match(Halt);
 13860   ins_cost(300);
 13862   // Use the following format syntax
 13863   format %{ "ILLTRAP   ;#@ShouldNotReachHere" %}
 13864   ins_encode %{
 13865     // Here we should emit illtrap !
 13867     __ stop("in ShoudNotReachHere");
 13869   %}
 13870   ins_pipe( pipe_jump );
 13871 %}
 13873 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
 13874 %{
 13875   predicate(Universe::narrow_oop_shift() == 0);
 13876   match(Set dst mem);
 13878   ins_cost(110);
 13879   format %{ "leaq    $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
 13880   ins_encode %{
 13881     Register  dst  = $dst$$Register;
 13882     Register  base = as_Register($mem$$base);
 13883     int       disp = $mem$$disp;
 13885     __ daddiu(dst, base, disp);
 13886   %}
 13887   ins_pipe( ialu_regI_imm16 );
 13888 %}
 13890 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
 13891 %{
 13892   match(Set dst mem);
 13894   ins_cost(110);
 13895   format %{ "leaq    $dst, $mem\t# @ PosIdxScaleOff8" %}
 13896   ins_encode %{
 13897     Register  dst   = $dst$$Register;
 13898     Register  base  = as_Register($mem$$base);
 13899     Register  index = as_Register($mem$$index);
 13900     int       scale = $mem$$scale;
 13901     int       disp  = $mem$$disp;
 13903     if (scale == 0) {
 13904       __ daddu(AT, base, index);
 13905       __ daddiu(dst, AT, disp);
 13906     } else {
 13907       __ dsll(AT, index, scale);
 13908       __ daddu(AT, base, AT);
 13909       __ daddiu(dst, AT, disp);
 13911  %}
 13913   ins_pipe( ialu_regI_imm16 );
 13914 %}
 13916 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
 13917 %{
 13918   match(Set dst mem);
 13920   ins_cost(110);
 13921   format %{ "leaq    $dst, $mem\t# @ leaPIdxScale" %}
 13922   ins_encode %{
 13923     Register  dst   = $dst$$Register;
 13924     Register  base  = as_Register($mem$$base);
 13925     Register  index = as_Register($mem$$index);
 13926     int       scale = $mem$$scale;
 13928     if (scale == 0) {
 13929        __ daddu(dst, base, index);
 13930     } else {
 13931        __ dsll(AT, index, scale);
 13932        __ daddu(dst, base, AT);
 13934  %}
 13936   ins_pipe( ialu_regI_imm16 );
 13937 %}
 13940 // ============================================================================
 13941 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 13942 // array for an instance of the superklass.  Set a hidden internal cache on a
 13943 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 13944 // NZ for a miss or zero for a hit.  The encoding ALSO sets flags.
 13945 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
 13946   match(Set result (PartialSubtypeCheck sub super));
 13947   effect(KILL tmp);
 13948   ins_cost(1100);  // slightly larger than the next version
 13949   format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
 13951   ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
 13952   ins_pipe( pipe_slow );
 13953 %}
 13956 // Conditional-store of an int value.
 13957 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
 13958 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
 13959   match(Set cr (StoreIConditional mem (Binary oldval newval)));
 13960 //  effect(KILL oldval);
 13961   format %{ "CMPXCHG  $newval, $mem, $oldval \t# @storeIConditional" %}
 13963   ins_encode %{
 13964     Register oldval = $oldval$$Register;
 13965     Register newval = $newval$$Register;
 13966     Address  addr(as_Register($mem$$base), $mem$$disp);
 13967     Label    again, failure;
 13969     int     index = $mem$$index;
 13970     int     scale = $mem$$scale;
 13971     int      disp = $mem$$disp;
 13973     guarantee(Assembler::is_simm16(disp), "");
 13975     if( index != 0 ) {
 13976       __ stop("in storeIConditional: index != 0");
 13977     } else {
 13978       __ bind(again);
 13979       if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
 13980       __ ll(AT, addr);
 13981       __ bne(AT, oldval, failure);
 13982       __ delayed()->addu(AT, R0, R0);
 13984       __ addu(AT, newval, R0);
 13985       __ sc(AT, addr);
 13986       __ beq(AT, R0, again);
 13987       __ delayed()->addiu(AT, R0, 0xFF);
 13988       __ bind(failure);
 13989       __ sync();
 13991 %}
 13993   ins_pipe( long_memory_op );
 13994 %}
 13996 // Conditional-store of a long value.
 13997 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
 13998 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
 13999 %{
 14000   match(Set cr (StoreLConditional mem (Binary oldval newval)));
 14001   effect(KILL oldval);
 14003   format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
 14004   ins_encode%{
 14005     Register oldval = $oldval$$Register;
 14006     Register newval = $newval$$Register;
 14007     Address addr((Register)$mem$$base, $mem$$disp);
 14009     int     index = $mem$$index;
 14010     int     scale = $mem$$scale;
 14011     int      disp = $mem$$disp;
 14013     guarantee(Assembler::is_simm16(disp), "");
 14015     if( index != 0 ) {
 14016       __ stop("in storeIConditional: index != 0");
 14017     } else {
 14018       __ cmpxchg(newval, addr, oldval);
 14020   %}
 14021   ins_pipe( long_memory_op );
 14022 %}
 14025 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
 14026   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
 14027   effect(KILL oldval);
 14028 //  match(CompareAndSwapI mem_ptr (Binary oldval newval));
 14029   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
 14030             "MOV    $res, 1 @ compareAndSwapI\n\t"
 14031             "BNE    AT, R0 @ compareAndSwapI\n\t"
 14032             "MOV    $res, 0 @ compareAndSwapI\n"
 14033           "L:" %}
 14034   ins_encode %{
 14035     Register newval = $newval$$Register;
 14036     Register oldval = $oldval$$Register;
 14037     Register res    = $res$$Register;
 14038     Address  addr($mem_ptr$$Register, 0);
 14039     Label L;
 14041     __ cmpxchg32(newval, addr, oldval);
 14042     __ move(res, AT);
 14043   %}
 14044   ins_pipe( long_memory_op );
 14045 %}
 14047 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
 14048   predicate(VM_Version::supports_cx8());
 14049   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
 14050   effect(KILL oldval);
 14051   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
 14052             "MOV    $res, 1 @ compareAndSwapI\n\t"
 14053             "BNE    AT, R0 @ compareAndSwapI\n\t"
 14054             "MOV    $res, 0 @ compareAndSwapI\n"
 14055           "L:" %}
 14056   ins_encode %{
 14057     Register newval = $newval$$Register;
 14058     Register oldval = $oldval$$Register;
 14059     Register res    = $res$$Register;
 14060     Address  addr($mem_ptr$$Register, 0);
 14061     Label L;
 14063     __ cmpxchg(newval, addr, oldval);
 14064     __ move(res, AT);
 14065   %}
 14066   ins_pipe( long_memory_op );
 14067 %}
 14069 //FIXME:
 14070 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
 14071   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
 14072   effect(KILL oldval);
 14073   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
 14074             "MOV    $res, AT @ compareAndSwapP\n\t"
 14075           "L:" %}
 14076   ins_encode %{
 14077     Register newval = $newval$$Register;
 14078     Register oldval = $oldval$$Register;
 14079     Register res    = $res$$Register;
 14080     Address  addr($mem_ptr$$Register, 0);
 14081     Label L;
 14083     __ cmpxchg(newval, addr, oldval);
 14084     __ move(res, AT);
 14085   %}
 14086   ins_pipe( long_memory_op );
 14087 %}
 14089 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
 14090   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
 14091   effect(KILL oldval);
 14092   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
 14093             "MOV    $res, AT @ compareAndSwapN\n\t"
 14094           "L:" %}
 14095   ins_encode %{
 14096     Register newval = $newval$$Register;
 14097     Register oldval = $oldval$$Register;
 14098     Register res    = $res$$Register;
 14099     Address  addr($mem_ptr$$Register, 0);
 14100     Label L;
 14102     /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
 14103      *      Thus, we should extend oldval's sign for correct comparision.
 14104      */
 14105     __ sll(oldval, oldval, 0);
 14107     __ cmpxchg32(newval, addr, oldval);
 14108     __ move(res, AT);
 14109   %}
 14110   ins_pipe( long_memory_op );
 14111 %}
 14113 //----------Max and Min--------------------------------------------------------
 14114 // Min Instructions
 14115 ////
 14116 //   *** Min and Max using the conditional move are slower than the
 14117 //   *** branch version on a Pentium III.
 14118 // // Conditional move for min
 14119 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 14120 //  effect( USE_DEF op2, USE op1, USE cr );
 14121 //  format %{ "CMOVlt $op2,$op1\t! min" %}
 14122 //  opcode(0x4C,0x0F);
 14123 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 14124 //  ins_pipe( pipe_cmov_reg );
 14125 //%}
 14126 //
 14127 //// Min Register with Register (P6 version)
 14128 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
 14129 //  predicate(VM_Version::supports_cmov() );
 14130 //  match(Set op2 (MinI op1 op2));
 14131 //  ins_cost(200);
 14132 //  expand %{
 14133 //    eFlagsReg cr;
 14134 //    compI_eReg(cr,op1,op2);
 14135 //    cmovI_reg_lt(op2,op1,cr);
 14136 //  %}
 14137 //%}
 14139 // Min Register with Register (generic version)
 14140 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
 14141   match(Set dst (MinI dst src));
 14142   //effect(KILL flags);
 14143   ins_cost(80);
 14145   format %{ "MIN    $dst, $src @minI_Reg_Reg" %}
 14146   ins_encode %{
 14147     Register dst   = $dst$$Register;
 14148     Register src   = $src$$Register;
 14150     __ slt(AT, src, dst);
 14151     __ movn(dst, src, AT);
 14153   %}
 14155   ins_pipe( pipe_slow );
 14156 %}
 14158 // Max Register with Register
 14159 //   *** Min and Max using the conditional move are slower than the
 14160 //   *** branch version on a Pentium III.
 14161 // // Conditional move for max
 14162 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 14163 //  effect( USE_DEF op2, USE op1, USE cr );
 14164 //  format %{ "CMOVgt $op2,$op1\t! max" %}
 14165 //  opcode(0x4F,0x0F);
 14166 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 14167 //  ins_pipe( pipe_cmov_reg );
 14168 //%}
 14169 //
 14170 // // Max Register with Register (P6 version)
 14171 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
 14172 //  predicate(VM_Version::supports_cmov() );
 14173 //  match(Set op2 (MaxI op1 op2));
 14174 //  ins_cost(200);
 14175 //  expand %{
 14176 //    eFlagsReg cr;
 14177 //    compI_eReg(cr,op1,op2);
 14178 //    cmovI_reg_gt(op2,op1,cr);
 14179 //  %}
 14180 //%}
 14182 // Max Register with Register (generic version)
 14183 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
 14184   match(Set dst (MaxI dst src));
 14185   ins_cost(80);
 14187   format %{ "MAX    $dst, $src @maxI_Reg_Reg" %}
 14189   ins_encode %{
 14190     Register dst   = $dst$$Register;
 14191     Register src   = $src$$Register;
 14193     __ slt(AT, dst, src);
 14194     __ movn(dst, src, AT);
 14196   %}
 14198   ins_pipe( pipe_slow );
 14199 %}
 14201 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
 14202   match(Set dst (MaxI dst zero));
 14203   ins_cost(50);
 14205   format %{ "MAX    $dst, 0 @maxI_Reg_zero" %}
 14207   ins_encode %{
 14208     Register dst   = $dst$$Register;
 14210     __ slt(AT, dst, R0);
 14211     __ movn(dst, R0, AT);
 14213   %}
 14215   ins_pipe( pipe_slow );
 14216 %}
 14218 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
 14219 %{
 14220   match(Set dst (AndL src mask));
 14222   format %{ "movl    $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
 14223   ins_encode %{
 14224     Register dst = $dst$$Register;
 14225     Register src = $src$$Register;
 14227     __ dext(dst, src, 0, 32);
 14228   %}
 14229   ins_pipe(ialu_regI_regI);
 14230 %}
 14232 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
 14233 %{
 14234   match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
 14236   format %{ "combine_i2l    $dst, $src2(H), $src1(L) @ combine_i2l" %}
 14237   ins_encode %{
 14238     Register dst  = $dst$$Register;
 14239     Register src1 = $src1$$Register;
 14240     Register src2 = $src2$$Register;
 14242     if (src1 == dst) {
 14243        __ dinsu(dst, src2, 32, 32);
 14244     } else if (src2 == dst) {
 14245        __ dsll32(dst, dst, 0);
 14246        __ dins(dst, src1, 0, 32);
 14247     } else {
 14248        __ dext(dst, src1, 0, 32);
 14249        __ dinsu(dst, src2, 32, 32);
 14251   %}
 14252   ins_pipe(ialu_regI_regI);
 14253 %}
 14255 // Zero-extend convert int to long
 14256 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
 14257 %{
 14258   match(Set dst (AndL (ConvI2L src) mask));
 14260   format %{ "movl    $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
 14261   ins_encode %{
 14262     Register dst = $dst$$Register;
 14263     Register src = $src$$Register;
 14265     __ dext(dst, src, 0, 32);
 14266   %}
 14267   ins_pipe(ialu_regI_regI);
 14268 %}
 14270 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
 14271 %{
 14272   match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
 14274   format %{ "movl    $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
 14275   ins_encode %{
 14276     Register dst = $dst$$Register;
 14277     Register src = $src$$Register;
 14279     __ dext(dst, src, 0, 32);
 14280   %}
 14281   ins_pipe(ialu_regI_regI);
 14282 %}
 14284 // Match loading integer and casting it to unsigned int in long register.
 14285 // LoadI + ConvI2L + AndL 0xffffffff.
 14286 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
 14287   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 14289   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
 14290   ins_encode (load_N_enc(dst, mem));
 14291   ins_pipe(ialu_loadI);
 14292 %}
 14294 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
 14295   match(Set dst (AndL mask (ConvI2L (LoadI mem))));
 14297   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
 14298   ins_encode (load_N_enc(dst, mem));
 14299   ins_pipe(ialu_loadI);
 14300 %}
 14303 // ============================================================================
 14304 // Safepoint Instruction
 14305 instruct safePoint_poll_reg(mRegP poll) %{
 14306   match(SafePoint poll);
 14307   predicate(false);
 14308   effect(USE poll);
 14310   ins_cost(125);
 14311   format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
 14313   ins_encode %{
 14314     Register poll_reg = $poll$$Register;
 14316     __ block_comment("Safepoint:");
 14317     __ relocate(relocInfo::poll_type);
 14318     __ lw(AT, poll_reg, 0);
 14319   %}
 14321   ins_pipe( ialu_storeI );
 14322 %}
 14324 instruct safePoint_poll() %{
 14325   match(SafePoint);
 14327   ins_cost(105);
 14328   format %{ "poll for GC @ safePoint_poll" %}
 14330   ins_encode %{
 14331     __ block_comment("Safepoint:");
 14332     __ set64(T9, (long)os::get_polling_page());
 14333     __ relocate(relocInfo::poll_type);
 14334     __ lw(AT, T9, 0);
 14335   %}
 14337   ins_pipe( ialu_storeI );
 14338 %}
 14340 //----------Arithmetic Conversion Instructions---------------------------------
 14342 instruct roundFloat_nop(regF dst)
 14343 %{
 14344   match(Set dst (RoundFloat dst));
 14346   ins_cost(0);
 14347   ins_encode();
 14348   ins_pipe(empty);
 14349 %}
 14351 instruct roundDouble_nop(regD dst)
 14352 %{
 14353   match(Set dst (RoundDouble dst));
 14355   ins_cost(0);
 14356   ins_encode();
 14357   ins_pipe(empty);
 14358 %}
 14360 //---------- Zeros Count Instructions ------------------------------------------
 14361 // CountLeadingZerosINode CountTrailingZerosINode
 14362 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
 14363   predicate(UseCountLeadingZerosInstruction);
 14364   match(Set dst (CountLeadingZerosI src));
 14366   format %{ "clz  $dst, $src\t# count leading zeros (int)" %}
 14367   ins_encode %{
 14368     __ clz($dst$$Register, $src$$Register);
 14369   %}
 14370   ins_pipe( ialu_regL_regL );
 14371 %}
 14373 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
 14374   predicate(UseCountLeadingZerosInstruction);
 14375   match(Set dst (CountLeadingZerosL src));
 14377   format %{ "dclz  $dst, $src\t# count leading zeros (long)" %}
 14378   ins_encode %{
 14379     __ dclz($dst$$Register, $src$$Register);
 14380   %}
 14381   ins_pipe( ialu_regL_regL );
 14382 %}
 14384 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
 14385   predicate(UseCountTrailingZerosInstruction);
 14386   match(Set dst (CountTrailingZerosI src));
 14388   format %{ "ctz    $dst, $src\t# count trailing zeros (int)" %}
 14389   ins_encode %{
 14390     // ctz and dctz is gs instructions.
 14391     __ ctz($dst$$Register, $src$$Register);
 14392   %}
 14393   ins_pipe( ialu_regL_regL );
 14394 %}
 14396 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
 14397   predicate(UseCountTrailingZerosInstruction);
 14398   match(Set dst (CountTrailingZerosL src));
 14400   format %{ "dcto    $dst, $src\t# count trailing zeros (long)" %}
 14401   ins_encode %{
 14402     __ dctz($dst$$Register, $src$$Register);
 14403   %}
 14404   ins_pipe( ialu_regL_regL );
 14405 %}
 14407 // ====================VECTOR INSTRUCTIONS=====================================
 14409 // Load vectors (8 bytes long)
 14410 instruct loadV8(vecD dst, memory mem) %{
 14411   predicate(n->as_LoadVector()->memory_size() == 8);
 14412   match(Set dst (LoadVector mem));
 14413   ins_cost(125);
 14414   format %{ "load    $dst, $mem\t! load vector (8 bytes)" %}
 14415   ins_encode(load_D_enc(dst, mem));
 14416   ins_pipe( fpu_loadF );
 14417 %}
 14419 // Store vectors (8 bytes long)
 14420 instruct storeV8(memory mem, vecD src) %{
 14421   predicate(n->as_StoreVector()->memory_size() == 8);
 14422   match(Set mem (StoreVector mem src));
 14423   ins_cost(145);
 14424   format %{ "store    $mem, $src\t! store vector (8 bytes)" %}
 14425   ins_encode(store_D_reg_enc(mem, src));
 14426   ins_pipe( fpu_storeF );
 14427 %}
 14429 instruct Repl8B_DSP(vecD dst, mRegI src) %{
 14430   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 14431   match(Set dst (ReplicateB src));
 14432   ins_cost(100);
 14433   format %{ "replv_ob    AT, $src\n\t"
 14434             "dmtc1 AT, $dst\t! replicate8B" %}
 14435   ins_encode %{
 14436     __ replv_ob(AT, $src$$Register);
 14437     __ dmtc1(AT, $dst$$FloatRegister);
 14438   %}
 14439   ins_pipe( pipe_mtc1 );
 14440 %}
 14442 instruct Repl8B(vecD dst, mRegI src) %{
 14443   predicate(n->as_Vector()->length() == 8);
 14444   match(Set dst (ReplicateB src));
 14445   ins_cost(140);
 14446   format %{ "move       AT,  $src\n\t"
 14447             "dins  AT, AT,  8,  8\n\t"
 14448             "dins  AT, AT, 16, 16\n\t"
 14449             "dinsu AT, AT, 32, 32\n\t"
 14450             "dmtc1 AT, $dst\t! replicate8B" %}
 14451   ins_encode %{
 14452     __ move(AT, $src$$Register);
 14453     __ dins(AT, AT, 8, 8);
 14454     __ dins(AT, AT, 16, 16);
 14455     __ dinsu(AT, AT, 32, 32);
 14456     __ dmtc1(AT, $dst$$FloatRegister);
 14457   %}
 14458   ins_pipe( pipe_mtc1 );
 14459 %}
 14461 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
 14462   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 14463   match(Set dst (ReplicateB con));
 14464   ins_cost(110);
 14465   format %{ "repl_ob    AT, [$con]\n\t"
 14466             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 14467   ins_encode %{
 14468     int      val = $con$$constant;
 14469     __ repl_ob(AT, val);
 14470     __ dmtc1(AT, $dst$$FloatRegister);
 14471   %}
 14472   ins_pipe( pipe_mtc1 );
 14473 %}
 14475 instruct Repl8B_imm(vecD dst, immI con) %{
 14476   predicate(n->as_Vector()->length() == 8);
 14477   match(Set dst (ReplicateB con));
 14478   ins_cost(150);
 14479   format %{ "move      AT, [$con]\n\t"
 14480             "dins  AT, AT,  8,  8\n\t"
 14481             "dins  AT, AT, 16, 16\n\t"
 14482             "dinsu AT, AT, 32, 32\n\t"
 14483             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 14484   ins_encode %{
 14485     __ move(AT, $con$$constant);
 14486     __ dins(AT, AT, 8, 8);
 14487     __ dins(AT, AT, 16, 16);
 14488     __ dinsu(AT, AT, 32, 32);
 14489     __ dmtc1(AT, $dst$$FloatRegister);
 14490   %}
 14491   ins_pipe( pipe_mtc1 );
 14492 %}
 14494 instruct Repl8B_zero(vecD dst, immI0 zero) %{
 14495   predicate(n->as_Vector()->length() == 8);
 14496   match(Set dst (ReplicateB zero));
 14497   ins_cost(90);
 14498   format %{ "dmtc1    R0, $dst\t! replicate8B zero" %}
 14499   ins_encode %{
 14500     __ dmtc1(R0, $dst$$FloatRegister);
 14501   %}
 14502   ins_pipe( pipe_mtc1 );
 14503 %}
 14505 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
 14506   predicate(n->as_Vector()->length() == 8);
 14507   match(Set dst (ReplicateB M1));
 14508   ins_cost(80);
 14509   format %{ "dmtc1    -1, $dst\t! replicate8B -1" %}
 14510   ins_encode %{
 14511     __ nor(AT, R0, R0);
 14512     __ dmtc1(AT, $dst$$FloatRegister);
 14513   %}
 14514   ins_pipe( pipe_mtc1 );
 14515 %}
 14517 instruct Repl4S_DSP(vecD dst, mRegI src) %{
 14518   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 14519   match(Set dst (ReplicateS src));
 14520   ins_cost(100);
 14521   format %{ "replv_qh    AT, $src\n\t"
 14522             "dmtc1 AT, $dst\t! replicate4S" %}
 14523   ins_encode %{
 14524     __ replv_qh(AT, $src$$Register);
 14525     __ dmtc1(AT, $dst$$FloatRegister);
 14526   %}
 14527   ins_pipe( pipe_mtc1 );
 14528 %}
 14530 instruct Repl4S(vecD dst, mRegI src) %{
 14531   predicate(n->as_Vector()->length() == 4);
 14532   match(Set dst (ReplicateS src));
 14533   ins_cost(120);
 14534   format %{ "move    AT,     $src  \n\t"
 14535             "dins    AT, AT, 16, 16\n\t"
 14536             "dinsu   AT, AT, 32, 32\n\t"
 14537             "dmtc1 AT, $dst\t! replicate4S" %}
 14538   ins_encode %{
 14539     __ move(AT, $src$$Register);
 14540     __ dins(AT, AT, 16, 16);
 14541     __ dinsu(AT, AT, 32, 32);
 14542     __ dmtc1(AT, $dst$$FloatRegister);
 14543   %}
 14544   ins_pipe( pipe_mtc1 );
 14545 %}
 14547 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
 14548   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 14549   match(Set dst (ReplicateS con));
 14550   ins_cost(100);
 14551   format %{ "repl_qh    AT, [$con]\n\t"
 14552             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 14553   ins_encode %{
 14554     int      val = $con$$constant;
 14555     if ( Assembler::is_simm(val, 10)) {
 14556       //repl_qh supports 10 bits immediate
 14557       __ repl_qh(AT, val);
 14558     } else {
 14559       __ li32(AT, val);
 14560       __ replv_qh(AT, AT);
 14562     __ dmtc1(AT, $dst$$FloatRegister);
 14563   %}
 14564   ins_pipe( pipe_mtc1 );
 14565 %}
 14567 instruct Repl4S_imm(vecD dst, immI con) %{
 14568   predicate(n->as_Vector()->length() == 4);
 14569   match(Set dst (ReplicateS con));
 14570   ins_cost(110);
 14571   format %{ "move    AT,   [$con]\n\t"
 14572             "dins  AT, AT, 16, 16\n\t"
 14573             "dinsu AT, AT, 32, 32\n\t"
 14574             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 14575   ins_encode %{
 14576     __ move(AT, $con$$constant);
 14577     __ dins(AT, AT, 16, 16);
 14578     __ dinsu(AT, AT, 32, 32);
 14579     __ dmtc1(AT, $dst$$FloatRegister);
 14580   %}
 14581   ins_pipe( pipe_mtc1 );
 14582 %}
 14584 instruct Repl4S_zero(vecD dst, immI0 zero) %{
 14585   predicate(n->as_Vector()->length() == 4);
 14586   match(Set dst (ReplicateS zero));
 14587   format %{ "dmtc1    R0, $dst\t! replicate4S zero" %}
 14588   ins_encode %{
 14589     __ dmtc1(R0, $dst$$FloatRegister);
 14590   %}
 14591   ins_pipe( pipe_mtc1 );
 14592 %}
 14594 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
 14595   predicate(n->as_Vector()->length() == 4);
 14596   match(Set dst (ReplicateS M1));
 14597   format %{ "dmtc1    -1, $dst\t! replicate4S -1" %}
 14598   ins_encode %{
 14599     __ nor(AT, R0, R0);
 14600     __ dmtc1(AT, $dst$$FloatRegister);
 14601   %}
 14602   ins_pipe( pipe_mtc1 );
 14603 %}
 14605 // Replicate integer (4 byte) scalar to be vector
 14606 instruct Repl2I(vecD dst, mRegI src) %{
 14607   predicate(n->as_Vector()->length() == 2);
 14608   match(Set dst (ReplicateI src));
 14609   format %{ "dins    AT, $src, 0, 32\n\t"
 14610             "dinsu   AT, $src, 32, 32\n\t"
 14611             "dmtc1   AT, $dst\t! replicate2I" %}
 14612   ins_encode %{
 14613     __ dins(AT, $src$$Register, 0, 32);
 14614     __ dinsu(AT, $src$$Register, 32, 32);
 14615     __ dmtc1(AT, $dst$$FloatRegister);
 14616   %}
 14617   ins_pipe( pipe_mtc1 );
 14618 %}
 14620 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
 14621 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
 14622   predicate(n->as_Vector()->length() == 2);
 14623   match(Set dst (ReplicateI con));
 14624   effect(KILL tmp);
 14625   format %{ "li32    AT, [$con], 32\n\t"
 14626             "dinsu   AT,         AT\n\t"
 14627             "dmtc1   AT, $dst\t! replicate2I($con)" %}
 14628   ins_encode %{
 14629     int      val = $con$$constant;
 14630     __ li32(AT, val);
 14631     __ dinsu(AT, AT, 32, 32);
 14632     __ dmtc1(AT, $dst$$FloatRegister);
 14633   %}
 14634   ins_pipe( pipe_mtc1 );
 14635 %}
 14637 // Replicate integer (4 byte) scalar zero to be vector
 14638 instruct Repl2I_zero(vecD dst, immI0 zero) %{
 14639   predicate(n->as_Vector()->length() == 2);
 14640   match(Set dst (ReplicateI zero));
 14641   format %{ "dmtc1    R0, $dst\t! replicate2I zero" %}
 14642   ins_encode %{
 14643     __ dmtc1(R0, $dst$$FloatRegister);
 14644   %}
 14645   ins_pipe( pipe_mtc1 );
 14646 %}
 14648 // Replicate integer (4 byte) scalar -1 to be vector
 14649 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
 14650   predicate(n->as_Vector()->length() == 2);
 14651   match(Set dst (ReplicateI M1));
 14652   format %{ "dmtc1    -1, $dst\t! replicate2I -1, use AT" %}
 14653   ins_encode %{
 14654     __ nor(AT, R0, R0);
 14655     __ dmtc1(AT, $dst$$FloatRegister);
 14656   %}
 14657   ins_pipe( pipe_mtc1 );
 14658 %}
 14660 // Replicate float (4 byte) scalar to be vector
 14661 instruct Repl2F(vecD dst, regF src) %{
 14662   predicate(n->as_Vector()->length() == 2);
 14663   match(Set dst (ReplicateF src));
 14664   format %{ "cvt.ps  $dst, $src, $src\t! replicate2F" %}
 14665   ins_encode %{
 14666     __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
 14667   %}
 14668   ins_pipe( pipe_slow );
 14669 %}
 14671 // Replicate float (4 byte) scalar zero to be vector
 14672 instruct Repl2F_zero(vecD dst, immF0 zero) %{
 14673   predicate(n->as_Vector()->length() == 2);
 14674   match(Set dst (ReplicateF zero));
 14675   format %{ "dmtc1   R0, $dst\t! replicate2F zero" %}
 14676   ins_encode %{
 14677     __ dmtc1(R0, $dst$$FloatRegister);
 14678   %}
 14679   ins_pipe( pipe_mtc1 );
 14680 %}
 14683 // ====================VECTOR ARITHMETIC=======================================
 14685 // --------------------------------- ADD --------------------------------------
 14687 // Floats vector add
 14688 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
 14689 instruct vadd2F(vecD dst, vecD src) %{
 14690   predicate(n->as_Vector()->length() == 2);
 14691   match(Set dst (AddVF dst src));
 14692   format %{ "add.ps   $dst,$src\t! add packed2F" %}
 14693   ins_encode %{
 14694     __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14695   %}
 14696   ins_pipe( pipe_slow );
 14697 %}
 14699 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
 14700   predicate(n->as_Vector()->length() == 2);
 14701   match(Set dst (AddVF src1 src2));
 14702   format %{ "add.ps   $dst,$src1,$src2\t! add packed2F" %}
 14703   ins_encode %{
 14704     __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14705   %}
 14706   ins_pipe( fpu_regF_regF );
 14707 %}
 14709 // --------------------------------- SUB --------------------------------------
 14711 // Floats vector sub
 14712 instruct vsub2F(vecD dst, vecD src) %{
 14713   predicate(n->as_Vector()->length() == 2);
 14714   match(Set dst (SubVF dst src));
 14715   format %{ "sub.ps   $dst,$src\t! sub packed2F" %}
 14716   ins_encode %{
 14717     __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14718   %}
 14719   ins_pipe( fpu_regF_regF );
 14720 %}
 14722 // --------------------------------- MUL --------------------------------------
 14724 // Floats vector mul
 14725 instruct vmul2F(vecD dst, vecD src) %{
 14726   predicate(n->as_Vector()->length() == 2);
 14727   match(Set dst (MulVF dst src));
 14728   format %{ "mul.ps   $dst, $src\t! mul packed2F" %}
 14729   ins_encode %{
 14730     __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14731   %}
 14732   ins_pipe( fpu_regF_regF );
 14733 %}
 14735 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
 14736   predicate(n->as_Vector()->length() == 2);
 14737   match(Set dst (MulVF src1 src2));
 14738   format %{ "mul.ps   $dst, $src1, $src2\t! mul packed2F" %}
 14739   ins_encode %{
 14740     __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14741   %}
 14742   ins_pipe( fpu_regF_regF );
 14743 %}
 14745 // --------------------------------- DIV --------------------------------------
 14746 // MIPS do not have div.ps
 14748 // --------------------------------- MADD --------------------------------------
 14749 // Floats vector madd
 14750 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
 14751 //  predicate(n->as_Vector()->length() == 2);
 14752 //  match(Set dst (AddVF (MulVF src1 src2) src3));
 14753 //  ins_cost(50);
 14754 //  format %{ "madd.ps   $dst, $src3, $src1, $src2\t! madd packed2F" %}
 14755 //  ins_encode %{
 14756 //    __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14757 //  %}
 14758 //  ins_pipe( fpu_regF_regF );
 14759 //%}
 14762 //----------PEEPHOLE RULES-----------------------------------------------------
 14763 // These must follow all instruction definitions as they use the names
 14764 // defined in the instructions definitions.
 14765 //
 14766 // peepmatch ( root_instr_name [preceeding_instruction]* );
 14767 //
 14768 // peepconstraint %{
 14769 // (instruction_number.operand_name relational_op instruction_number.operand_name
 14770 //  [, ...] );
 14771 // // instruction numbers are zero-based using left to right order in peepmatch
 14772 //
 14773 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
 14774 // // provide an instruction_number.operand_name for each operand that appears
 14775 // // in the replacement instruction's match rule
 14776 //
 14777 // ---------VM FLAGS---------------------------------------------------------
 14778 //
 14779 // All peephole optimizations can be turned off using -XX:-OptoPeephole
 14780 //
 14781 // Each peephole rule is given an identifying number starting with zero and
 14782 // increasing by one in the order seen by the parser.  An individual peephole
 14783 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
 14784 // on the command-line.
 14785 //
 14786 // ---------CURRENT LIMITATIONS----------------------------------------------
 14787 //
 14788 // Only match adjacent instructions in same basic block
 14789 // Only equality constraints
 14790 // Only constraints between operands, not (0.dest_reg == EAX_enc)
 14791 // Only one replacement instruction
 14792 //
 14793 // ---------EXAMPLE----------------------------------------------------------
 14794 //
 14795 // // pertinent parts of existing instructions in architecture description
 14796 // instruct movI(eRegI dst, eRegI src) %{
 14797 //   match(Set dst (CopyI src));
 14798 // %}
 14799 //
 14800 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
 14801 //   match(Set dst (AddI dst src));
 14802 //   effect(KILL cr);
 14803 // %}
 14804 //
 14805 // // Change (inc mov) to lea
 14806 // peephole %{
 14807 //   // increment preceeded by register-register move
 14808 //   peepmatch ( incI_eReg movI );
 14809 //   // require that the destination register of the increment
 14810 //   // match the destination register of the move
 14811 //   peepconstraint ( 0.dst == 1.dst );
 14812 //   // construct a replacement instruction that sets
 14813 //   // the destination to ( move's source register + one )
 14814 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14815 // %}
 14816 //
 14817 // Implementation no longer uses movX instructions since
 14818 // machine-independent system no longer uses CopyX nodes.
 14819 //
 14820 // peephole %{
 14821 //   peepmatch ( incI_eReg movI );
 14822 //   peepconstraint ( 0.dst == 1.dst );
 14823 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14824 // %}
 14825 //
 14826 // peephole %{
 14827 //   peepmatch ( decI_eReg movI );
 14828 //   peepconstraint ( 0.dst == 1.dst );
 14829 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14830 // %}
 14831 //
 14832 // peephole %{
 14833 //   peepmatch ( addI_eReg_imm movI );
 14834 //   peepconstraint ( 0.dst == 1.dst );
 14835 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14836 // %}
 14837 //
 14838 // peephole %{
 14839 //   peepmatch ( addP_eReg_imm movP );
 14840 //   peepconstraint ( 0.dst == 1.dst );
 14841 //   peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
 14842 // %}
 14844 // // Change load of spilled value to only a spill
 14845 // instruct storeI(memory mem, eRegI src) %{
 14846 //   match(Set mem (StoreI mem src));
 14847 // %}
 14848 //
 14849 // instruct loadI(eRegI dst, memory mem) %{
 14850 //   match(Set dst (LoadI mem));
 14851 // %}
 14852 //
 14853 //peephole %{
 14854 //  peepmatch ( loadI storeI );
 14855 //  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
 14856 //  peepreplace ( storeI( 1.mem 1.mem 1.src ) );
 14857 //%}
 14859 //----------SMARTSPILL RULES---------------------------------------------------
 14860 // These must follow all instruction definitions as they use the names
 14861 // defined in the instructions definitions.

mercurial