src/cpu/mips/vm/mips_64.ad

Tue, 04 Sep 2018 21:25:12 +0800

author
aoqi
date
Tue, 04 Sep 2018 21:25:12 +0800
changeset 9228
617b86d17edb
parent 9155
30adb9fd9663
child 9234
a1cf6cdffc83
permissions
-rw-r--r--

#7517 mRegP match a0_RegP

     1 //
     2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     3 // Copyright (c) 2015, 2018, Loongson Technology. All rights reserved.
     4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5 //
     6 // This code is free software; you can redistribute it and/or modify it
     7 // under the terms of the GNU General Public License version 2 only, as
     8 // published by the Free Software Foundation.
     9 //
    10 // This code is distributed in the hope that it will be useful, but WITHOUT
    11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13 // version 2 for more details (a copy is included in the LICENSE file that
    14 // accompanied this code).
    15 //
    16 // You should have received a copy of the GNU General Public License version
    17 // 2 along with this work; if not, write to the Free Software Foundation,
    18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19 //
    20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21 // or visit www.oracle.com if you need additional information or have any
    22 // questions.
    23 //
    24 //
    26 // GodSon3 Architecture Description File
    28 //----------REGISTER DEFINITION BLOCK------------------------------------------
    29 // This information is used by the matcher and the register allocator to
    30 // describe individual registers and classes of registers within the target
    31 // archtecture.
    33 // format:
    34 // reg_def name (call convention, c-call convention, ideal type, encoding);
    35 //     call convention :
    36 //      NS  = No-Save
    37 //      SOC = Save-On-Call
    38 //      SOE = Save-On-Entry
    39 //      AS  = Always-Save
    40 //    ideal type :
    41 //      see opto/opcodes.hpp for more info
    42 // reg_class name (reg, ...);
    43 // alloc_class name (reg, ...);
    44 register %{
    46 // General Registers
    47 // Integer Registers
    48   reg_def R0      ( NS,  NS,   Op_RegI,  0, VMRegImpl::Bad());
    49   reg_def AT    ( NS,  NS,   Op_RegI,  1, AT->as_VMReg());
    50   reg_def AT_H    ( NS,  NS,  Op_RegI,  1, AT->as_VMReg()->next());
    51   reg_def V0    (SOC, SOC,  Op_RegI,  2, V0->as_VMReg());
    52   reg_def V0_H  (SOC, SOC,  Op_RegI,  2, V0->as_VMReg()->next());
    53   reg_def V1    (SOC, SOC,  Op_RegI,  3, V1->as_VMReg());
    54   reg_def V1_H  (SOC, SOC,  Op_RegI,  3, V1->as_VMReg()->next());
    55   reg_def A0    (SOC, SOC,  Op_RegI,  4, A0->as_VMReg());
    56   reg_def A0_H  (SOC, SOC,  Op_RegI,  4, A0->as_VMReg()->next());
    57   reg_def A1    (SOC, SOC,  Op_RegI,  5, A1->as_VMReg());
    58   reg_def A1_H  (SOC, SOC,  Op_RegI,  5, A1->as_VMReg()->next());
    59   reg_def A2    (SOC, SOC,  Op_RegI,  6, A2->as_VMReg());
    60   reg_def A2_H  (SOC, SOC,  Op_RegI,  6, A2->as_VMReg()->next());
    61   reg_def A3    (SOC, SOC,  Op_RegI,  7, A3->as_VMReg());
    62   reg_def A3_H  (SOC, SOC,  Op_RegI,  7, A3->as_VMReg()->next());
    63   reg_def A4    (SOC, SOC,  Op_RegI,  8, A4->as_VMReg());
    64   reg_def A4_H  (SOC, SOC,  Op_RegI,  8, A4->as_VMReg()->next());
    65   reg_def A5    (SOC, SOC,  Op_RegI,  9, A5->as_VMReg());
    66   reg_def A5_H  (SOC, SOC,  Op_RegI,  9, A5->as_VMReg()->next());
    67   reg_def A6    (SOC, SOC,  Op_RegI,  10, A6->as_VMReg());
    68   reg_def A6_H  (SOC, SOC,  Op_RegI,  10, A6->as_VMReg()->next());
    69   reg_def A7    (SOC, SOC,  Op_RegI,  11, A7->as_VMReg());
    70   reg_def A7_H  (SOC, SOC,  Op_RegI,  11, A7->as_VMReg()->next());
    71   reg_def T0    (SOC, SOC,  Op_RegI,  12, T0->as_VMReg());
    72   reg_def T0_H  (SOC, SOC,  Op_RegI,  12, T0->as_VMReg()->next());
    73   reg_def T1    (SOC, SOC,  Op_RegI,  13, T1->as_VMReg());
    74   reg_def T1_H  (SOC, SOC,  Op_RegI,  13, T1->as_VMReg()->next());
    75   reg_def T2    (SOC, SOC,  Op_RegI,  14, T2->as_VMReg());
    76   reg_def T2_H  (SOC, SOC,  Op_RegI,  14, T2->as_VMReg()->next());
    77   reg_def T3    (SOC, SOC,  Op_RegI,  15, T3->as_VMReg());
    78   reg_def T3_H  (SOC, SOC,  Op_RegI,  15, T3->as_VMReg()->next());
    79   reg_def S0    (SOC, SOE,  Op_RegI,  16, S0->as_VMReg());
    80   reg_def S0_H  (SOC, SOE,  Op_RegI,  16, S0->as_VMReg()->next());
    81   reg_def S1    (SOC, SOE,  Op_RegI,  17, S1->as_VMReg());
    82   reg_def S1_H  (SOC, SOE,  Op_RegI,  17, S1->as_VMReg()->next());
    83   reg_def S2    (SOC, SOE,  Op_RegI,  18, S2->as_VMReg());
    84   reg_def S2_H  (SOC, SOE,  Op_RegI,  18, S2->as_VMReg()->next());
    85   reg_def S3    (SOC, SOE,  Op_RegI,  19, S3->as_VMReg());
    86   reg_def S3_H  (SOC, SOE,  Op_RegI,  19, S3->as_VMReg()->next());
    87   reg_def S4    (SOC, SOE,  Op_RegI,  20, S4->as_VMReg());
    88   reg_def S4_H  (SOC, SOE,  Op_RegI,  20, S4->as_VMReg()->next());
    89   reg_def S5    (SOC, SOE,  Op_RegI,  21, S5->as_VMReg());
    90   reg_def S5_H  (SOC, SOE,  Op_RegI,  21, S5->as_VMReg()->next());
    91   reg_def S6    (SOC, SOE,  Op_RegI,  22, S6->as_VMReg());
    92   reg_def S6_H  (SOC, SOE,  Op_RegI,  22, S6->as_VMReg()->next());
    93   reg_def S7    (SOC, SOE,  Op_RegI,  23, S7->as_VMReg());
    94   reg_def S7_H  (SOC, SOE,  Op_RegI,  23, S7->as_VMReg()->next());
    95   reg_def T8    (SOC, SOC,  Op_RegI,  24, T8->as_VMReg());
    96   reg_def T8_H  (SOC, SOC,  Op_RegI,  24, T8->as_VMReg()->next());
    97   reg_def T9    (SOC, SOC,  Op_RegI,  25, T9->as_VMReg());
    98   reg_def T9_H  (SOC, SOC,  Op_RegI,  25, T9->as_VMReg()->next());
   100 // Special Registers
   101   reg_def K0    ( NS,  NS,  Op_RegI, 26, K0->as_VMReg());
   102   reg_def K1    ( NS,  NS,  Op_RegI, 27, K1->as_VMReg());
   103   reg_def GP    ( NS,  NS,  Op_RegI, 28, GP->as_VMReg());
   104   reg_def GP_H  ( NS,  NS,  Op_RegI, 28, GP->as_VMReg()->next());
   105   reg_def SP    ( NS,  NS,  Op_RegI, 29, SP->as_VMReg());
   106   reg_def SP_H  ( NS,  NS,  Op_RegI, 29, SP->as_VMReg()->next());
   107   reg_def FP    ( NS,  NS,  Op_RegI, 30, FP->as_VMReg());
   108   reg_def FP_H  ( NS,  NS,  Op_RegI, 30, FP->as_VMReg()->next());
   109   reg_def RA    ( NS,  NS,  Op_RegI, 31, RA->as_VMReg());
   110   reg_def RA_H  ( NS,  NS,  Op_RegI, 31, RA->as_VMReg()->next());
   112 // Floating registers.
   113 reg_def F0          ( SOC, SOC, Op_RegF, 0, F0->as_VMReg());
   114 reg_def F0_H        ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()->next());
   115 reg_def F1          ( SOC, SOC, Op_RegF, 1, F1->as_VMReg());
   116 reg_def F1_H        ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()->next());
   117 reg_def F2          ( SOC, SOC, Op_RegF, 2, F2->as_VMReg());
   118 reg_def F2_H        ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()->next());
   119 reg_def F3          ( SOC, SOC, Op_RegF, 3, F3->as_VMReg());
   120 reg_def F3_H        ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()->next());
   121 reg_def F4          ( SOC, SOC, Op_RegF, 4, F4->as_VMReg());
   122 reg_def F4_H        ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()->next());
   123 reg_def F5          ( SOC, SOC, Op_RegF, 5, F5->as_VMReg());
   124 reg_def F5_H        ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()->next());
   125 reg_def F6          ( SOC, SOC, Op_RegF, 6, F6->as_VMReg());
   126 reg_def F6_H        ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()->next());
   127 reg_def F7          ( SOC, SOC, Op_RegF, 7, F7->as_VMReg());
   128 reg_def F7_H        ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()->next());
   129 reg_def F8          ( SOC, SOC, Op_RegF, 8, F8->as_VMReg());
   130 reg_def F8_H        ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()->next());
   131 reg_def F9          ( SOC, SOC, Op_RegF, 9, F9->as_VMReg());
   132 reg_def F9_H        ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()->next());
   133 reg_def F10         ( SOC, SOC, Op_RegF, 10, F10->as_VMReg());
   134 reg_def F10_H       ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()->next());
   135 reg_def F11         ( SOC, SOC, Op_RegF, 11, F11->as_VMReg());
   136 reg_def F11_H       ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()->next());
   137 reg_def F12         ( SOC, SOC, Op_RegF, 12, F12->as_VMReg());
   138 reg_def F12_H       ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()->next());
   139 reg_def F13         ( SOC, SOC, Op_RegF, 13, F13->as_VMReg());
   140 reg_def F13_H       ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()->next());
   141 reg_def F14         ( SOC, SOC, Op_RegF, 14, F14->as_VMReg());
   142 reg_def F14_H       ( SOC, SOC, Op_RegF, 14, F14->as_VMReg()->next());
   143 reg_def F15         ( SOC, SOC, Op_RegF, 15, F15->as_VMReg());
   144 reg_def F15_H       ( SOC, SOC, Op_RegF, 15, F15->as_VMReg()->next());
   145 reg_def F16         ( SOC, SOC, Op_RegF, 16, F16->as_VMReg());
   146 reg_def F16_H       ( SOC, SOC, Op_RegF, 16, F16->as_VMReg()->next());
   147 reg_def F17         ( SOC, SOC, Op_RegF, 17, F17->as_VMReg());
   148 reg_def F17_H       ( SOC, SOC, Op_RegF, 17, F17->as_VMReg()->next());
   149 reg_def F18         ( SOC, SOC, Op_RegF, 18, F18->as_VMReg());
   150 reg_def F18_H       ( SOC, SOC, Op_RegF, 18, F18->as_VMReg()->next());
   151 reg_def F19         ( SOC, SOC, Op_RegF, 19, F19->as_VMReg());
   152 reg_def F19_H       ( SOC, SOC, Op_RegF, 19, F19->as_VMReg()->next());
   153 reg_def F20         ( SOC, SOC, Op_RegF, 20, F20->as_VMReg());
   154 reg_def F20_H       ( SOC, SOC, Op_RegF, 20, F20->as_VMReg()->next());
   155 reg_def F21         ( SOC, SOC, Op_RegF, 21, F21->as_VMReg());
   156 reg_def F21_H       ( SOC, SOC, Op_RegF, 21, F21->as_VMReg()->next());
   157 reg_def F22         ( SOC, SOC, Op_RegF, 22, F22->as_VMReg());
   158 reg_def F22_H       ( SOC, SOC, Op_RegF, 22, F22->as_VMReg()->next());
   159 reg_def F23         ( SOC, SOC, Op_RegF, 23, F23->as_VMReg());
   160 reg_def F23_H       ( SOC, SOC, Op_RegF, 23, F23->as_VMReg()->next());
   161 reg_def F24         ( SOC, SOC, Op_RegF, 24, F24->as_VMReg());
   162 reg_def F24_H       ( SOC, SOC, Op_RegF, 24, F24->as_VMReg()->next());
   163 reg_def F25         ( SOC, SOC, Op_RegF, 25, F25->as_VMReg());
   164 reg_def F25_H       ( SOC, SOC, Op_RegF, 25, F25->as_VMReg()->next());
   165 reg_def F26         ( SOC, SOC, Op_RegF, 26, F26->as_VMReg());
   166 reg_def F26_H       ( SOC, SOC, Op_RegF, 26, F26->as_VMReg()->next());
   167 reg_def F27         ( SOC, SOC, Op_RegF, 27, F27->as_VMReg());
   168 reg_def F27_H       ( SOC, SOC, Op_RegF, 27, F27->as_VMReg()->next());
   169 reg_def F28         ( SOC, SOC, Op_RegF, 28, F28->as_VMReg());
   170 reg_def F28_H       ( SOC, SOC, Op_RegF, 28, F28->as_VMReg()->next());
   171 reg_def F29         ( SOC, SOC, Op_RegF, 29, F29->as_VMReg());
   172 reg_def F29_H       ( SOC, SOC, Op_RegF, 29, F29->as_VMReg()->next());
   173 reg_def F30         ( SOC, SOC, Op_RegF, 30, F30->as_VMReg());
   174 reg_def F30_H       ( SOC, SOC, Op_RegF, 30, F30->as_VMReg()->next());
   175 reg_def F31         ( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
   176 reg_def F31_H       ( SOC, SOC, Op_RegF, 31, F31->as_VMReg()->next());
   179 // ----------------------------
   180 // Special Registers
   181 // Condition Codes Flag Registers
   182 reg_def MIPS_FLAG (SOC, SOC,  Op_RegFlags, 1, as_Register(1)->as_VMReg());
   183 //S6 is used for get_thread(S6)
   184 //S5 is uesd for heapbase of compressed oop
   185 alloc_class chunk0(
   186                      S7, S7_H,
   187                      S0, S0_H,
   188                      S1, S1_H,
   189                      S2, S2_H,
   190                      S4, S4_H,
   191                      S5, S5_H,
   192                      S6, S6_H,
   193                      S3, S3_H,
   194                      T2, T2_H,
   195                      T3, T3_H,
   196                      T8, T8_H,
   197                      T9, T9_H,
   198                      T1, T1_H, // inline_cache_reg
   199                      V1, V1_H,
   200                      A7, A7_H,
   201                      A6, A6_H,
   202                      A5, A5_H,
   203                      A4, A4_H,
   204                      V0, V0_H,
   205                      A3, A3_H,
   206                      A2, A2_H,
   207                      A1, A1_H,
   208                      A0, A0_H,
   209                      T0, T0_H,
   210                      GP, GP_H
   211                      RA, RA_H,
   212                      SP, SP_H, // stack_pointer
   213                      FP, FP_H  // frame_pointer
   214                  );
   216 alloc_class chunk1(  F0, F0_H,
   217                      F1, F1_H,
   218                      F2, F2_H,
   219                      F3, F3_H,
   220                      F4, F4_H,
   221                      F5, F5_H,
   222                      F6, F6_H,
   223                      F7, F7_H,
   224                      F8, F8_H,
   225                      F9, F9_H,
   226                      F10, F10_H,
   227                      F11, F11_H,
   228                      F20, F20_H,
   229                      F21, F21_H,
   230                      F22, F22_H,
   231                      F23, F23_H,
   232                      F24, F24_H,
   233                      F25, F25_H,
   234                      F26, F26_H,
   235                      F27, F27_H,
   236                      F28, F28_H,
   237                      F19, F19_H,
   238                      F18, F18_H,
   239                      F17, F17_H,
   240                      F16, F16_H,
   241                      F15, F15_H,
   242                      F14, F14_H,
   243                      F13, F13_H,
   244                      F12, F12_H,
   245                      F29, F29_H,
   246                      F30, F30_H,
   247                      F31, F31_H);
   249 alloc_class chunk2(MIPS_FLAG);
   251 reg_class s_reg( S0, S1, S2, S3, S4, S5, S6, S7 );
   252 reg_class s0_reg( S0 );
   253 reg_class s1_reg( S1 );
   254 reg_class s2_reg( S2 );
   255 reg_class s3_reg( S3 );
   256 reg_class s4_reg( S4 );
   257 reg_class s5_reg( S5 );
   258 reg_class s6_reg( S6 );
   259 reg_class s7_reg( S7 );
   261 reg_class t_reg( T0, T1, T2, T3, T8, T9 );
   262 reg_class t0_reg( T0 );
   263 reg_class t1_reg( T1 );
   264 reg_class t2_reg( T2 );
   265 reg_class t3_reg( T3 );
   266 reg_class t8_reg( T8 );
   267 reg_class t9_reg( T9 );
   269 reg_class a_reg( A0, A1, A2, A3, A4, A5, A6, A7 );
   270 reg_class a0_reg( A0 );
   271 reg_class a1_reg( A1 );
   272 reg_class a2_reg( A2 );
   273 reg_class a3_reg( A3 );
   274 reg_class a4_reg( A4 );
   275 reg_class a5_reg( A5 );
   276 reg_class a6_reg( A6 );
   277 reg_class a7_reg( A7 );
   279 reg_class v0_reg( V0 );
   280 reg_class v1_reg( V1 );
   282 reg_class sp_reg( SP, SP_H );
   283 reg_class fp_reg( FP, FP_H );
   285 reg_class mips_flags(MIPS_FLAG);
   287 reg_class v0_long_reg( V0, V0_H );
   288 reg_class v1_long_reg( V1, V1_H );
   289 reg_class a0_long_reg( A0, A0_H );
   290 reg_class a1_long_reg( A1, A1_H );
   291 reg_class a2_long_reg( A2, A2_H );
   292 reg_class a3_long_reg( A3, A3_H );
   293 reg_class a4_long_reg( A4, A4_H );
   294 reg_class a5_long_reg( A5, A5_H );
   295 reg_class a6_long_reg( A6, A6_H );
   296 reg_class a7_long_reg( A7, A7_H );
   297 reg_class t0_long_reg( T0, T0_H );
   298 reg_class t1_long_reg( T1, T1_H );
   299 reg_class t2_long_reg( T2, T2_H );
   300 reg_class t3_long_reg( T3, T3_H );
   301 reg_class t8_long_reg( T8, T8_H );
   302 reg_class t9_long_reg( T9, T9_H );
   303 reg_class s0_long_reg( S0, S0_H );
   304 reg_class s1_long_reg( S1, S1_H );
   305 reg_class s2_long_reg( S2, S2_H );
   306 reg_class s3_long_reg( S3, S3_H );
   307 reg_class s4_long_reg( S4, S4_H );
   308 reg_class s5_long_reg( S5, S5_H );
   309 reg_class s6_long_reg( S6, S6_H );
   310 reg_class s7_long_reg( S7, S7_H );
   312 reg_class int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, A7, A6, A5, A4, V0, A3, A2, A1, A0, T0 );
   314 reg_class no_Ax_int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, V0, T0 );
   316 reg_class p_reg(
   317                  S7, S7_H,
   318                  S0, S0_H,
   319                  S1, S1_H,
   320                  S2, S2_H,
   321                  S4, S4_H,
   322                  S3, S3_H,
   323                  T8, T8_H,
   324                  T2, T2_H,
   325                  T3, T3_H,
   326                  T1, T1_H,
   327                  A7, A7_H,
   328                  A6, A6_H,
   329                  A5, A5_H,
   330                  A4, A4_H,
   331                  A3, A3_H,
   332                  A2, A2_H,
   333                  A1, A1_H,
   334                  A0, A0_H,
   335                  T0, T0_H
   336                );
   338 reg_class no_T8_p_reg(
   339                  S7, S7_H,
   340                  S0, S0_H,
   341                  S1, S1_H,
   342                  S2, S2_H,
   343                  S4, S4_H,
   344                  S3, S3_H,
   345                  T2, T2_H,
   346                  T3, T3_H,
   347                  T1, T1_H,
   348                  A7, A7_H,
   349                  A6, A6_H,
   350                  A5, A5_H,
   351                  A4, A4_H,
   352                  A3, A3_H,
   353                  A2, A2_H,
   354                  A1, A1_H,
   355                  A0, A0_H,
   356                  T0, T0_H
   357                );
   359 reg_class long_reg(
   360                     S7, S7_H,
   361                     S0, S0_H,
   362                     S1, S1_H,
   363                     S2, S2_H,
   364                     S4, S4_H,
   365                     S3, S3_H,
   366                     T8, T8_H,
   367                     T2, T2_H,
   368                     T3, T3_H,
   369                     T1, T1_H,
   370                     A7, A7_H,
   371                     A6, A6_H,
   372                     A5, A5_H,
   373                     A4, A4_H,
   374                     A3, A3_H,
   375                     A2, A2_H,
   376                     A1, A1_H,
   377                     A0, A0_H,
   378                     T0, T0_H
   379                   );
   382 // Floating point registers.
   383 // F31 are not used as temporary registers in D2I
   384 reg_class flt_reg( F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17 F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F31);
   385 reg_class dbl_reg( F0, F0_H,
   386                    F1, F1_H,
   387                    F2, F2_H,
   388                    F3, F3_H,
   389                    F4, F4_H,
   390                    F5, F5_H,
   391                    F6, F6_H,
   392                    F7, F7_H,
   393                    F8, F8_H,
   394                    F9, F9_H,
   395                    F10, F10_H,
   396                    F11, F11_H,
   397                    F12, F12_H,
   398                    F13, F13_H,
   399                    F14, F14_H,
   400                    F15, F15_H,
   401                    F16, F16_H,
   402                    F17, F17_H,
   403                    F18, F18_H,
   404                    F19, F19_H,
   405                    F20, F20_H,
   406                    F21, F21_H,
   407                    F22, F22_H,
   408                    F23, F23_H,
   409                    F24, F24_H,
   410                    F25, F25_H,
   411                    F26, F26_H,
   412                    F27, F27_H,
   413                    F28, F28_H,
   414                    F29, F29_H,
   415                    F31, F31_H);
   417 reg_class flt_arg0( F12 );
   418 reg_class dbl_arg0( F12, F12_H );
   419 reg_class dbl_arg1( F14, F14_H );
   421 %}
   423 //----------DEFINITION BLOCK---------------------------------------------------
   424 // Define name --> value mappings to inform the ADLC of an integer valued name
   425 // Current support includes integer values in the range [0, 0x7FFFFFFF]
   426 // Format:
   427 //        int_def  <name>         ( <int_value>, <expression>);
   428 // Generated Code in ad_<arch>.hpp
   429 //        #define  <name>   (<expression>)
   430 //        // value == <int_value>
   431 // Generated code in ad_<arch>.cpp adlc_verification()
   432 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
   433 //
   434 definitions %{
   435   int_def DEFAULT_COST      (    100,     100);
   436   int_def HUGE_COST         (1000000, 1000000);
   438   // Memory refs are twice as expensive as run-of-the-mill.
   439   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
   441   // Branches are even more expensive.
   442   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
   443   // we use jr instruction to construct call, so more expensive
   444   int_def CALL_COST         (    500, DEFAULT_COST * 5);
   445 /*
   446         int_def EQUAL             (   1, 1  );
   447         int_def NOT_EQUAL         (   2, 2  );
   448         int_def GREATER           (   3, 3  );
   449         int_def GREATER_EQUAL     (   4, 4  );
   450         int_def LESS              (   5, 5  );
   451         int_def LESS_EQUAL        (   6, 6  );
   452 */
   453 %}
   457 //----------SOURCE BLOCK-------------------------------------------------------
   458 // This is a block of C++ code which provides values, functions, and
   459 // definitions necessary in the rest of the architecture description
   461 source_hpp %{
   462 // Header information of the source block.
   463 // Method declarations/definitions which are used outside
   464 // the ad-scope can conveniently be defined here.
   465 //
   466 // To keep related declarations/definitions/uses close together,
   467 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
   469 class CallStubImpl {
   471   //--------------------------------------------------------------
   472   //---<  Used for optimization in Compile::shorten_branches  >---
   473   //--------------------------------------------------------------
   475  public:
   476   // Size of call trampoline stub.
   477   static uint size_call_trampoline() {
   478     return 0; // no call trampolines on this platform
   479   }
   481   // number of relocations needed by a call trampoline stub
   482   static uint reloc_call_trampoline() {
   483     return 0; // no call trampolines on this platform
   484   }
   485 };
   487 class HandlerImpl {
   489  public:
   491   static int emit_exception_handler(CodeBuffer &cbuf);
   492   static int emit_deopt_handler(CodeBuffer& cbuf);
   494   static uint size_exception_handler() {
   495     // NativeCall instruction size is the same as NativeJump.
   496     // exception handler starts out as jump and can be patched to
   497     // a call be deoptimization.  (4932387)
   498     // Note that this value is also credited (in output.cpp) to
   499     // the size of the code section.
   500     int size = NativeCall::instruction_size;
   501     return round_to(size, 16);
   502   }
   504 #ifdef _LP64
   505   static uint size_deopt_handler() {
   506     int size = NativeCall::instruction_size;
   507     return round_to(size, 16);
   508   }
   509 #else
   510   static uint size_deopt_handler() {
   511     // NativeCall instruction size is the same as NativeJump.
   512     // exception handler starts out as jump and can be patched to
   513     // a call be deoptimization.  (4932387)
   514     // Note that this value is also credited (in output.cpp) to
   515     // the size of the code section.
   516     return 5 + NativeJump::instruction_size; // pushl(); jmp;
   517   }
   518 #endif
   519 };
   521 %} // end source_hpp
   523 source %{
   525 #define   NO_INDEX    0
   526 #define   RELOC_IMM64    Assembler::imm_operand
   527 #define   RELOC_DISP32   Assembler::disp32_operand
   530 #define __ _masm.
   533 // Emit exception handler code.
   534 // Stuff framesize into a register and call a VM stub routine.
   535 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
   536   // Note that the code buffer's insts_mark is always relative to insts.
   537   // That's why we must use the macroassembler to generate a handler.
   538   MacroAssembler _masm(&cbuf);
   539   address base = __ start_a_stub(size_exception_handler());
   540   if (base == NULL) {
   541     ciEnv::current()->record_failure("CodeCache is full");
   542     return 0;  // CodeBuffer::expand failed
   543   }
   545   int offset = __ offset();
   547   __ block_comment("; emit_exception_handler");
   549   cbuf.set_insts_mark();
   550   __ relocate(relocInfo::runtime_call_type);
   551   __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
   552   __ align(16);
   553   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
   554   __ end_a_stub();
   555   return offset;
   556 }
   558 // Emit deopt handler code.
   559 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
   560   // Note that the code buffer's insts_mark is always relative to insts.
   561   // That's why we must use the macroassembler to generate a handler.
   562   MacroAssembler _masm(&cbuf);
   563   address base = __ start_a_stub(size_deopt_handler());
   564   if (base == NULL) {
   565     ciEnv::current()->record_failure("CodeCache is full");
   566     return 0;  // CodeBuffer::expand failed
   567   }
   569   int offset = __ offset();
   571   __ block_comment("; emit_deopt_handler");
   573   cbuf.set_insts_mark();
   574   __ relocate(relocInfo::runtime_call_type);
   575   __ patchable_call(SharedRuntime::deopt_blob()->unpack());
   576   __ align(16);
   577   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
   578   __ end_a_stub();
   579   return offset;
   580 }
   583 const bool Matcher::match_rule_supported(int opcode) {
   584   if (!has_match_rule(opcode))
   585     return false;
   587   switch (opcode) {
   588     //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
   589     case Op_CountLeadingZerosI:
   590     case Op_CountLeadingZerosL:
   591       if (!UseCountLeadingZerosInstructionMIPS64)
   592         return false;
   593       break;
   594     case Op_CountTrailingZerosI:
   595     case Op_CountTrailingZerosL:
   596       if (!UseCountTrailingZerosInstructionMIPS64)
   597         return false;
   598       break;
   599   }
   601   return true;  // Per default match rules are supported.
   602 }
   604 //FIXME
   605 // emit call stub, compiled java to interpreter
   606 void emit_java_to_interp(CodeBuffer &cbuf ) {
   607   // Stub is fixed up when the corresponding call is converted from calling
   608   // compiled code to calling interpreted code.
   609   // mov rbx,0
   610   // jmp -1
   612   address mark = cbuf.insts_mark();  // get mark within main instrs section
   614   // Note that the code buffer's insts_mark is always relative to insts.
   615   // That's why we must use the macroassembler to generate a stub.
   616   MacroAssembler _masm(&cbuf);
   618   address base = __ start_a_stub(Compile::MAX_stubs_size);
   619   if (base == NULL) { // CodeBuffer::expand failed
   620     ciEnv::current()->record_failure("CodeCache is full");
   621   }
   623   // static stub relocation stores the instruction address of the call
   625   __ relocate(static_stub_Relocation::spec(mark), 0);
   627   // static stub relocation also tags the methodOop in the code-stream.
   628   __ patchable_set48(S3, (long)0);
   629   // This is recognized as unresolved by relocs/nativeInst/ic code
   631   __ relocate(relocInfo::runtime_call_type);
   633   cbuf.set_insts_mark();
   634   address call_pc = (address)-1;
   635   __ patchable_jump(call_pc);
   636   __ align(16);
   637   __ end_a_stub();
   638   // Update current stubs pointer and restore code_end.
   639 }
   641 // size of call stub, compiled java to interpretor
   642 uint size_java_to_interp() {
   643   int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
   644   return round_to(size, 16);
   645 }
   647 // relocation entries for call stub, compiled java to interpreter
   648 uint reloc_java_to_interp() {
   649   return 16;  //  in emit_java_to_interp +  in Java_Static_Call
   650 }
   652 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
   653   int offs = offset - br_size + 4;
   654   // To be conservative on MIPS
   655   // branch node should be end with:
   656   //   branch inst
   657   //   delay slot
   658   const int safety_zone = 3 * BytesPerInstWord;
   659   return Assembler::is_simm16((offs<0 ? offs-safety_zone : offs+safety_zone) >> 2);
   660 }
   663 // No additional cost for CMOVL.
   664 const int Matcher::long_cmove_cost() { return 0; }
   666 // No CMOVF/CMOVD with SSE2
   667 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
   669 // Does the CPU require late expand (see block.cpp for description of late expand)?
   670 const bool Matcher::require_postalloc_expand = false;
   672 // Should the Matcher clone shifts on addressing modes, expecting them
   673 // to be subsumed into complex addressing expressions or compute them
   674 // into registers?  True for Intel but false for most RISCs
   675 const bool Matcher::clone_shift_expressions = false;
   677 // Do we need to mask the count passed to shift instructions or does
   678 // the cpu only look at the lower 5/6 bits anyway?
   679 const bool Matcher::need_masked_shift_count = false;
   681 bool Matcher::narrow_oop_use_complex_address() {
   682   NOT_LP64(ShouldNotCallThis());
   683   assert(UseCompressedOops, "only for compressed oops code");
   684   return false;
   685 }
   687 bool Matcher::narrow_klass_use_complex_address() {
   688   NOT_LP64(ShouldNotCallThis());
   689   assert(UseCompressedClassPointers, "only for compressed klass code");
   690   return false;
   691 }
   693 // This is UltraSparc specific, true just means we have fast l2f conversion
   694 const bool Matcher::convL2FSupported(void) {
   695   return true;
   696 }
   698 // Max vector size in bytes. 0 if not supported.
   699 const int Matcher::vector_width_in_bytes(BasicType bt) {
   700   if (MaxVectorSize == 0)
   701     return 0;
   702   assert(MaxVectorSize == 8, "");
   703   return 8;
   704 }
   706 // Vector ideal reg
   707 const int Matcher::vector_ideal_reg(int size) {
   708   assert(MaxVectorSize == 8, "");
   709   switch(size) {
   710     case  8: return Op_VecD;
   711   }
   712   ShouldNotReachHere();
   713   return 0;
   714 }
   716 // Only lowest bits of xmm reg are used for vector shift count.
   717 const int Matcher::vector_shift_count_ideal_reg(int size) {
   718   fatal("vector shift is not supported");
   719   return Node::NotAMachineReg;
   720 }
   722 // Limits on vector size (number of elements) loaded into vector.
   723 const int Matcher::max_vector_size(const BasicType bt) {
   724   assert(is_java_primitive(bt), "only primitive type vectors");
   725   return vector_width_in_bytes(bt)/type2aelembytes(bt);
   726 }
   728 const int Matcher::min_vector_size(const BasicType bt) {
   729   return max_vector_size(bt); // Same as max.
   730 }
   732 // MIPS supports misaligned vectors store/load? FIXME
   733 const bool Matcher::misaligned_vectors_ok() {
   734   return false;
   735   //return !AlignVector; // can be changed by flag
   736 }
   738 // Register for DIVI projection of divmodI
   739 RegMask Matcher::divI_proj_mask() {
   740   ShouldNotReachHere();
   741   return RegMask();
   742 }
   744 // Register for MODI projection of divmodI
   745 RegMask Matcher::modI_proj_mask() {
   746   ShouldNotReachHere();
   747   return RegMask();
   748 }
   750 // Register for DIVL projection of divmodL
   751 RegMask Matcher::divL_proj_mask() {
   752   ShouldNotReachHere();
   753   return RegMask();
   754 }
   756 int Matcher::regnum_to_fpu_offset(int regnum) {
   757   return regnum - 32; // The FP registers are in the second chunk
   758 }
   761 const bool Matcher::isSimpleConstant64(jlong value) {
   762   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
   763   return true;
   764 }
   767 // Return whether or not this register is ever used as an argument.  This
   768 // function is used on startup to build the trampoline stubs in generateOptoStub.
   769 // Registers not mentioned will be killed by the VM call in the trampoline, and
   770 // arguments in those registers not be available to the callee.
   771 bool Matcher::can_be_java_arg( int reg ) {
   772   /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
   773   if (    reg == T0_num || reg == T0_H_num
   774        || reg == A0_num || reg == A0_H_num
   775        || reg == A1_num || reg == A1_H_num
   776        || reg == A2_num || reg == A2_H_num
   777        || reg == A3_num || reg == A3_H_num
   778        || reg == A4_num || reg == A4_H_num
   779        || reg == A5_num || reg == A5_H_num
   780        || reg == A6_num || reg == A6_H_num
   781        || reg == A7_num || reg == A7_H_num )
   782     return true;
   784   if (    reg == F12_num || reg == F12_H_num
   785        || reg == F13_num || reg == F13_H_num
   786        || reg == F14_num || reg == F14_H_num
   787        || reg == F15_num || reg == F15_H_num
   788        || reg == F16_num || reg == F16_H_num
   789        || reg == F17_num || reg == F17_H_num
   790        || reg == F18_num || reg == F18_H_num
   791        || reg == F19_num || reg == F19_H_num )
   792     return true;
   794   return false;
   795 }
   797 bool Matcher::is_spillable_arg( int reg ) {
   798   return can_be_java_arg(reg);
   799 }
   801 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
   802   return false;
   803 }
   805 // Register for MODL projection of divmodL
   806 RegMask Matcher::modL_proj_mask() {
   807   ShouldNotReachHere();
   808   return RegMask();
   809 }
   811 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
   812   return FP_REG_mask();
   813 }
   815 // MIPS doesn't support AES intrinsics
   816 const bool Matcher::pass_original_key_for_aes() {
   817   return false;
   818 }
   820 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
   821   //lui
   822   //ori
   823   //dsll
   824   //ori
   826   //jalr
   827   //nop
   829   return round_to(current_offset, alignment_required()) - current_offset;
   830 }
   832 int CallLeafDirectNode::compute_padding(int current_offset) const {
   833   //lui
   834   //ori
   835   //dsll
   836   //ori
   838   //jalr
   839   //nop
   841   return round_to(current_offset, alignment_required()) - current_offset;
   842 }
   844 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
   845   //lui
   846   //ori
   847   //dsll
   848   //ori
   850   //jalr
   851   //nop
   853   return round_to(current_offset, alignment_required()) - current_offset;
   854 }
   856 // If CPU can load and store mis-aligned doubles directly then no fixup is
   857 // needed.  Else we split the double into 2 integer pieces and move it
   858 // piece-by-piece.  Only happens when passing doubles into C code as the
   859 // Java calling convention forces doubles to be aligned.
   860 const bool Matcher::misaligned_doubles_ok = false;
   861 // Do floats take an entire double register or just half?
   862 //const bool Matcher::float_in_double = true;
   863 bool Matcher::float_in_double() { return false; }
   864 // Threshold size for cleararray.
   865 const int Matcher::init_array_short_size = 8 * BytesPerLong;
   866 // Do ints take an entire long register or just half?
   867 const bool Matcher::int_in_long = true;
   868 // Is it better to copy float constants, or load them directly from memory?
   869 // Intel can load a float constant from a direct address, requiring no
   870 // extra registers.  Most RISCs will have to materialize an address into a
   871 // register first, so they would do better to copy the constant from stack.
   872 const bool Matcher::rematerialize_float_constants = false;
   873 // Advertise here if the CPU requires explicit rounding operations
   874 // to implement the UseStrictFP mode.
   875 const bool Matcher::strict_fp_requires_explicit_rounding = false;
   876 // The ecx parameter to rep stos for the ClearArray node is in dwords.
   877 const bool Matcher::init_array_count_is_in_bytes = false;
   880 // Indicate if the safepoint node needs the polling page as an input.
   881 // Since MIPS doesn't have absolute addressing, it needs.
   882 bool SafePointNode::needs_polling_address_input() {
   883   return false;
   884 }
   886 // !!!!! Special hack to get all type of calls to specify the byte offset
   887 //       from the start of the call to the point where the return address
   888 //       will point.
   889 int MachCallStaticJavaNode::ret_addr_offset() {
   890   //lui
   891   //ori
   892   //nop
   893   //nop
   894   //jalr
   895   //nop
   896   return 24;
   897 }
   899 int MachCallDynamicJavaNode::ret_addr_offset() {
   900   //lui IC_Klass,
   901   //ori IC_Klass,
   902   //dsll IC_Klass
   903   //ori IC_Klass
   905   //lui T9
   906   //ori T9
   907   //nop
   908   //nop
   909   //jalr T9
   910   //nop
   911   return 4 * 4 + 4 * 6;
   912 }
   914 //=============================================================================
   916 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
   917 enum RC { rc_bad, rc_int, rc_float, rc_stack };
   918 static enum RC rc_class( OptoReg::Name reg ) {
   919   if( !OptoReg::is_valid(reg)  ) return rc_bad;
   920   if (OptoReg::is_stack(reg)) return rc_stack;
   921   VMReg r = OptoReg::as_VMReg(reg);
   922   if (r->is_Register()) return rc_int;
   923   assert(r->is_FloatRegister(), "must be");
   924   return rc_float;
   925 }
   927 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
   928   // Get registers to move
   929   OptoReg::Name src_second = ra_->get_reg_second(in(1));
   930   OptoReg::Name src_first = ra_->get_reg_first(in(1));
   931   OptoReg::Name dst_second = ra_->get_reg_second(this );
   932   OptoReg::Name dst_first = ra_->get_reg_first(this );
   934   enum RC src_second_rc = rc_class(src_second);
   935   enum RC src_first_rc = rc_class(src_first);
   936   enum RC dst_second_rc = rc_class(dst_second);
   937   enum RC dst_first_rc = rc_class(dst_first);
   939   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
   941   // Generate spill code!
   942   int size = 0;
   944   if( src_first == dst_first && src_second == dst_second )
   945     return 0;            // Self copy, no move
   947   if (src_first_rc == rc_stack) {
   948     // mem ->
   949     if (dst_first_rc == rc_stack) {
   950       // mem -> mem
   951       assert(src_second != dst_first, "overlap");
   952       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   953           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   954         // 64-bit
   955         int src_offset = ra_->reg2offset(src_first);
   956         int dst_offset = ra_->reg2offset(dst_first);
   957         if (cbuf) {
   958           MacroAssembler _masm(cbuf);
   959           __ ld(AT, Address(SP, src_offset));
   960           __ sd(AT, Address(SP, dst_offset));
   961 #ifndef PRODUCT
   962         } else {
   963           if(!do_size){
   964             if (size != 0) st->print("\n\t");
   965               st->print("ld    AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
   966                         "sd    AT, [SP + #%d]",
   967                         src_offset, dst_offset);
   968           }
   969 #endif
   970         }
   971         size += 8;
   972       } else {
   973         // 32-bit
   974         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
   975         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
   976         // No pushl/popl, so:
   977         int src_offset = ra_->reg2offset(src_first);
   978         int dst_offset = ra_->reg2offset(dst_first);
   979         if (cbuf) {
   980           MacroAssembler _masm(cbuf);
   981           __ lw(AT, Address(SP, src_offset));
   982           __ sw(AT, Address(SP, dst_offset));
   983 #ifndef PRODUCT
   984         } else {
   985           if(!do_size){
   986             if (size != 0) st->print("\n\t");
   987               st->print("lw    AT, [SP + #%d] spill 2\n\t"
   988                         "sw    AT, [SP + #%d]\n\t",
   989                         src_offset, dst_offset);
   990           }
   991 #endif
   992         }
   993         size += 8;
   994       }
   995       return size;
   996     } else if (dst_first_rc == rc_int) {
   997       // mem -> gpr
   998       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   999           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1000         // 64-bit
  1001         int offset = ra_->reg2offset(src_first);
  1002         if (cbuf) {
  1003           MacroAssembler _masm(cbuf);
  1004           __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1005 #ifndef PRODUCT
  1006         } else {
  1007           if(!do_size){
  1008             if (size != 0) st->print("\n\t");
  1009               st->print("ld    %s, [SP + #%d]\t# spill 3",
  1010                         Matcher::regName[dst_first],
  1011                         offset);
  1013 #endif
  1015         size += 4;
  1016       } else {
  1017         // 32-bit
  1018         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1019         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1020         int offset = ra_->reg2offset(src_first);
  1021         if (cbuf) {
  1022           MacroAssembler _masm(cbuf);
  1023           if (this->ideal_reg() == Op_RegI)
  1024             __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1025           else
  1026             __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1027 #ifndef PRODUCT
  1028           } else {
  1029             if(!do_size){
  1030               if (size != 0) st->print("\n\t");
  1031               if (this->ideal_reg() == Op_RegI)
  1032                 st->print("lw    %s, [SP + #%d]\t# spill 4",
  1033                           Matcher::regName[dst_first],
  1034                           offset);
  1035               else
  1036                 st->print("lwu    %s, [SP + #%d]\t# spill 5",
  1037                           Matcher::regName[dst_first],
  1038                           offset);
  1040 #endif
  1042           size += 4;
  1044       return size;
  1045     } else if (dst_first_rc == rc_float) {
  1046       // mem-> xmm
  1047       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1048           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1049         // 64-bit
  1050         int offset = ra_->reg2offset(src_first);
  1051         if (cbuf) {
  1052           MacroAssembler _masm(cbuf);
  1053           __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1054 #ifndef PRODUCT
  1055         } else {
  1056           if (!do_size) {
  1057             if (size != 0) st->print("\n\t");
  1058             st->print("ldc1  %s, [SP + #%d]\t# spill 6",
  1059                       Matcher::regName[dst_first],
  1060                       offset);
  1062 #endif
  1064         size += 4;
  1065       } else {
  1066         // 32-bit
  1067         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1068         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1069         int offset = ra_->reg2offset(src_first);
  1070         if (cbuf) {
  1071           MacroAssembler _masm(cbuf);
  1072           __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1073 #ifndef PRODUCT
  1074         } else {
  1075           if(!do_size){
  1076             if (size != 0) st->print("\n\t");
  1077             st->print("lwc1   %s, [SP + #%d]\t# spill 7",
  1078                       Matcher::regName[dst_first],
  1079                       offset);
  1081 #endif
  1083         size += 4;
  1085       return size;
  1087   } else if (src_first_rc == rc_int) {
  1088     // gpr ->
  1089     if (dst_first_rc == rc_stack) {
  1090       // gpr -> mem
  1091       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1092           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1093         // 64-bit
  1094         int offset = ra_->reg2offset(dst_first);
  1095         if (cbuf) {
  1096           MacroAssembler _masm(cbuf);
  1097           __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1098 #ifndef PRODUCT
  1099         } else {
  1100           if(!do_size){
  1101             if (size != 0) st->print("\n\t");
  1102             st->print("sd    %s, [SP + #%d] # spill 8",
  1103                       Matcher::regName[src_first],
  1104                       offset);
  1106 #endif
  1108         size += 4;
  1109       } else {
  1110         // 32-bit
  1111         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1112         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1113         int offset = ra_->reg2offset(dst_first);
  1114         if (cbuf) {
  1115           MacroAssembler _masm(cbuf);
  1116           __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1117 #ifndef PRODUCT
  1118         } else {
  1119           if (!do_size) {
  1120             if (size != 0) st->print("\n\t");
  1121             st->print("sw    %s, [SP + #%d]\t# spill 9",
  1122                       Matcher::regName[src_first], offset);
  1124 #endif
  1126         size += 4;
  1128       return size;
  1129     } else if (dst_first_rc == rc_int) {
  1130       // gpr -> gpr
  1131       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1132           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1133         // 64-bit
  1134         if (cbuf) {
  1135           MacroAssembler _masm(cbuf);
  1136           __ move(as_Register(Matcher::_regEncode[dst_first]),
  1137                   as_Register(Matcher::_regEncode[src_first]));
  1138 #ifndef PRODUCT
  1139         } else {
  1140           if(!do_size){
  1141             if (size != 0) st->print("\n\t");
  1142             st->print("move(64bit)    %s <-- %s\t# spill 10",
  1143                       Matcher::regName[dst_first],
  1144                       Matcher::regName[src_first]);
  1146 #endif
  1148         size += 4;
  1149         return size;
  1150       } else {
  1151         // 32-bit
  1152         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1153         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1154         if (cbuf) {
  1155           MacroAssembler _masm(cbuf);
  1156           if (this->ideal_reg() == Op_RegI)
  1157               __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
  1158           else
  1159               __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
  1160 #ifndef PRODUCT
  1161         } else {
  1162           if (!do_size) {
  1163             if (size != 0) st->print("\n\t");
  1164             st->print("move(32-bit)    %s <-- %s\t# spill 11",
  1165                       Matcher::regName[dst_first],
  1166                       Matcher::regName[src_first]);
  1168 #endif
  1170         size += 4;
  1171         return size;
  1173     } else if (dst_first_rc == rc_float) {
  1174       // gpr -> xmm
  1175       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1176           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1177         // 64-bit
  1178         if (cbuf) {
  1179           MacroAssembler _masm(cbuf);
  1180           __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
  1181 #ifndef PRODUCT
  1182         } else {
  1183           if(!do_size){
  1184             if (size != 0) st->print("\n\t");
  1185             st->print("dmtc1   %s, %s\t# spill 12",
  1186                       Matcher::regName[dst_first],
  1187                       Matcher::regName[src_first]);
  1189 #endif
  1191         size += 4;
  1192       } else {
  1193         // 32-bit
  1194         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1195         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1196         if (cbuf) {
  1197           MacroAssembler _masm(cbuf);
  1198           __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
  1199 #ifndef PRODUCT
  1200         } else {
  1201           if(!do_size){
  1202             if (size != 0) st->print("\n\t");
  1203             st->print("mtc1   %s, %s\t# spill 13",
  1204                       Matcher::regName[dst_first],
  1205                       Matcher::regName[src_first]);
  1207 #endif
  1209         size += 4;
  1211       return size;
  1213   } else if (src_first_rc == rc_float) {
  1214     // xmm ->
  1215     if (dst_first_rc == rc_stack) {
  1216       // xmm -> mem
  1217       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1218           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1219         // 64-bit
  1220         int offset = ra_->reg2offset(dst_first);
  1221         if (cbuf) {
  1222           MacroAssembler _masm(cbuf);
  1223           __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
  1224 #ifndef PRODUCT
  1225         } else {
  1226           if(!do_size){
  1227             if (size != 0) st->print("\n\t");
  1228             st->print("sdc1   %s, [SP + #%d]\t# spill 14",
  1229                       Matcher::regName[src_first],
  1230                       offset);
  1232 #endif
  1234         size += 4;
  1235       } else {
  1236         // 32-bit
  1237         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1238         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1239         int offset = ra_->reg2offset(dst_first);
  1240         if (cbuf) {
  1241           MacroAssembler _masm(cbuf);
  1242           __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
  1243 #ifndef PRODUCT
  1244         } else {
  1245           if(!do_size){
  1246             if (size != 0) st->print("\n\t");
  1247             st->print("swc1   %s, [SP + #%d]\t# spill 15",
  1248                       Matcher::regName[src_first],
  1249                       offset);
  1251 #endif
  1253         size += 4;
  1255       return size;
  1256     } else if (dst_first_rc == rc_int) {
  1257       // xmm -> gpr
  1258       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1259           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1260         // 64-bit
  1261         if (cbuf) {
  1262           MacroAssembler _masm(cbuf);
  1263           __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1264 #ifndef PRODUCT
  1265         } else {
  1266           if(!do_size){
  1267             if (size != 0) st->print("\n\t");
  1268             st->print("dmfc1   %s, %s\t# spill 16",
  1269                       Matcher::regName[dst_first],
  1270                       Matcher::regName[src_first]);
  1272 #endif
  1274         size += 4;
  1275       } else {
  1276         // 32-bit
  1277         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1278         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1279         if (cbuf) {
  1280           MacroAssembler _masm(cbuf);
  1281           __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1282 #ifndef PRODUCT
  1283         } else {
  1284       if(!do_size){
  1285             if (size != 0) st->print("\n\t");
  1286             st->print("mfc1   %s, %s\t# spill 17",
  1287                       Matcher::regName[dst_first],
  1288                       Matcher::regName[src_first]);
  1290 #endif
  1292         size += 4;
  1294       return size;
  1295     } else if (dst_first_rc == rc_float) {
  1296       // xmm -> xmm
  1297       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1298           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1299         // 64-bit
  1300         if (cbuf) {
  1301           MacroAssembler _masm(cbuf);
  1302           __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1303 #ifndef PRODUCT
  1304         } else {
  1305           if(!do_size){
  1306             if (size != 0) st->print("\n\t");
  1307             st->print("mov_d  %s <-- %s\t# spill 18",
  1308                       Matcher::regName[dst_first],
  1309                       Matcher::regName[src_first]);
  1311 #endif
  1313         size += 4;
  1314       } else {
  1315         // 32-bit
  1316         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1317         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1318         if (cbuf) {
  1319           MacroAssembler _masm(cbuf);
  1320           __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1321 #ifndef PRODUCT
  1322         } else {
  1323           if(!do_size){
  1324             if (size != 0) st->print("\n\t");
  1325             st->print("mov_s  %s <-- %s\t# spill 19",
  1326                       Matcher::regName[dst_first],
  1327                       Matcher::regName[src_first]);
  1329 #endif
  1331         size += 4;
  1333       return size;
  1337   assert(0," foo ");
  1338   Unimplemented();
  1339   return size;
  1343 #ifndef PRODUCT
  1344 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1345   implementation( NULL, ra_, false, st );
  1347 #endif
  1349 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1350   implementation( &cbuf, ra_, false, NULL );
  1353 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  1354   return implementation( NULL, ra_, true, NULL );
  1357 //=============================================================================
  1360 #ifndef PRODUCT
  1361 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1362   st->print("INT3");
  1364 #endif
  1366 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
  1367   MacroAssembler _masm(&cbuf);
  1368   __ int3();
  1371 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
  1372   return MachNode::size(ra_);
  1376 //=============================================================================
  1377 #ifndef PRODUCT
  1378 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1379   Compile *C = ra_->C;
  1380   int framesize = C->frame_size_in_bytes();
  1382   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1384   st->print_cr("daddiu   SP, SP, %d # Rlease stack @ MachEpilogNode", framesize);
  1385   st->print("\t");
  1386   if (UseLoongsonISA) {
  1387     st->print_cr("gslq  RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
  1388   } else {
  1389     st->print_cr("ld    RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
  1390     st->print("\t");
  1391     st->print_cr("ld    FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
  1394   if( do_polling() && C->is_method_compilation() ) {
  1395     st->print("\t");
  1396     st->print_cr("Poll Safepoint # MachEpilogNode");
  1399 #endif
  1401 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1402   Compile *C = ra_->C;
  1403   MacroAssembler _masm(&cbuf);
  1404   int framesize = C->frame_size_in_bytes();
  1406   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1408   __ daddiu(SP, SP, framesize);
  1410   if (UseLoongsonISA) {
  1411     __ gslq(RA, FP, SP, -wordSize*2);
  1412   } else {
  1413     __ ld(RA, SP, -wordSize );
  1414     __ ld(FP, SP, -wordSize*2 );
  1417   if( do_polling() && C->is_method_compilation() ) {
  1418     __ set64(AT, (long)os::get_polling_page());
  1419     __ relocate(relocInfo::poll_return_type);
  1420     __ lw(AT, AT, 0);
  1424 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  1425   return MachNode::size(ra_); // too many variables; just compute it the hard way  fujie debug
  1428 int MachEpilogNode::reloc() const {
  1429   return 0; // a large enough number
  1432 const Pipeline * MachEpilogNode::pipeline() const {
  1433   return MachNode::pipeline_class();
  1436 int MachEpilogNode::safepoint_offset() const { return 0; }
  1438 //=============================================================================
  1440 #ifndef PRODUCT
  1441 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1442   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1443   int reg = ra_->get_reg_first(this);
  1444   st->print("ADDI %s, SP, %d   @BoxLockNode",Matcher::regName[reg],offset);
  1446 #endif
  1449 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  1450   return 4;
  1453 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1454   MacroAssembler _masm(&cbuf);
  1455   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1456   int reg = ra_->get_encode(this);
  1458   __ addi(as_Register(reg), SP, offset);
  1462 //static int sizeof_FFree_Float_Stack_All = -1;
  1464 int MachCallRuntimeNode::ret_addr_offset() {
  1465   //lui
  1466   //ori
  1467   //dsll
  1468   //ori
  1469   //jalr
  1470   //nop
  1471   assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
  1472   return NativeCall::instruction_size;
  1476 //=============================================================================
  1477 #ifndef PRODUCT
  1478 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1479   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  1481 #endif
  1483 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  1484   MacroAssembler _masm(&cbuf);
  1485   int i = 0;
  1486   for(i = 0; i < _count; i++)
  1487      __ nop();
  1490 uint MachNopNode::size(PhaseRegAlloc *) const {
  1491   return 4 * _count;
  1493 const Pipeline* MachNopNode::pipeline() const {
  1494   return MachNode::pipeline_class();
  1497 //=============================================================================
  1499 //=============================================================================
  1500 #ifndef PRODUCT
  1501 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1502   st->print_cr("load_klass(T9, T0)");
  1503   st->print_cr("\tbeq(T9, iCache, L)");
  1504   st->print_cr("\tnop");
  1505   st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
  1506   st->print_cr("\tnop");
  1507   st->print_cr("\tnop");
  1508   st->print_cr("    L:");
  1510 #endif
  1513 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1514   MacroAssembler _masm(&cbuf);
  1515 #ifdef ASSERT
  1516   //uint code_size = cbuf.code_size();
  1517 #endif
  1518   int  ic_reg = Matcher::inline_cache_reg_encode();
  1519   Label L;
  1520   Register receiver = T0;
  1521   Register   iCache = as_Register(ic_reg);
  1522   __ load_klass(T9, receiver);
  1523   __ beq(T9, iCache, L);
  1524   __ delayed()->nop();
  1526   __ relocate(relocInfo::runtime_call_type);
  1527   __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
  1529   /* WARNING these NOPs are critical so that verified entry point is properly
  1530    *      8 bytes aligned for patching by NativeJump::patch_verified_entry() */
  1531   __ align(CodeEntryAlignment);
  1532   __ bind(L);
  1535 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  1536   return MachNode::size(ra_);
  1541 //=============================================================================
  1543 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
  1545 int Compile::ConstantTable::calculate_table_base_offset() const {
  1546   return 0;  // absolute addressing, no offset
  1549 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  1550 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  1551   ShouldNotReachHere();
  1554 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  1555   Compile* C = ra_->C;
  1556   Compile::ConstantTable& constant_table = C->constant_table();
  1557   MacroAssembler _masm(&cbuf);
  1559   Register Rtoc = as_Register(ra_->get_encode(this));
  1560   CodeSection* consts_section = __ code()->consts();
  1561   int consts_size = consts_section->align_at_start(consts_section->size());
  1562   assert(constant_table.size() == consts_size, "must be equal");
  1564   if (consts_section->size()) {
  1565     // Materialize the constant table base.
  1566     address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  1567     // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  1568     __ relocate(relocInfo::internal_word_type);
  1569     __ patchable_set48(Rtoc, (long)baseaddr);
  1573 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
  1574   // patchable_set48 (4 insts)
  1575   return 4 * 4;
  1578 #ifndef PRODUCT
  1579 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  1580   Register r = as_Register(ra_->get_encode(this));
  1581   st->print("patchable_set48    %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
  1583 #endif
  1586 //=============================================================================
  1587 #ifndef PRODUCT
  1588 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1589   Compile* C = ra_->C;
  1591   int framesize = C->frame_size_in_bytes();
  1592   int bangsize = C->bang_size_in_bytes();
  1593   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1595   // Calls to C2R adapters often do not accept exceptional returns.
  1596   // We require that their callers must bang for them.  But be careful, because
  1597   // some VM calls (such as call site linkage) can use several kilobytes of
  1598   // stack.  But the stack safety zone should account for that.
  1599   // See bugs 4446381, 4468289, 4497237.
  1600   if (C->need_stack_bang(bangsize)) {
  1601     st->print_cr("# stack bang"); st->print("\t");
  1603   if (UseLoongsonISA) {
  1604     st->print("gssq     RA, FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1605   } else {
  1606     st->print("sd       RA, %d(SP)  @ MachPrologNode\n\t", -wordSize);
  1607     st->print("sd       FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1609   st->print("daddiu   FP, SP, -%d \n\t", wordSize*2);
  1610   st->print("daddiu   SP, SP, -%d \t",framesize);
  1612 #endif
  1615 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1616   Compile* C = ra_->C;
  1617   MacroAssembler _masm(&cbuf);
  1619   int framesize = C->frame_size_in_bytes();
  1620   int bangsize = C->bang_size_in_bytes();
  1622   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1624   if (C->need_stack_bang(bangsize)) {
  1625     __ generate_stack_overflow_check(bangsize);
  1628   if (UseLoongsonISA) {
  1629     __ gssq(RA, FP, SP, -wordSize*2);
  1630   } else {
  1631     __ sd(RA, SP, -wordSize);
  1632     __ sd(FP, SP, -wordSize*2);
  1634   __ daddiu(FP, SP, -wordSize*2);
  1635   __ daddiu(SP, SP, -framesize);
  1636   __ nop(); // Make enough room for patch_verified_entry()
  1637   __ nop();
  1639   C->set_frame_complete(cbuf.insts_size());
  1640   if (C->has_mach_constant_base_node()) {
  1641     // NOTE: We set the table base offset here because users might be
  1642     // emitted before MachConstantBaseNode.
  1643     Compile::ConstantTable& constant_table = C->constant_table();
  1644     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  1650 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  1651   return MachNode::size(ra_); // too many variables; just compute it the hard way
  1654 int MachPrologNode::reloc() const {
  1655   return 0; // a large enough number
  1658 %}
  1660 //----------ENCODING BLOCK-----------------------------------------------------
  1661 // This block specifies the encoding classes used by the compiler to output
  1662 // byte streams.  Encoding classes generate functions which are called by
  1663 // Machine Instruction Nodes in order to generate the bit encoding of the
  1664 // instruction.  Operands specify their base encoding interface with the
  1665 // interface keyword.  There are currently supported four interfaces,
  1666 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
  1667 // operand to generate a function which returns its register number when
  1668 // queried.   CONST_INTER causes an operand to generate a function which
  1669 // returns the value of the constant when queried.  MEMORY_INTER causes an
  1670 // operand to generate four functions which return the Base Register, the
  1671 // Index Register, the Scale Value, and the Offset Value of the operand when
  1672 // queried.  COND_INTER causes an operand to generate six functions which
  1673 // return the encoding code (ie - encoding bits for the instruction)
  1674 // associated with each basic boolean condition for a conditional instruction.
  1675 // Instructions specify two basic values for encoding.  They use the
  1676 // ins_encode keyword to specify their encoding class (which must be one of
  1677 // the class names specified in the encoding block), and they use the
  1678 // opcode keyword to specify, in order, their primary, secondary, and
  1679 // tertiary opcode.  Only the opcode sections which a particular instruction
  1680 // needs for encoding need to be specified.
  1681 encode %{
  1683   //Load byte signed
  1684   enc_class load_B_enc (mRegI dst, memory mem) %{
  1685     MacroAssembler _masm(&cbuf);
  1686     int  dst = $dst$$reg;
  1687     int  base = $mem$$base;
  1688     int  index = $mem$$index;
  1689     int  scale = $mem$$scale;
  1690     int  disp = $mem$$disp;
  1692     if( index != 0 ) {
  1693       if( Assembler::is_simm16(disp) ) {
  1694         if( UseLoongsonISA ) {
  1695           if (scale == 0) {
  1696             __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1697           } else {
  1698             __ dsll(AT, as_Register(index), scale);
  1699             __ gslbx(as_Register(dst), as_Register(base), AT, disp);
  1701         } else {
  1702           if (scale == 0) {
  1703             __ addu(AT, as_Register(base), as_Register(index));
  1704           } else {
  1705             __ dsll(AT, as_Register(index), scale);
  1706             __ addu(AT, as_Register(base), AT);
  1708           __ lb(as_Register(dst), AT, disp);
  1710       } else {
  1711         if (scale == 0) {
  1712           __ addu(AT, as_Register(base), as_Register(index));
  1713         } else {
  1714           __ dsll(AT, as_Register(index), scale);
  1715           __ addu(AT, as_Register(base), AT);
  1717         __ move(T9, disp);
  1718         if( UseLoongsonISA ) {
  1719           __ gslbx(as_Register(dst), AT, T9, 0);
  1720         } else {
  1721           __ addu(AT, AT, T9);
  1722           __ lb(as_Register(dst), AT, 0);
  1725     } else {
  1726       if( Assembler::is_simm16(disp) ) {
  1727         __ lb(as_Register(dst), as_Register(base), disp);
  1728       } else {
  1729         __ move(T9, disp);
  1730         if( UseLoongsonISA ) {
  1731           __ gslbx(as_Register(dst), as_Register(base), T9, 0);
  1732         } else {
  1733           __ addu(AT, as_Register(base), T9);
  1734           __ lb(as_Register(dst), AT, 0);
  1738   %}
  1740   //Load byte unsigned
  1741   enc_class load_UB_enc (mRegI dst, memory mem) %{
  1742     MacroAssembler _masm(&cbuf);
  1743     int  dst = $dst$$reg;
  1744     int  base = $mem$$base;
  1745     int  index = $mem$$index;
  1746     int  scale = $mem$$scale;
  1747     int  disp = $mem$$disp;
  1749     if( index != 0 ) {
  1750       if (scale == 0) {
  1751         __ daddu(AT, as_Register(base), as_Register(index));
  1752       } else {
  1753         __ dsll(AT, as_Register(index), scale);
  1754         __ daddu(AT, as_Register(base), AT);
  1756       if( Assembler::is_simm16(disp) ) {
  1757         __ lbu(as_Register(dst), AT, disp);
  1758       } else {
  1759         __ move(T9, disp);
  1760         __ daddu(AT, AT, T9);
  1761         __ lbu(as_Register(dst), AT, 0);
  1763     } else {
  1764       if( Assembler::is_simm16(disp) ) {
  1765         __ lbu(as_Register(dst), as_Register(base), disp);
  1766       } else {
  1767         __ move(T9, disp);
  1768         __ daddu(AT, as_Register(base), T9);
  1769         __ lbu(as_Register(dst), AT, 0);
  1772   %}
  1774   enc_class store_B_reg_enc (memory mem, mRegI src) %{
  1775     MacroAssembler _masm(&cbuf);
  1776     int  src = $src$$reg;
  1777     int  base = $mem$$base;
  1778     int  index = $mem$$index;
  1779     int  scale = $mem$$scale;
  1780     int  disp = $mem$$disp;
  1782     if( index != 0 ) {
  1783       if (scale == 0) {
  1784         if( Assembler::is_simm(disp, 8) ) {
  1785           if (UseLoongsonISA) {
  1786             __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
  1787           } else {
  1788             __ addu(AT, as_Register(base), as_Register(index));
  1789             __ sb(as_Register(src), AT, disp);
  1791         } else if( Assembler::is_simm16(disp) ) {
  1792           __ addu(AT, as_Register(base), as_Register(index));
  1793           __ sb(as_Register(src), AT, disp);
  1794         } else {
  1795           __ addu(AT, as_Register(base), as_Register(index));
  1796           __ move(T9, disp);
  1797           if (UseLoongsonISA) {
  1798             __ gssbx(as_Register(src), AT, T9, 0);
  1799           } else {
  1800             __ addu(AT, AT, T9);
  1801             __ sb(as_Register(src), AT, 0);
  1804       } else {
  1805         __ dsll(AT, as_Register(index), scale);
  1806         if( Assembler::is_simm(disp, 8) ) {
  1807           if (UseLoongsonISA) {
  1808             __ gssbx(as_Register(src), AT, as_Register(base), disp);
  1809           } else {
  1810             __ addu(AT, as_Register(base), AT);
  1811             __ sb(as_Register(src), AT, disp);
  1813         } else if( Assembler::is_simm16(disp) ) {
  1814           __ addu(AT, as_Register(base), AT);
  1815           __ sb(as_Register(src), AT, disp);
  1816         } else {
  1817           __ addu(AT, as_Register(base), AT);
  1818           __ move(T9, disp);
  1819           if (UseLoongsonISA) {
  1820             __ gssbx(as_Register(src), AT, T9, 0);
  1821           } else {
  1822             __ addu(AT, AT, T9);
  1823             __ sb(as_Register(src), AT, 0);
  1827     } else {
  1828       if( Assembler::is_simm16(disp) ) {
  1829         __ sb(as_Register(src), as_Register(base), disp);
  1830       } else {
  1831         __ move(T9, disp);
  1832         if (UseLoongsonISA) {
  1833           __ gssbx(as_Register(src), as_Register(base), T9, 0);
  1834         } else {
  1835           __ addu(AT, as_Register(base), T9);
  1836           __ sb(as_Register(src), AT, 0);
  1840   %}
  1842   enc_class store_B_immI_enc (memory mem, immI8 src) %{
  1843     MacroAssembler _masm(&cbuf);
  1844     int  base = $mem$$base;
  1845     int  index = $mem$$index;
  1846     int  scale = $mem$$scale;
  1847     int  disp = $mem$$disp;
  1848     int value = $src$$constant;
  1850     if( index != 0 ) {
  1851       if (!UseLoongsonISA) {
  1852         if (scale == 0) {
  1853           __ daddu(AT, as_Register(base), as_Register(index));
  1854         } else {
  1855           __ dsll(AT, as_Register(index), scale);
  1856           __ daddu(AT, as_Register(base), AT);
  1858         if( Assembler::is_simm16(disp) ) {
  1859           if (value == 0) {
  1860             __ sb(R0, AT, disp);
  1861           } else {
  1862             __ move(T9, value);
  1863             __ sb(T9, AT, disp);
  1865         } else {
  1866           if (value == 0) {
  1867             __ move(T9, disp);
  1868             __ daddu(AT, AT, T9);
  1869             __ sb(R0, AT, 0);
  1870           } else {
  1871             __ move(T9, disp);
  1872             __ daddu(AT, AT, T9);
  1873             __ move(T9, value);
  1874             __ sb(T9, AT, 0);
  1877       } else {
  1879         if (scale == 0) {
  1880           if( Assembler::is_simm(disp, 8) ) {
  1881             if (value == 0) {
  1882               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1883             } else {
  1884               __ move(T9, value);
  1885               __ gssbx(T9, as_Register(base), as_Register(index), disp);
  1887           } else if( Assembler::is_simm16(disp) ) {
  1888             __ daddu(AT, as_Register(base), as_Register(index));
  1889             if (value == 0) {
  1890               __ sb(R0, AT, disp);
  1891             } else {
  1892               __ move(T9, value);
  1893               __ sb(T9, AT, disp);
  1895           } else {
  1896             if (value == 0) {
  1897               __ daddu(AT, as_Register(base), as_Register(index));
  1898               __ move(T9, disp);
  1899               __ gssbx(R0, AT, T9, 0);
  1900             } else {
  1901               __ move(AT, disp);
  1902               __ move(T9, value);
  1903               __ daddu(AT, as_Register(base), AT);
  1904               __ gssbx(T9, AT, as_Register(index), 0);
  1908         } else {
  1910           if( Assembler::is_simm(disp, 8) ) {
  1911             __ dsll(AT, as_Register(index), scale);
  1912             if (value == 0) {
  1913               __ gssbx(R0, as_Register(base), AT, disp);
  1914             } else {
  1915               __ move(T9, value);
  1916               __ gssbx(T9, as_Register(base), AT, disp);
  1918           } else if( Assembler::is_simm16(disp) ) {
  1919             __ dsll(AT, as_Register(index), scale);
  1920             __ daddu(AT, as_Register(base), AT);
  1921             if (value == 0) {
  1922               __ sb(R0, AT, disp);
  1923             } else {
  1924               __ move(T9, value);
  1925               __ sb(T9, AT, disp);
  1927           } else {
  1928             __ dsll(AT, as_Register(index), scale);
  1929             if (value == 0) {
  1930               __ daddu(AT, as_Register(base), AT);
  1931               __ move(T9, disp);
  1932               __ gssbx(R0, AT, T9, 0);
  1933             } else {
  1934               __ move(T9, disp);
  1935               __ daddu(AT, AT, T9);
  1936               __ move(T9, value);
  1937               __ gssbx(T9, as_Register(base), AT, 0);
  1942     } else {
  1943       if( Assembler::is_simm16(disp) ) {
  1944         if (value == 0) {
  1945           __ sb(R0, as_Register(base), disp);
  1946         } else {
  1947           __ move(AT, value);
  1948           __ sb(AT, as_Register(base), disp);
  1950       } else {
  1951         if (value == 0) {
  1952           __ move(T9, disp);
  1953           if (UseLoongsonISA) {
  1954             __ gssbx(R0, as_Register(base), T9, 0);
  1955           } else {
  1956             __ daddu(AT, as_Register(base), T9);
  1957             __ sb(R0, AT, 0);
  1959         } else {
  1960           __ move(T9, disp);
  1961           if (UseLoongsonISA) {
  1962             __ move(AT, value);
  1963             __ gssbx(AT, as_Register(base), T9, 0);
  1964           } else {
  1965             __ daddu(AT, as_Register(base), T9);
  1966             __ move(T9, value);
  1967             __ sb(T9, AT, 0);
  1972   %}
  1975   enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
  1976     MacroAssembler _masm(&cbuf);
  1977     int  base = $mem$$base;
  1978     int  index = $mem$$index;
  1979     int  scale = $mem$$scale;
  1980     int  disp = $mem$$disp;
  1981     int value = $src$$constant;
  1983     if( index != 0 ) {
  1984       if ( UseLoongsonISA ) {
  1985         if ( Assembler::is_simm(disp,8) ) {
  1986           if ( scale == 0 ) {
  1987             if ( value == 0 ) {
  1988               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1989             } else {
  1990               __ move(AT, value);
  1991               __ gssbx(AT, as_Register(base), as_Register(index), disp);
  1993           } else {
  1994             __ dsll(AT, as_Register(index), scale);
  1995             if ( value == 0 ) {
  1996               __ gssbx(R0, as_Register(base), AT, disp);
  1997             } else {
  1998               __ move(T9, value);
  1999               __ gssbx(T9, as_Register(base), AT, disp);
  2002         } else if ( Assembler::is_simm16(disp) ) {
  2003           if ( scale == 0 ) {
  2004             __ daddu(AT, as_Register(base), as_Register(index));
  2005             if ( value == 0 ){
  2006               __ sb(R0, AT, disp);
  2007             } else {
  2008               __ move(T9, value);
  2009               __ sb(T9, AT, disp);
  2011           } else {
  2012             __ dsll(AT, as_Register(index), scale);
  2013             __ daddu(AT, as_Register(base), AT);
  2014             if ( value == 0 ) {
  2015               __ sb(R0, AT, disp);
  2016             } else {
  2017               __ move(T9, value);
  2018               __ sb(T9, AT, disp);
  2021         } else {
  2022           if ( scale == 0 ) {
  2023             __ move(AT, disp);
  2024             __ daddu(AT, as_Register(index), AT);
  2025             if ( value == 0 ) {
  2026               __ gssbx(R0, as_Register(base), AT, 0);
  2027             } else {
  2028               __ move(T9, value);
  2029               __ gssbx(T9, as_Register(base), AT, 0);
  2031           } else {
  2032             __ dsll(AT, as_Register(index), scale);
  2033             __ move(T9, disp);
  2034             __ daddu(AT, AT, T9);
  2035             if ( value == 0 ) {
  2036               __ gssbx(R0, as_Register(base), AT, 0);
  2037             } else {
  2038               __ move(T9, value);
  2039               __ gssbx(T9, as_Register(base), AT, 0);
  2043       } else { //not use loongson isa
  2044         if (scale == 0) {
  2045           __ daddu(AT, as_Register(base), as_Register(index));
  2046         } else {
  2047           __ dsll(AT, as_Register(index), scale);
  2048           __ daddu(AT, as_Register(base), AT);
  2050         if( Assembler::is_simm16(disp) ) {
  2051           if (value == 0) {
  2052             __ sb(R0, AT, disp);
  2053           } else {
  2054             __ move(T9, value);
  2055             __ sb(T9, AT, disp);
  2057         } else {
  2058           if (value == 0) {
  2059             __ move(T9, disp);
  2060             __ daddu(AT, AT, T9);
  2061             __ sb(R0, AT, 0);
  2062           } else {
  2063             __ move(T9, disp);
  2064             __ daddu(AT, AT, T9);
  2065             __ move(T9, value);
  2066             __ sb(T9, AT, 0);
  2070     } else {
  2071       if ( UseLoongsonISA ){
  2072         if ( Assembler::is_simm16(disp) ){
  2073           if ( value == 0 ) {
  2074             __ sb(R0, as_Register(base), disp);
  2075           } else {
  2076             __ move(AT, value);
  2077             __ sb(AT, as_Register(base), disp);
  2079         } else {
  2080           __ move(AT, disp);
  2081           if ( value == 0 ) {
  2082             __ gssbx(R0, as_Register(base), AT, 0);
  2083           } else {
  2084             __ move(T9, value);
  2085             __ gssbx(T9, as_Register(base), AT, 0);
  2088       } else {
  2089         if( Assembler::is_simm16(disp) ) {
  2090           if (value == 0) {
  2091             __ sb(R0, as_Register(base), disp);
  2092           } else {
  2093             __ move(AT, value);
  2094             __ sb(AT, as_Register(base), disp);
  2096         } else {
  2097           if (value == 0) {
  2098             __ move(T9, disp);
  2099             __ daddu(AT, as_Register(base), T9);
  2100             __ sb(R0, AT, 0);
  2101           } else {
  2102             __ move(T9, disp);
  2103             __ daddu(AT, as_Register(base), T9);
  2104             __ move(T9, value);
  2105             __ sb(T9, AT, 0);
  2111     __ sync();
  2112   %}
  2114   // Load Short (16bit signed)
  2115   enc_class load_S_enc (mRegI dst, memory mem) %{
  2116     MacroAssembler _masm(&cbuf);
  2117     int  dst = $dst$$reg;
  2118     int  base = $mem$$base;
  2119     int  index = $mem$$index;
  2120     int  scale = $mem$$scale;
  2121     int  disp = $mem$$disp;
  2123     if( index != 0 ) {
  2124       if ( UseLoongsonISA ) {
  2125         if ( Assembler::is_simm(disp, 8) ) {
  2126           if (scale == 0) {
  2127             __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2128           } else {
  2129             __ dsll(AT, as_Register(index), scale);
  2130             __ gslhx(as_Register(dst), as_Register(base), AT, disp);
  2132         } else if ( Assembler::is_simm16(disp) ) {
  2133           if (scale == 0) {
  2134             __ daddu(AT, as_Register(base), as_Register(index));
  2135             __ lh(as_Register(dst), AT, disp);
  2136           } else {
  2137             __ dsll(AT, as_Register(index), scale);
  2138             __ daddu(AT, as_Register(base), AT);
  2139             __ lh(as_Register(dst), AT, disp);
  2141         } else {
  2142           if (scale == 0) {
  2143             __ move(AT, disp);
  2144             __ daddu(AT, as_Register(index), AT);
  2145             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2146           } else {
  2147             __ dsll(AT, as_Register(index), scale);
  2148             __ move(T9, disp);
  2149             __ daddu(AT, AT, T9);
  2150             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2153       } else { // not use loongson isa
  2154         if (scale == 0) {
  2155           __ daddu(AT, as_Register(base), as_Register(index));
  2156         } else {
  2157           __ dsll(AT, as_Register(index), scale);
  2158           __ daddu(AT, as_Register(base), AT);
  2160         if( Assembler::is_simm16(disp) ) {
  2161           __ lh(as_Register(dst), AT, disp);
  2162         } else {
  2163           __ move(T9, disp);
  2164           __ daddu(AT, AT, T9);
  2165           __ lh(as_Register(dst), AT, 0);
  2168     } else { // index is 0
  2169       if ( UseLoongsonISA ) {
  2170         if ( Assembler::is_simm16(disp) ) {
  2171           __ lh(as_Register(dst), as_Register(base), disp);
  2172         } else {
  2173           __ move(T9, disp);
  2174           __ gslhx(as_Register(dst), as_Register(base), T9, 0);
  2176       } else { //not use loongson isa
  2177         if( Assembler::is_simm16(disp) ) {
  2178           __ lh(as_Register(dst), as_Register(base), disp);
  2179         } else {
  2180           __ move(T9, disp);
  2181           __ daddu(AT, as_Register(base), T9);
  2182           __ lh(as_Register(dst), AT, 0);
  2186   %}
  2188   // Load Char (16bit unsigned)
  2189   enc_class load_C_enc (mRegI dst, memory mem) %{
  2190     MacroAssembler _masm(&cbuf);
  2191     int  dst = $dst$$reg;
  2192     int  base = $mem$$base;
  2193     int  index = $mem$$index;
  2194     int  scale = $mem$$scale;
  2195     int  disp = $mem$$disp;
  2197     if( index != 0 ) {
  2198       if (scale == 0) {
  2199         __ daddu(AT, as_Register(base), as_Register(index));
  2200       } else {
  2201         __ dsll(AT, as_Register(index), scale);
  2202         __ daddu(AT, as_Register(base), AT);
  2204       if( Assembler::is_simm16(disp) ) {
  2205         __ lhu(as_Register(dst), AT, disp);
  2206       } else {
  2207         __ move(T9, disp);
  2208         __ addu(AT, AT, T9);
  2209         __ lhu(as_Register(dst), AT, 0);
  2211     } else {
  2212       if( Assembler::is_simm16(disp) ) {
  2213         __ lhu(as_Register(dst), as_Register(base), disp);
  2214       } else {
  2215         __ move(T9, disp);
  2216         __ daddu(AT, as_Register(base), T9);
  2217         __ lhu(as_Register(dst), AT, 0);
  2220   %}
  2222   // Store Char (16bit unsigned)
  2223   enc_class store_C_reg_enc (memory mem, mRegI src) %{
  2224     MacroAssembler _masm(&cbuf);
  2225     int  src = $src$$reg;
  2226     int  base = $mem$$base;
  2227     int  index = $mem$$index;
  2228     int  scale = $mem$$scale;
  2229     int  disp = $mem$$disp;
  2231     if( index != 0 ) {
  2232       if( Assembler::is_simm16(disp) ) {
  2233         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2234           if (scale == 0) {
  2235             __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
  2236           } else {
  2237             __ dsll(AT, as_Register(index), scale);
  2238             __ gsshx(as_Register(src), as_Register(base), AT, disp);
  2240         } else {
  2241           if (scale == 0) {
  2242             __ addu(AT, as_Register(base), as_Register(index));
  2243           } else {
  2244             __ dsll(AT, as_Register(index), scale);
  2245             __ addu(AT, as_Register(base), AT);
  2247           __ sh(as_Register(src), AT, disp);
  2249       } else {
  2250         if (scale == 0) {
  2251           __ addu(AT, as_Register(base), as_Register(index));
  2252         } else {
  2253           __ dsll(AT, as_Register(index), scale);
  2254           __ addu(AT, as_Register(base), AT);
  2256         __ move(T9, disp);
  2257         if( UseLoongsonISA ) {
  2258           __ gsshx(as_Register(src), AT, T9, 0);
  2259         } else {
  2260           __ addu(AT, AT, T9);
  2261           __ sh(as_Register(src), AT, 0);
  2264     } else {
  2265       if( Assembler::is_simm16(disp) ) {
  2266         __ sh(as_Register(src), as_Register(base), disp);
  2267       } else {
  2268         __ move(T9, disp);
  2269         if( UseLoongsonISA ) {
  2270           __ gsshx(as_Register(src), as_Register(base), T9, 0);
  2271         } else {
  2272           __ addu(AT, as_Register(base), T9);
  2273           __ sh(as_Register(src), AT, 0);
  2277   %}
  2279   enc_class store_C0_enc (memory mem) %{
  2280     MacroAssembler _masm(&cbuf);
  2281     int  base = $mem$$base;
  2282     int  index = $mem$$index;
  2283     int  scale = $mem$$scale;
  2284     int  disp = $mem$$disp;
  2286     if( index != 0 ) {
  2287       if( Assembler::is_simm16(disp) ) {
  2288         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2289           if (scale == 0) {
  2290             __ gsshx(R0, as_Register(base), as_Register(index), disp);
  2291           } else {
  2292             __ dsll(AT, as_Register(index), scale);
  2293             __ gsshx(R0, as_Register(base), AT, disp);
  2295         } else {
  2296           if (scale == 0) {
  2297             __ addu(AT, as_Register(base), as_Register(index));
  2298           } else {
  2299             __ dsll(AT, as_Register(index), scale);
  2300             __ addu(AT, as_Register(base), AT);
  2302           __ sh(R0, AT, disp);
  2304       } else {
  2305         if (scale == 0) {
  2306           __ addu(AT, as_Register(base), as_Register(index));
  2307         } else {
  2308           __ dsll(AT, as_Register(index), scale);
  2309           __ addu(AT, as_Register(base), AT);
  2311         __ move(T9, disp);
  2312         if( UseLoongsonISA ) {
  2313           __ gsshx(R0, AT, T9, 0);
  2314         } else {
  2315           __ addu(AT, AT, T9);
  2316           __ sh(R0, AT, 0);
  2319     } else {
  2320       if( Assembler::is_simm16(disp) ) {
  2321         __ sh(R0, as_Register(base), disp);
  2322       } else {
  2323         __ move(T9, disp);
  2324         if( UseLoongsonISA ) {
  2325           __ gsshx(R0, as_Register(base), T9, 0);
  2326         } else {
  2327           __ addu(AT, as_Register(base), T9);
  2328           __ sh(R0, AT, 0);
  2332   %}
  2334   enc_class load_I_enc (mRegI dst, memory mem) %{
  2335     MacroAssembler _masm(&cbuf);
  2336     int  dst = $dst$$reg;
  2337     int  base = $mem$$base;
  2338     int  index = $mem$$index;
  2339     int  scale = $mem$$scale;
  2340     int  disp = $mem$$disp;
  2342     if( index != 0 ) {
  2343       if( Assembler::is_simm16(disp) ) {
  2344         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2345           if (scale == 0) {
  2346             __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2347           } else {
  2348             __ dsll(AT, as_Register(index), scale);
  2349             __ gslwx(as_Register(dst), as_Register(base), AT, disp);
  2351         } else {
  2352           if (scale == 0) {
  2353             __ addu(AT, as_Register(base), as_Register(index));
  2354           } else {
  2355             __ dsll(AT, as_Register(index), scale);
  2356             __ addu(AT, as_Register(base), AT);
  2358           __ lw(as_Register(dst), AT, disp);
  2360       } else {
  2361         if (scale == 0) {
  2362           __ addu(AT, as_Register(base), as_Register(index));
  2363         } else {
  2364           __ dsll(AT, as_Register(index), scale);
  2365           __ addu(AT, as_Register(base), AT);
  2367         __ move(T9, disp);
  2368         if( UseLoongsonISA ) {
  2369           __ gslwx(as_Register(dst), AT, T9, 0);
  2370         } else {
  2371           __ addu(AT, AT, T9);
  2372           __ lw(as_Register(dst), AT, 0);
  2375     } else {
  2376       if( Assembler::is_simm16(disp) ) {
  2377         __ lw(as_Register(dst), as_Register(base), disp);
  2378       } else {
  2379         __ move(T9, disp);
  2380         if( UseLoongsonISA ) {
  2381           __ gslwx(as_Register(dst), as_Register(base), T9, 0);
  2382         } else {
  2383           __ addu(AT, as_Register(base), T9);
  2384           __ lw(as_Register(dst), AT, 0);
  2388   %}
  2390   enc_class store_I_reg_enc (memory mem, mRegI src) %{
  2391     MacroAssembler _masm(&cbuf);
  2392     int  src = $src$$reg;
  2393     int  base = $mem$$base;
  2394     int  index = $mem$$index;
  2395     int  scale = $mem$$scale;
  2396     int  disp = $mem$$disp;
  2398     if( index != 0 ) {
  2399       if( Assembler::is_simm16(disp) ) {
  2400         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2401           if (scale == 0) {
  2402             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2403           } else {
  2404             __ dsll(AT, as_Register(index), scale);
  2405             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2407         } else {
  2408           if (scale == 0) {
  2409             __ addu(AT, as_Register(base), as_Register(index));
  2410           } else {
  2411             __ dsll(AT, as_Register(index), scale);
  2412             __ addu(AT, as_Register(base), AT);
  2414           __ sw(as_Register(src), AT, disp);
  2416       } else {
  2417         if (scale == 0) {
  2418           __ addu(AT, as_Register(base), as_Register(index));
  2419         } else {
  2420           __ dsll(AT, as_Register(index), scale);
  2421           __ addu(AT, as_Register(base), AT);
  2423         __ move(T9, disp);
  2424         if( UseLoongsonISA ) {
  2425           __ gsswx(as_Register(src), AT, T9, 0);
  2426         } else {
  2427           __ addu(AT, AT, T9);
  2428           __ sw(as_Register(src), AT, 0);
  2431     } else {
  2432       if( Assembler::is_simm16(disp) ) {
  2433         __ sw(as_Register(src), as_Register(base), disp);
  2434       } else {
  2435         __ move(T9, disp);
  2436         if( UseLoongsonISA ) {
  2437           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2438         } else {
  2439           __ addu(AT, as_Register(base), T9);
  2440           __ sw(as_Register(src), AT, 0);
  2444   %}
  2446   enc_class store_I_immI_enc (memory mem, immI src) %{
  2447     MacroAssembler _masm(&cbuf);
  2448     int  base = $mem$$base;
  2449     int  index = $mem$$index;
  2450     int  scale = $mem$$scale;
  2451     int  disp = $mem$$disp;
  2452     int value = $src$$constant;
  2454     if( index != 0 ) {
  2455       if ( UseLoongsonISA ) {
  2456         if ( Assembler::is_simm(disp, 8) ) {
  2457           if ( scale == 0 ) {
  2458             if ( value == 0 ) {
  2459               __ gsswx(R0, as_Register(base), as_Register(index), disp);
  2460             } else {
  2461               __ move(T9, value);
  2462               __ gsswx(T9, as_Register(base), as_Register(index), disp);
  2464           } else {
  2465             __ dsll(AT, as_Register(index), scale);
  2466             if ( value == 0 ) {
  2467               __ gsswx(R0, as_Register(base), AT, disp);
  2468             } else {
  2469               __ move(T9, value);
  2470               __ gsswx(T9, as_Register(base), AT, disp);
  2473         } else if ( Assembler::is_simm16(disp) ) {
  2474           if ( scale == 0 ) {
  2475             __ daddu(AT, as_Register(base), as_Register(index));
  2476             if ( value == 0 ) {
  2477               __ sw(R0, AT, disp);
  2478             } else {
  2479               __ move(T9, value);
  2480               __ sw(T9, AT, disp);
  2482           } else {
  2483             __ dsll(AT, as_Register(index), scale);
  2484             __ daddu(AT, as_Register(base), AT);
  2485             if ( value == 0 ) {
  2486               __ sw(R0, AT, disp);
  2487             } else {
  2488               __ move(T9, value);
  2489               __ sw(T9, AT, disp);
  2492         } else {
  2493           if ( scale == 0 ) {
  2494             __ move(T9, disp);
  2495             __ daddu(AT, as_Register(index), T9);
  2496             if ( value ==0 ) {
  2497               __ gsswx(R0, as_Register(base), AT, 0);
  2498             } else {
  2499               __ move(T9, value);
  2500               __ gsswx(T9, as_Register(base), AT, 0);
  2502           } else {
  2503             __ dsll(AT, as_Register(index), scale);
  2504             __ move(T9, disp);
  2505             __ daddu(AT, AT, T9);
  2506             if ( value == 0 ) {
  2507               __ gsswx(R0, as_Register(base), AT, 0);
  2508             } else {
  2509               __ move(T9, value);
  2510               __ gsswx(T9, as_Register(base), AT, 0);
  2514       } else { //not use loongson isa
  2515         if (scale == 0) {
  2516           __ daddu(AT, as_Register(base), as_Register(index));
  2517         } else {
  2518           __ dsll(AT, as_Register(index), scale);
  2519           __ daddu(AT, as_Register(base), AT);
  2521         if( Assembler::is_simm16(disp) ) {
  2522           if (value == 0) {
  2523             __ sw(R0, AT, disp);
  2524           } else {
  2525             __ move(T9, value);
  2526             __ sw(T9, AT, disp);
  2528         } else {
  2529           if (value == 0) {
  2530             __ move(T9, disp);
  2531             __ daddu(AT, AT, T9);
  2532             __ sw(R0, AT, 0);
  2533           } else {
  2534             __ move(T9, disp);
  2535             __ daddu(AT, AT, T9);
  2536             __ move(T9, value);
  2537             __ sw(T9, AT, 0);
  2541     } else {
  2542       if ( UseLoongsonISA ) {
  2543         if ( Assembler::is_simm16(disp) ) {
  2544           if ( value == 0 ) {
  2545             __ sw(R0, as_Register(base), disp);
  2546           } else {
  2547             __ move(AT, value);
  2548             __ sw(AT, as_Register(base), disp);
  2550         } else {
  2551           __ move(T9, disp);
  2552           if ( value == 0 ) {
  2553             __ gsswx(R0, as_Register(base), T9, 0);
  2554           } else {
  2555             __ move(AT, value);
  2556             __ gsswx(AT, as_Register(base), T9, 0);
  2559       } else {
  2560         if( Assembler::is_simm16(disp) ) {
  2561           if (value == 0) {
  2562             __ sw(R0, as_Register(base), disp);
  2563           } else {
  2564             __ move(AT, value);
  2565             __ sw(AT, as_Register(base), disp);
  2567         } else {
  2568           if (value == 0) {
  2569             __ move(T9, disp);
  2570             __ daddu(AT, as_Register(base), T9);
  2571             __ sw(R0, AT, 0);
  2572           } else {
  2573             __ move(T9, disp);
  2574             __ daddu(AT, as_Register(base), T9);
  2575             __ move(T9, value);
  2576             __ sw(T9, AT, 0);
  2581   %}
  2583   enc_class load_N_enc (mRegN dst, memory mem) %{
  2584     MacroAssembler _masm(&cbuf);
  2585     int  dst = $dst$$reg;
  2586     int  base = $mem$$base;
  2587     int  index = $mem$$index;
  2588     int  scale = $mem$$scale;
  2589     int  disp = $mem$$disp;
  2590     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2591     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2593     if( index != 0 ) {
  2594       if (scale == 0) {
  2595         __ daddu(AT, as_Register(base), as_Register(index));
  2596       } else {
  2597         __ dsll(AT, as_Register(index), scale);
  2598         __ daddu(AT, as_Register(base), AT);
  2600       if( Assembler::is_simm16(disp) ) {
  2601         __ lwu(as_Register(dst), AT, disp);
  2602       } else {
  2603         __ set64(T9, disp);
  2604         __ daddu(AT, AT, T9);
  2605         __ lwu(as_Register(dst), AT, 0);
  2607     } else {
  2608       if( Assembler::is_simm16(disp) ) {
  2609         __ lwu(as_Register(dst), as_Register(base), disp);
  2610       } else {
  2611         __ set64(T9, disp);
  2612         __ daddu(AT, as_Register(base), T9);
  2613         __ lwu(as_Register(dst), AT, 0);
  2616   %}
  2619   enc_class load_P_enc (mRegP dst, memory mem) %{
  2620     MacroAssembler _masm(&cbuf);
  2621     int  dst = $dst$$reg;
  2622     int  base = $mem$$base;
  2623     int  index = $mem$$index;
  2624     int  scale = $mem$$scale;
  2625     int  disp = $mem$$disp;
  2626     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2627     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2629     if( index != 0 ) {
  2630       if ( UseLoongsonISA ) {
  2631         if ( Assembler::is_simm(disp, 8) ) {
  2632           if ( scale != 0 ) {
  2633             __ dsll(AT, as_Register(index), scale);
  2634             __ gsldx(as_Register(dst), as_Register(base), AT, disp);
  2635           } else {
  2636             __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2638         } else if ( Assembler::is_simm16(disp) ){
  2639           if ( scale != 0 ) {
  2640             __ dsll(AT, as_Register(index), scale);
  2641             __ daddu(AT, AT, as_Register(base));
  2642           } else {
  2643             __ daddu(AT, as_Register(index), as_Register(base));
  2645           __ ld(as_Register(dst), AT, disp);
  2646         } else {
  2647           if ( scale != 0 ) {
  2648             __ dsll(AT, as_Register(index), scale);
  2649             __ move(T9, disp);
  2650             __ daddu(AT, AT, T9);
  2651           } else {
  2652             __ move(T9, disp);
  2653             __ daddu(AT, as_Register(index), T9);
  2655           __ gsldx(as_Register(dst), as_Register(base), AT, 0);
  2657       } else { //not use loongson isa
  2658         if (scale == 0) {
  2659           __ daddu(AT, as_Register(base), as_Register(index));
  2660         } else {
  2661           __ dsll(AT, as_Register(index), scale);
  2662           __ daddu(AT, as_Register(base), AT);
  2664         if( Assembler::is_simm16(disp) ) {
  2665           __ ld(as_Register(dst), AT, disp);
  2666         } else {
  2667           __ set64(T9, disp);
  2668           __ daddu(AT, AT, T9);
  2669           __ ld(as_Register(dst), AT, 0);
  2672     } else {
  2673       if ( UseLoongsonISA ) {
  2674         if ( Assembler::is_simm16(disp) ){
  2675           __ ld(as_Register(dst), as_Register(base), disp);
  2676         } else {
  2677           __ set64(T9, disp);
  2678           __ gsldx(as_Register(dst), as_Register(base), T9, 0);
  2680       } else { //not use loongson isa
  2681         if( Assembler::is_simm16(disp) ) {
  2682           __ ld(as_Register(dst), as_Register(base), disp);
  2683         } else {
  2684           __ set64(T9, disp);
  2685           __ daddu(AT, as_Register(base), T9);
  2686           __ ld(as_Register(dst), AT, 0);
  2690   %}
  2692   enc_class store_P_reg_enc (memory mem, mRegP src) %{
  2693     MacroAssembler _masm(&cbuf);
  2694     int  src = $src$$reg;
  2695     int  base = $mem$$base;
  2696     int  index = $mem$$index;
  2697     int  scale = $mem$$scale;
  2698     int  disp = $mem$$disp;
  2700     if( index != 0 ) {
  2701       if ( UseLoongsonISA ){
  2702         if ( Assembler::is_simm(disp, 8) ) {
  2703           if ( scale == 0 ) {
  2704             __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
  2705           } else {
  2706             __ dsll(AT, as_Register(index), scale);
  2707             __ gssdx(as_Register(src), as_Register(base), AT, disp);
  2709         } else if ( Assembler::is_simm16(disp) ) {
  2710           if ( scale == 0 ) {
  2711             __ daddu(AT, as_Register(base), as_Register(index));
  2712           } else {
  2713             __ dsll(AT, as_Register(index), scale);
  2714             __ daddu(AT, as_Register(base), AT);
  2716           __ sd(as_Register(src), AT, disp);
  2717         } else {
  2718           if ( scale == 0 ) {
  2719             __ move(T9, disp);
  2720             __ daddu(AT, as_Register(index), T9);
  2721           } else {
  2722             __ dsll(AT, as_Register(index), scale);
  2723             __ move(T9, disp);
  2724             __ daddu(AT, AT, T9);
  2726           __ gssdx(as_Register(src), as_Register(base), AT, 0);
  2728       } else { //not use loongson isa
  2729         if (scale == 0) {
  2730           __ daddu(AT, as_Register(base), as_Register(index));
  2731         } else {
  2732           __ dsll(AT, as_Register(index), scale);
  2733           __ daddu(AT, as_Register(base), AT);
  2735         if( Assembler::is_simm16(disp) ) {
  2736           __ sd(as_Register(src), AT, disp);
  2737         } else {
  2738           __ move(T9, disp);
  2739           __ daddu(AT, AT, T9);
  2740           __ sd(as_Register(src), AT, 0);
  2743     } else {
  2744       if ( UseLoongsonISA ) {
  2745         if ( Assembler::is_simm16(disp) ) {
  2746           __ sd(as_Register(src), as_Register(base), disp);
  2747         } else {
  2748           __ move(T9, disp);
  2749           __ gssdx(as_Register(src), as_Register(base), T9, 0);
  2751       } else {
  2752         if( Assembler::is_simm16(disp) ) {
  2753           __ sd(as_Register(src), as_Register(base), disp);
  2754         } else {
  2755           __ move(T9, disp);
  2756           __ daddu(AT, as_Register(base), T9);
  2757           __ sd(as_Register(src), AT, 0);
  2761   %}
  2763   enc_class store_N_reg_enc (memory mem, mRegN src) %{
  2764     MacroAssembler _masm(&cbuf);
  2765     int  src = $src$$reg;
  2766     int  base = $mem$$base;
  2767     int  index = $mem$$index;
  2768     int  scale = $mem$$scale;
  2769     int  disp = $mem$$disp;
  2771     if( index != 0 ) {
  2772       if ( UseLoongsonISA ){
  2773         if ( Assembler::is_simm(disp, 8) ) {
  2774           if ( scale == 0 ) {
  2775             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2776           } else {
  2777             __ dsll(AT, as_Register(index), scale);
  2778             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2780         } else if ( Assembler::is_simm16(disp) ) {
  2781           if ( scale == 0 ) {
  2782             __ daddu(AT, as_Register(base), as_Register(index));
  2783           } else {
  2784             __ dsll(AT, as_Register(index), scale);
  2785             __ daddu(AT, as_Register(base), AT);
  2787           __ sw(as_Register(src), AT, disp);
  2788         } else {
  2789           if ( scale == 0 ) {
  2790             __ move(T9, disp);
  2791             __ daddu(AT, as_Register(index), T9);
  2792           } else {
  2793             __ dsll(AT, as_Register(index), scale);
  2794             __ move(T9, disp);
  2795             __ daddu(AT, AT, T9);
  2797           __ gsswx(as_Register(src), as_Register(base), AT, 0);
  2799       } else { //not use loongson isa
  2800         if (scale == 0) {
  2801           __ daddu(AT, as_Register(base), as_Register(index));
  2802         } else {
  2803           __ dsll(AT, as_Register(index), scale);
  2804           __ daddu(AT, as_Register(base), AT);
  2806         if( Assembler::is_simm16(disp) ) {
  2807           __ sw(as_Register(src), AT, disp);
  2808         } else {
  2809           __ move(T9, disp);
  2810           __ daddu(AT, AT, T9);
  2811           __ sw(as_Register(src), AT, 0);
  2814     } else {
  2815       if ( UseLoongsonISA ) {
  2816         if ( Assembler::is_simm16(disp) ) {
  2817           __ sw(as_Register(src), as_Register(base), disp);
  2818         } else {
  2819           __ move(T9, disp);
  2820           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2822       } else {
  2823         if( Assembler::is_simm16(disp) ) {
  2824           __ sw(as_Register(src), as_Register(base), disp);
  2825         } else {
  2826           __ move(T9, disp);
  2827           __ daddu(AT, as_Register(base), T9);
  2828           __ sw(as_Register(src), AT, 0);
  2832   %}
  2834   enc_class store_P_immP0_enc (memory mem) %{
  2835     MacroAssembler _masm(&cbuf);
  2836     int  base = $mem$$base;
  2837     int  index = $mem$$index;
  2838     int  scale = $mem$$scale;
  2839     int  disp = $mem$$disp;
  2841     if( index != 0 ) {
  2842       if (scale == 0) {
  2843         if( Assembler::is_simm16(disp) ) {
  2844           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2845             __ gssdx(R0, as_Register(base), as_Register(index), disp);
  2846           } else {
  2847             __ daddu(AT, as_Register(base), as_Register(index));
  2848             __ sd(R0, AT, disp);
  2850         } else {
  2851           __ daddu(AT, as_Register(base), as_Register(index));
  2852           __ move(T9, disp);
  2853           if(UseLoongsonISA) {
  2854             __ gssdx(R0, AT, T9, 0);
  2855           } else {
  2856             __ daddu(AT, AT, T9);
  2857             __ sd(R0, AT, 0);
  2860       } else {
  2861         __ dsll(AT, as_Register(index), scale);
  2862         if( Assembler::is_simm16(disp) ) {
  2863           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2864             __ gssdx(R0, as_Register(base), AT, disp);
  2865           } else {
  2866             __ daddu(AT, as_Register(base), AT);
  2867             __ sd(R0, AT, disp);
  2869         } else {
  2870           __ daddu(AT, as_Register(base), AT);
  2871           __ move(T9, disp);
  2872           if (UseLoongsonISA) {
  2873             __ gssdx(R0, AT, T9, 0);
  2874           } else {
  2875             __ daddu(AT, AT, T9);
  2876             __ sd(R0, AT, 0);
  2880     } else {
  2881       if( Assembler::is_simm16(disp) ) {
  2882         __ sd(R0, as_Register(base), disp);
  2883       } else {
  2884         __ move(T9, disp);
  2885         if (UseLoongsonISA) {
  2886           __ gssdx(R0, as_Register(base), T9, 0);
  2887         } else {
  2888           __ daddu(AT, as_Register(base), T9);
  2889           __ sd(R0, AT, 0);
  2893   %}
  2895   enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
  2896     MacroAssembler _masm(&cbuf);
  2897     int  base = $mem$$base;
  2898     int  index = $mem$$index;
  2899     int  scale = $mem$$scale;
  2900     int  disp = $mem$$disp;
  2902     if(index!=0){
  2903       if (scale == 0) {
  2904         __ daddu(AT, as_Register(base), as_Register(index));
  2905       } else {
  2906         __ dsll(AT, as_Register(index), scale);
  2907         __ daddu(AT, as_Register(base), AT);
  2910       if( Assembler::is_simm16(disp) ) {
  2911         __ sw(R0, AT, disp);
  2912       } else {
  2913         __ move(T9, disp);
  2914         __ daddu(AT, AT, T9);
  2915         __ sw(R0, AT, 0);
  2917     } else {
  2918       if( Assembler::is_simm16(disp) ) {
  2919         __ sw(R0, as_Register(base), disp);
  2920       } else {
  2921         __ move(T9, disp);
  2922         __ daddu(AT, as_Register(base), T9);
  2923         __ sw(R0, AT, 0);
  2926   %}
  2928   enc_class load_L_enc (mRegL dst, memory mem) %{
  2929     MacroAssembler _masm(&cbuf);
  2930     int  base = $mem$$base;
  2931     int  index = $mem$$index;
  2932     int  scale = $mem$$scale;
  2933     int  disp = $mem$$disp;
  2934     Register  dst_reg = as_Register($dst$$reg);
  2936     if( index != 0 ) {
  2937       if (scale == 0) {
  2938         __ daddu(AT, as_Register(base), as_Register(index));
  2939       } else {
  2940         __ dsll(AT, as_Register(index), scale);
  2941         __ daddu(AT, as_Register(base), AT);
  2943       if( Assembler::is_simm16(disp) ) {
  2944         __ ld(dst_reg, AT, disp);
  2945       } else {
  2946         __ move(T9, disp);
  2947         __ daddu(AT, AT, T9);
  2948         __ ld(dst_reg, AT, 0);
  2950     } else {
  2951       if( Assembler::is_simm16(disp) ) {
  2952         __ ld(dst_reg, as_Register(base), disp);
  2953       } else {
  2954         __ move(T9, disp);
  2955         __ daddu(AT, as_Register(base), T9);
  2956         __ ld(dst_reg, AT, 0);
  2959   %}
  2961   enc_class store_L_reg_enc (memory mem, mRegL src) %{
  2962     MacroAssembler _masm(&cbuf);
  2963     int  base = $mem$$base;
  2964     int  index = $mem$$index;
  2965     int  scale = $mem$$scale;
  2966     int  disp = $mem$$disp;
  2967     Register  src_reg = as_Register($src$$reg);
  2969     if( index != 0 ) {
  2970       if (scale == 0) {
  2971         __ daddu(AT, as_Register(base), as_Register(index));
  2972       } else {
  2973         __ dsll(AT, as_Register(index), scale);
  2974         __ daddu(AT, as_Register(base), AT);
  2976       if( Assembler::is_simm16(disp) ) {
  2977         __ sd(src_reg, AT, disp);
  2978       } else {
  2979         __ move(T9, disp);
  2980         __ daddu(AT, AT, T9);
  2981         __ sd(src_reg, AT, 0);
  2983     } else {
  2984       if( Assembler::is_simm16(disp) ) {
  2985         __ sd(src_reg, as_Register(base), disp);
  2986       } else {
  2987         __ move(T9, disp);
  2988         __ daddu(AT, as_Register(base), T9);
  2989         __ sd(src_reg, AT, 0);
  2992   %}
  2994   enc_class store_L_immL0_enc (memory mem, immL0 src) %{
  2995     MacroAssembler _masm(&cbuf);
  2996     int  base = $mem$$base;
  2997     int  index = $mem$$index;
  2998     int  scale = $mem$$scale;
  2999     int  disp = $mem$$disp;
  3001     if( index != 0 ) {
  3002       if (scale == 0) {
  3003         __ daddu(AT, as_Register(base), as_Register(index));
  3004       } else {
  3005         __ dsll(AT, as_Register(index), scale);
  3006         __ daddu(AT, as_Register(base), AT);
  3008       if( Assembler::is_simm16(disp) ) {
  3009         __ sd(R0, AT, disp);
  3010       } else {
  3011         __ move(T9, disp);
  3012         __ addu(AT, AT, T9);
  3013         __ sd(R0, AT, 0);
  3015     } else {
  3016       if( Assembler::is_simm16(disp) ) {
  3017         __ sd(R0, as_Register(base), disp);
  3018       } else {
  3019         __ move(T9, disp);
  3020         __ addu(AT, as_Register(base), T9);
  3021         __ sd(R0, AT, 0);
  3024   %}
  3026   enc_class store_L_immL_enc (memory mem, immL src) %{
  3027     MacroAssembler _masm(&cbuf);
  3028     int  base = $mem$$base;
  3029     int  index = $mem$$index;
  3030     int  scale = $mem$$scale;
  3031     int  disp = $mem$$disp;
  3032     long  imm = $src$$constant;
  3034     if( index != 0 ) {
  3035       if (scale == 0) {
  3036         __ daddu(AT, as_Register(base), as_Register(index));
  3037       } else {
  3038         __ dsll(AT, as_Register(index), scale);
  3039         __ daddu(AT, as_Register(base), AT);
  3041       if( Assembler::is_simm16(disp) ) {
  3042         __ set64(T9, imm);
  3043         __ sd(T9, AT, disp);
  3044       } else {
  3045         __ move(T9, disp);
  3046         __ addu(AT, AT, T9);
  3047         __ set64(T9, imm);
  3048         __ sd(T9, AT, 0);
  3050     } else {
  3051       if( Assembler::is_simm16(disp) ) {
  3052         __ move(AT, as_Register(base));
  3053         __ set64(T9, imm);
  3054         __ sd(T9, AT, disp);
  3055       } else {
  3056         __ move(T9, disp);
  3057         __ addu(AT, as_Register(base), T9);
  3058         __ set64(T9, imm);
  3059         __ sd(T9, AT, 0);
  3062   %}
  3064   enc_class load_F_enc (regF dst, memory mem) %{
  3065     MacroAssembler _masm(&cbuf);
  3066     int  base = $mem$$base;
  3067     int  index = $mem$$index;
  3068     int  scale = $mem$$scale;
  3069     int  disp = $mem$$disp;
  3070     FloatRegister dst = $dst$$FloatRegister;
  3072     if( index != 0 ) {
  3073       if( Assembler::is_simm16(disp) ) {
  3074         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3075           if (scale == 0) {
  3076             __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
  3077           } else {
  3078             __ dsll(AT, as_Register(index), scale);
  3079             __ gslwxc1(dst, as_Register(base), AT, disp);
  3081         } else {
  3082           if (scale == 0) {
  3083             __ daddu(AT, as_Register(base), as_Register(index));
  3084           } else {
  3085             __ dsll(AT, as_Register(index), scale);
  3086             __ daddu(AT, as_Register(base), AT);
  3088           __ lwc1(dst, AT, disp);
  3090       } else {
  3091         if (scale == 0) {
  3092           __ daddu(AT, as_Register(base), as_Register(index));
  3093         } else {
  3094           __ dsll(AT, as_Register(index), scale);
  3095           __ daddu(AT, as_Register(base), AT);
  3097         __ move(T9, disp);
  3098         if( UseLoongsonISA ) {
  3099           __ gslwxc1(dst, AT, T9, 0);
  3100         } else {
  3101           __ daddu(AT, AT, T9);
  3102           __ lwc1(dst, AT, 0);
  3105     } else {
  3106       if( Assembler::is_simm16(disp) ) {
  3107         __ lwc1(dst, as_Register(base), disp);
  3108       } else {
  3109         __ move(T9, disp);
  3110         if( UseLoongsonISA ) {
  3111           __ gslwxc1(dst, as_Register(base), T9, 0);
  3112         } else {
  3113           __ daddu(AT, as_Register(base), T9);
  3114           __ lwc1(dst, AT, 0);
  3118   %}
  3120   enc_class store_F_reg_enc (memory mem, regF src) %{
  3121     MacroAssembler _masm(&cbuf);
  3122     int  base = $mem$$base;
  3123     int  index = $mem$$index;
  3124     int  scale = $mem$$scale;
  3125     int  disp = $mem$$disp;
  3126     FloatRegister src = $src$$FloatRegister;
  3128     if( index != 0 ) {
  3129       if( Assembler::is_simm16(disp) ) {
  3130         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3131           if (scale == 0) {
  3132             __ gsswxc1(src, as_Register(base), as_Register(index), disp);
  3133           } else {
  3134             __ dsll(AT, as_Register(index), scale);
  3135             __ gsswxc1(src, as_Register(base), AT, disp);
  3137         } else {
  3138           if (scale == 0) {
  3139             __ daddu(AT, as_Register(base), as_Register(index));
  3140           } else {
  3141             __ dsll(AT, as_Register(index), scale);
  3142             __ daddu(AT, as_Register(base), AT);
  3144           __ swc1(src, AT, disp);
  3146       } else {
  3147         if (scale == 0) {
  3148           __ daddu(AT, as_Register(base), as_Register(index));
  3149         } else {
  3150           __ dsll(AT, as_Register(index), scale);
  3151           __ daddu(AT, as_Register(base), AT);
  3153         __ move(T9, disp);
  3154         if( UseLoongsonISA ) {
  3155           __ gsswxc1(src, AT, T9, 0);
  3156         } else {
  3157           __ daddu(AT, AT, T9);
  3158           __ swc1(src, AT, 0);
  3161     } else {
  3162       if( Assembler::is_simm16(disp) ) {
  3163         __ swc1(src, as_Register(base), disp);
  3164       } else {
  3165         __ move(T9, disp);
  3166         if( UseLoongsonISA ) {
  3167           __ gsswxc1(src, as_Register(base), T9, 0);
  3168         } else {
  3169           __ daddu(AT, as_Register(base), T9);
  3170           __ swc1(src, AT, 0);
  3174   %}
  3176   enc_class load_D_enc (regD dst, memory mem) %{
  3177     MacroAssembler _masm(&cbuf);
  3178     int  base = $mem$$base;
  3179     int  index = $mem$$index;
  3180     int  scale = $mem$$scale;
  3181     int  disp = $mem$$disp;
  3182     FloatRegister dst_reg = as_FloatRegister($dst$$reg);
  3184     if( index != 0 ) {
  3185       if( Assembler::is_simm16(disp) ) {
  3186         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3187           if (scale == 0) {
  3188             __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
  3189           } else {
  3190             __ dsll(AT, as_Register(index), scale);
  3191             __ gsldxc1(dst_reg, as_Register(base), AT, disp);
  3193         } else {
  3194           if (scale == 0) {
  3195             __ daddu(AT, as_Register(base), as_Register(index));
  3196           } else {
  3197             __ dsll(AT, as_Register(index), scale);
  3198             __ daddu(AT, as_Register(base), AT);
  3200           __ ldc1(dst_reg, AT, disp);
  3202       } else {
  3203         if (scale == 0) {
  3204           __ daddu(AT, as_Register(base), as_Register(index));
  3205         } else {
  3206           __ dsll(AT, as_Register(index), scale);
  3207           __ daddu(AT, as_Register(base), AT);
  3209         __ move(T9, disp);
  3210         if( UseLoongsonISA ) {
  3211           __ gsldxc1(dst_reg, AT, T9, 0);
  3212         } else {
  3213           __ addu(AT, AT, T9);
  3214           __ ldc1(dst_reg, AT, 0);
  3217     } else {
  3218       if( Assembler::is_simm16(disp) ) {
  3219         __ ldc1(dst_reg, as_Register(base), disp);
  3220       } else {
  3221         __ move(T9, disp);
  3222         if( UseLoongsonISA ) {
  3223           __ gsldxc1(dst_reg, as_Register(base), T9, 0);
  3224         } else {
  3225           __ addu(AT, as_Register(base), T9);
  3226           __ ldc1(dst_reg, AT, 0);
  3230   %}
  3232   enc_class store_D_reg_enc (memory mem, regD src) %{
  3233     MacroAssembler _masm(&cbuf);
  3234     int  base = $mem$$base;
  3235     int  index = $mem$$index;
  3236     int  scale = $mem$$scale;
  3237     int  disp = $mem$$disp;
  3238     FloatRegister src_reg = as_FloatRegister($src$$reg);
  3240     if( index != 0 ) {
  3241       if( Assembler::is_simm16(disp) ) {
  3242         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  3243           if (scale == 0) {
  3244             __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
  3245           } else {
  3246             __ dsll(AT, as_Register(index), scale);
  3247             __ gssdxc1(src_reg, as_Register(base), AT, disp);
  3249         } else {
  3250           if (scale == 0) {
  3251             __ daddu(AT, as_Register(base), as_Register(index));
  3252           } else {
  3253             __ dsll(AT, as_Register(index), scale);
  3254             __ daddu(AT, as_Register(base), AT);
  3256           __ sdc1(src_reg, AT, disp);
  3258       } else {
  3259         if (scale == 0) {
  3260           __ daddu(AT, as_Register(base), as_Register(index));
  3261         } else {
  3262           __ dsll(AT, as_Register(index), scale);
  3263           __ daddu(AT, as_Register(base), AT);
  3265         __ move(T9, disp);
  3266         if( UseLoongsonISA ) {
  3267           __ gssdxc1(src_reg, AT, T9, 0);
  3268         } else {
  3269           __ addu(AT, AT, T9);
  3270           __ sdc1(src_reg, AT, 0);
  3273     } else {
  3274       if( Assembler::is_simm16(disp) ) {
  3275         __ sdc1(src_reg, as_Register(base), disp);
  3276       } else {
  3277         __ move(T9, disp);
  3278         if( UseLoongsonISA ) {
  3279           __ gssdxc1(src_reg, as_Register(base), T9, 0);
  3280         } else {
  3281           __ addu(AT, as_Register(base), T9);
  3282           __ sdc1(src_reg, AT, 0);
  3286   %}
  3288   enc_class Java_To_Runtime (method meth) %{    // CALL Java_To_Runtime, Java_To_Runtime_Leaf
  3289     MacroAssembler _masm(&cbuf);
  3290     // This is the instruction starting address for relocation info.
  3291     __ block_comment("Java_To_Runtime");
  3292     cbuf.set_insts_mark();
  3293     __ relocate(relocInfo::runtime_call_type);
  3295     __ patchable_call((address)$meth$$method);
  3296   %}
  3298   enc_class Java_Static_Call (method meth) %{    // JAVA STATIC CALL
  3299     // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
  3300     // who we intended to call.
  3301     MacroAssembler _masm(&cbuf);
  3302     cbuf.set_insts_mark();
  3304     if ( !_method ) {
  3305       __ relocate(relocInfo::runtime_call_type);
  3306     } else if(_optimized_virtual) {
  3307       __ relocate(relocInfo::opt_virtual_call_type);
  3308     } else {
  3309       __ relocate(relocInfo::static_call_type);
  3312     __ patchable_call((address)($meth$$method));
  3313     if( _method ) {  // Emit stub for static call
  3314       emit_java_to_interp(cbuf);
  3316   %}
  3319   /*
  3320    * [Ref: LIR_Assembler::ic_call() ]
  3321    */
  3322   enc_class Java_Dynamic_Call (method meth) %{    // JAVA DYNAMIC CALL
  3323     MacroAssembler _masm(&cbuf);
  3324     __ block_comment("Java_Dynamic_Call");
  3325     __ ic_call((address)$meth$$method);
  3326   %}
  3329   enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
  3330     Register flags = $cr$$Register;
  3331     Label  L;
  3333     MacroAssembler _masm(&cbuf);
  3335     __ addu(flags, R0, R0);
  3336     __ beq(AT, R0, L);
  3337     __ delayed()->nop();
  3338     __ move(flags, 0xFFFFFFFF);
  3339     __ bind(L);
  3340   %}
  3342   enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
  3343     Register result = $result$$Register;
  3344     Register sub    = $sub$$Register;
  3345     Register super  = $super$$Register;
  3346     Register length = $tmp$$Register;
  3347     Register tmp    = T9;
  3348     Label miss;
  3350     // result may be the same as sub
  3351     //    47c   B40: #    B21 B41 <- B20  Freq: 0.155379
  3352     //    47c     partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
  3353     //    4bc     mov   S2, NULL #@loadConP
  3354     //    4c0     beq   S1, S2, B21 #@branchConP  P=0.999999 C=-1.000000
  3355     //
  3356     MacroAssembler _masm(&cbuf);
  3357     Label done;
  3358     __ check_klass_subtype_slow_path(sub, super, length, tmp,
  3359         NULL, &miss,
  3360         /*set_cond_codes:*/ true);
  3361     // Refer to X86_64's RDI
  3362     __ move(result, 0);
  3363     __ b(done);
  3364     __ delayed()->nop();
  3366     __ bind(miss);
  3367     __ move(result, 1);
  3368     __ bind(done);
  3369   %}
  3371 %}
  3374 //---------MIPS FRAME--------------------------------------------------------------
  3375 // Definition of frame structure and management information.
  3376 //
  3377 //  S T A C K   L A Y O U T    Allocators stack-slot number
  3378 //                             |   (to get allocators register number
  3379 //  G  Owned by    |        |  v    add SharedInfo::stack0)
  3380 //  r   CALLER     |        |
  3381 //  o     |        +--------+      pad to even-align allocators stack-slot
  3382 //  w     V        |  pad0  |        numbers; owned by CALLER
  3383 //  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
  3384 //  h     ^        |   in   |  5
  3385 //        |        |  args  |  4   Holes in incoming args owned by SELF
  3386 //  |     |    old |        |  3
  3387 //  |     |     SP-+--------+----> Matcher::_old_SP, even aligned
  3388 //  v     |        |  ret   |  3   return address
  3389 //     Owned by    +--------+
  3390 //      Self       |  pad2  |  2   pad to align old SP
  3391 //        |        +--------+  1
  3392 //        |        | locks  |  0
  3393 //        |        +--------+----> SharedInfo::stack0, even aligned
  3394 //        |        |  pad1  | 11   pad to align new SP
  3395 //        |        +--------+
  3396 //        |        |        | 10
  3397 //        |        | spills |  9   spills
  3398 //        V        |        |  8   (pad0 slot for callee)
  3399 //      -----------+--------+----> Matcher::_out_arg_limit, unaligned
  3400 //        ^        |  out   |  7
  3401 //        |        |  args  |  6   Holes in outgoing args owned by CALLEE
  3402 //   Owned by  new |        |
  3403 //    Callee    SP-+--------+----> Matcher::_new_SP, even aligned
  3404 //                  |        |
  3405 //
  3406 // Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
  3407 //         known from SELF's arguments and the Java calling convention.
  3408 //         Region 6-7 is determined per call site.
  3409 // Note 2: If the calling convention leaves holes in the incoming argument
  3410 //         area, those holes are owned by SELF.  Holes in the outgoing area
  3411 //         are owned by the CALLEE.  Holes should not be nessecary in the
  3412 //         incoming area, as the Java calling convention is completely under
  3413 //         the control of the AD file.  Doubles can be sorted and packed to
  3414 //         avoid holes.  Holes in the outgoing arguments may be nessecary for
  3415 //         varargs C calling conventions.
  3416 // Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
  3417 //         even aligned with pad0 as needed.
  3418 //         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
  3419 //         region 6-11 is even aligned; it may be padded out more so that
  3420 //         the region from SP to FP meets the minimum stack alignment.
  3421 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
  3422 //         alignment.  Region 11, pad1, may be dynamically extended so that
  3423 //         SP meets the minimum alignment.
  3426 frame %{
  3428   stack_direction(TOWARDS_LOW);
  3430   // These two registers define part of the calling convention
  3431   // between compiled code and the interpreter.
  3432   // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
  3433   // for more information.
  3435   inline_cache_reg(T1);                // Inline Cache Register
  3436   interpreter_method_oop_reg(S3);      // Method Oop Register when calling interpreter
  3438   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
  3439   cisc_spilling_operand_name(indOffset32);
  3441   // Number of stack slots consumed by locking an object
  3442   // generate Compile::sync_stack_slots
  3443 #ifdef _LP64
  3444   sync_stack_slots(2);
  3445 #else
  3446   sync_stack_slots(1);
  3447 #endif
  3449   frame_pointer(SP);
  3451   // Interpreter stores its frame pointer in a register which is
  3452   // stored to the stack by I2CAdaptors.
  3453   // I2CAdaptors convert from interpreted java to compiled java.
  3455   interpreter_frame_pointer(FP);
  3457   // generate Matcher::stack_alignment
  3458   stack_alignment(StackAlignmentInBytes);  //wordSize = sizeof(char*);
  3460   // Number of stack slots between incoming argument block and the start of
  3461   // a new frame.  The PROLOG must add this many slots to the stack.  The
  3462   // EPILOG must remove this many slots.  Intel needs one slot for
  3463   // return address.
  3464   // generate Matcher::in_preserve_stack_slots
  3465   //in_preserve_stack_slots(VerifyStackAtCalls + 2);  //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
  3466   in_preserve_stack_slots(4);  //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
  3468   // Number of outgoing stack slots killed above the out_preserve_stack_slots
  3469   // for calls to C.  Supports the var-args backing area for register parms.
  3470   varargs_C_out_slots_killed(0);
  3472   // The after-PROLOG location of the return address.  Location of
  3473   // return address specifies a type (REG or STACK) and a number
  3474   // representing the register number (i.e. - use a register name) or
  3475   // stack slot.
  3476   // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
  3477   // Otherwise, it is above the locks and verification slot and alignment word
  3478   //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
  3479   return_addr(REG RA);
  3481   // Body of function which returns an integer array locating
  3482   // arguments either in registers or in stack slots.  Passed an array
  3483   // of ideal registers called "sig" and a "length" count.  Stack-slot
  3484   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  3485   // arguments for a CALLEE.  Incoming stack arguments are
  3486   // automatically biased by the preserve_stack_slots field above.
  3489   // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
  3490   // StartNode::calling_convention call this.
  3491   calling_convention %{
  3492     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
  3493   %}
  3498   // Body of function which returns an integer array locating
  3499   // arguments either in registers or in stack slots.  Passed an array
  3500   // of ideal registers called "sig" and a "length" count.  Stack-slot
  3501   // offsets are based on outgoing arguments, i.e. a CALLER setting up
  3502   // arguments for a CALLEE.  Incoming stack arguments are
  3503   // automatically biased by the preserve_stack_slots field above.
  3506   // SEE CallRuntimeNode::calling_convention for more information.
  3507   c_calling_convention %{
  3508    (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
  3509   %}
  3512   // Location of C & interpreter return values
  3513   // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
  3514   // SEE Matcher::match.
  3515   c_return_value %{
  3516     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  3517                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  3518     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,    V0_num };
  3519     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,  V0_H_num };
  3520     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  3521   %}
  3523   // Location of return values
  3524   // register(s) contain(s) return value for Op_StartC2I and Op_Start.
  3525   // SEE Matcher::match.
  3527   return_value %{
  3528     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
  3529                                /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
  3530     static int lo[Op_RegL+1] = { 0, 0, V0_num,       V0_num,       V0_num,       F0_num,       F0_num,     V0_num };
  3531     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num,     OptoReg::Bad, F0_H_num,   V0_H_num};
  3532     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
  3533   %}
  3535 %}
  3537 //----------ATTRIBUTES---------------------------------------------------------
  3538 //----------Operand Attributes-------------------------------------------------
  3539 op_attrib op_cost(0);        // Required cost attribute
  3541 //----------Instruction Attributes---------------------------------------------
  3542 ins_attrib ins_cost(100);       // Required cost attribute
  3543 ins_attrib ins_size(32);         // Required size attribute (in bits)
  3544 ins_attrib ins_pc_relative(0);  // Required PC Relative flag
  3545 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
  3546                                 // non-matching short branch variant of some
  3547                                                             // long branch?
  3548 ins_attrib ins_alignment(4);    // Required alignment attribute (must be a power of 2)
  3549                                 // specifies the alignment that some part of the instruction (not
  3550                                 // necessarily the start) requires.  If > 1, a compute_padding()
  3551                                 // function must be provided for the instruction
  3553 //----------OPERANDS-----------------------------------------------------------
  3554 // Operand definitions must precede instruction definitions for correct parsing
  3555 // in the ADLC because operands constitute user defined types which are used in
  3556 // instruction definitions.
  3558 // Vectors
  3559 operand vecD() %{
  3560   constraint(ALLOC_IN_RC(dbl_reg));
  3561   match(VecD);
  3563   format %{ %}
  3564   interface(REG_INTER);
  3565 %}
  3567 // Flags register, used as output of compare instructions
  3568 operand FlagsReg() %{
  3569   constraint(ALLOC_IN_RC(mips_flags));
  3570   match(RegFlags);
  3572   format %{ "AT" %}
  3573   interface(REG_INTER);
  3574 %}
  3576 //----------Simple Operands----------------------------------------------------
  3577 //TODO: Should we need to define some more special immediate number ?
  3578 // Immediate Operands
  3579 // Integer Immediate
  3580 operand immI() %{
  3581   match(ConI);
  3582   //TODO: should not match immI8 here LEE
  3583   match(immI8);
  3585   op_cost(20);
  3586   format %{ %}
  3587   interface(CONST_INTER);
  3588 %}
  3590 // Long Immediate 8-bit
  3591 operand immL8()
  3592 %{
  3593   predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
  3594   match(ConL);
  3596   op_cost(5);
  3597   format %{ %}
  3598   interface(CONST_INTER);
  3599 %}
  3601 // Constant for test vs zero
  3602 operand immI0() %{
  3603   predicate(n->get_int() == 0);
  3604   match(ConI);
  3606   op_cost(0);
  3607   format %{ %}
  3608   interface(CONST_INTER);
  3609 %}
  3611 // Constant for increment
  3612 operand immI1() %{
  3613   predicate(n->get_int() == 1);
  3614   match(ConI);
  3616   op_cost(0);
  3617   format %{ %}
  3618   interface(CONST_INTER);
  3619 %}
  3621 // Constant for decrement
  3622 operand immI_M1() %{
  3623   predicate(n->get_int() == -1);
  3624   match(ConI);
  3626   op_cost(0);
  3627   format %{ %}
  3628   interface(CONST_INTER);
  3629 %}
  3631 operand immI_MaxI() %{
  3632   predicate(n->get_int() == 2147483647);
  3633   match(ConI);
  3635   op_cost(0);
  3636   format %{ %}
  3637   interface(CONST_INTER);
  3638 %}
  3640 // Valid scale values for addressing modes
  3641 operand immI2() %{
  3642   predicate(0 <= n->get_int() && (n->get_int() <= 3));
  3643   match(ConI);
  3645   format %{ %}
  3646   interface(CONST_INTER);
  3647 %}
  3649 operand immI8() %{
  3650   predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
  3651   match(ConI);
  3653   op_cost(5);
  3654   format %{ %}
  3655   interface(CONST_INTER);
  3656 %}
  3658 operand immI16() %{
  3659   predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
  3660   match(ConI);
  3662   op_cost(10);
  3663   format %{ %}
  3664   interface(CONST_INTER);
  3665 %}
  3667 // Constant for long shifts
  3668 operand immI_32() %{
  3669   predicate( n->get_int() == 32 );
  3670   match(ConI);
  3672   op_cost(0);
  3673   format %{ %}
  3674   interface(CONST_INTER);
  3675 %}
  3677 operand immI_63() %{
  3678   predicate( n->get_int() == 63 );
  3679   match(ConI);
  3681   op_cost(0);
  3682   format %{ %}
  3683   interface(CONST_INTER);
  3684 %}
  3686 operand immI_0_31() %{
  3687   predicate( n->get_int() >= 0 && n->get_int() <= 31 );
  3688   match(ConI);
  3690   op_cost(0);
  3691   format %{ %}
  3692   interface(CONST_INTER);
  3693 %}
  3695 // Operand for non-negtive integer mask
  3696 operand immI_nonneg_mask() %{
  3697   predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
  3698   match(ConI);
  3700   op_cost(0);
  3701   format %{ %}
  3702   interface(CONST_INTER);
  3703 %}
  3705 operand immI_32_63() %{
  3706   predicate( n->get_int() >= 32 && n->get_int() <= 63 );
  3707   match(ConI);
  3708   op_cost(0);
  3710   format %{ %}
  3711   interface(CONST_INTER);
  3712 %}
  3714 operand immI16_sub() %{
  3715   predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
  3716   match(ConI);
  3718   op_cost(10);
  3719   format %{ %}
  3720   interface(CONST_INTER);
  3721 %}
  3723 operand immI_0_32767() %{
  3724   predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
  3725   match(ConI);
  3726   op_cost(0);
  3728   format %{ %}
  3729   interface(CONST_INTER);
  3730 %}
  3732 operand immI_0_65535() %{
  3733   predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
  3734   match(ConI);
  3735   op_cost(0);
  3737   format %{ %}
  3738   interface(CONST_INTER);
  3739 %}
  3741 operand immI_1() %{
  3742   predicate( n->get_int() == 1 );
  3743   match(ConI);
  3745   op_cost(0);
  3746   format %{ %}
  3747   interface(CONST_INTER);
  3748 %}
  3750 operand immI_2() %{
  3751   predicate( n->get_int() == 2 );
  3752   match(ConI);
  3754   op_cost(0);
  3755   format %{ %}
  3756   interface(CONST_INTER);
  3757 %}
  3759 operand immI_3() %{
  3760   predicate( n->get_int() == 3 );
  3761   match(ConI);
  3763   op_cost(0);
  3764   format %{ %}
  3765   interface(CONST_INTER);
  3766 %}
  3768 operand immI_7() %{
  3769   predicate( n->get_int() == 7 );
  3770   match(ConI);
  3772   format %{ %}
  3773   interface(CONST_INTER);
  3774 %}
  3776 // Immediates for special shifts (sign extend)
  3778 // Constants for increment
  3779 operand immI_16() %{
  3780   predicate( n->get_int() == 16 );
  3781   match(ConI);
  3783   format %{ %}
  3784   interface(CONST_INTER);
  3785 %}
  3787 operand immI_24() %{
  3788   predicate( n->get_int() == 24 );
  3789   match(ConI);
  3791   format %{ %}
  3792   interface(CONST_INTER);
  3793 %}
  3795 // Constant for byte-wide masking
  3796 operand immI_255() %{
  3797   predicate( n->get_int() == 255 );
  3798   match(ConI);
  3800   op_cost(0);
  3801   format %{ %}
  3802   interface(CONST_INTER);
  3803 %}
  3805 operand immI_65535() %{
  3806   predicate( n->get_int() == 65535 );
  3807   match(ConI);
  3809   op_cost(5);
  3810   format %{ %}
  3811   interface(CONST_INTER);
  3812 %}
  3814 operand immI_65536() %{
  3815   predicate( n->get_int() == 65536 );
  3816   match(ConI);
  3818   op_cost(5);
  3819   format %{ %}
  3820   interface(CONST_INTER);
  3821 %}
  3823 operand immI_M65536() %{
  3824   predicate( n->get_int() == -65536 );
  3825   match(ConI);
  3827   op_cost(5);
  3828   format %{ %}
  3829   interface(CONST_INTER);
  3830 %}
  3832 // Pointer Immediate
  3833 operand immP() %{
  3834   match(ConP);
  3836   op_cost(10);
  3837   format %{ %}
  3838   interface(CONST_INTER);
  3839 %}
  3841 // NULL Pointer Immediate
  3842 operand immP0() %{
  3843   predicate( n->get_ptr() == 0 );
  3844   match(ConP);
  3845   op_cost(0);
  3847   format %{ %}
  3848   interface(CONST_INTER);
  3849 %}
  3851 // Pointer Immediate: 64-bit
  3852 operand immP_set() %{
  3853   match(ConP);
  3855   op_cost(5);
  3856   // formats are generated automatically for constants and base registers
  3857   format %{ %}
  3858   interface(CONST_INTER);
  3859 %}
  3861 // Pointer Immediate: 64-bit
  3862 operand immP_load() %{
  3863   predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
  3864   match(ConP);
  3866   op_cost(5);
  3867   // formats are generated automatically for constants and base registers
  3868   format %{ %}
  3869   interface(CONST_INTER);
  3870 %}
  3872 // Pointer Immediate: 64-bit
  3873 operand immP_no_oop_cheap() %{
  3874   predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
  3875   match(ConP);
  3877   op_cost(5);
  3878   // formats are generated automatically for constants and base registers
  3879   format %{ %}
  3880   interface(CONST_INTER);
  3881 %}
  3883 // Pointer for polling page
  3884 operand immP_poll() %{
  3885   predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
  3886   match(ConP);
  3887   op_cost(5);
  3889   format %{ %}
  3890   interface(CONST_INTER);
  3891 %}
  3893 // Pointer Immediate
  3894 operand immN() %{
  3895   match(ConN);
  3897   op_cost(10);
  3898   format %{ %}
  3899   interface(CONST_INTER);
  3900 %}
  3902 operand immNKlass() %{
  3903   match(ConNKlass);
  3905   op_cost(10);
  3906   format %{ %}
  3907   interface(CONST_INTER);
  3908 %}
  3910 // NULL Pointer Immediate
  3911 operand immN0() %{
  3912   predicate(n->get_narrowcon() == 0);
  3913   match(ConN);
  3915   op_cost(5);
  3916   format %{ %}
  3917   interface(CONST_INTER);
  3918 %}
  3920 // Long Immediate
  3921 operand immL() %{
  3922   match(ConL);
  3924   op_cost(20);
  3925   format %{ %}
  3926   interface(CONST_INTER);
  3927 %}
  3929 // Long Immediate zero
  3930 operand immL0() %{
  3931   predicate( n->get_long() == 0L );
  3932   match(ConL);
  3933   op_cost(0);
  3935   format %{ %}
  3936   interface(CONST_INTER);
  3937 %}
  3939 operand immL7() %{
  3940   predicate( n->get_long() == 7L );
  3941   match(ConL);
  3942   op_cost(0);
  3944   format %{ %}
  3945   interface(CONST_INTER);
  3946 %}
  3948 operand immL_M1() %{
  3949   predicate( n->get_long() == -1L );
  3950   match(ConL);
  3951   op_cost(0);
  3953   format %{ %}
  3954   interface(CONST_INTER);
  3955 %}
  3957 // bit 0..2 zero
  3958 operand immL_M8() %{
  3959   predicate( n->get_long() == -8L );
  3960   match(ConL);
  3961   op_cost(0);
  3963   format %{ %}
  3964   interface(CONST_INTER);
  3965 %}
  3967 // bit 2 zero
  3968 operand immL_M5() %{
  3969   predicate( n->get_long() == -5L );
  3970   match(ConL);
  3971   op_cost(0);
  3973   format %{ %}
  3974   interface(CONST_INTER);
  3975 %}
  3977 // bit 1..2 zero
  3978 operand immL_M7() %{
  3979   predicate( n->get_long() == -7L );
  3980   match(ConL);
  3981   op_cost(0);
  3983   format %{ %}
  3984   interface(CONST_INTER);
  3985 %}
  3987 // bit 0..1 zero
  3988 operand immL_M4() %{
  3989   predicate( n->get_long() == -4L );
  3990   match(ConL);
  3991   op_cost(0);
  3993   format %{ %}
  3994   interface(CONST_INTER);
  3995 %}
  3997 // bit 3..6 zero
  3998 operand immL_M121() %{
  3999   predicate( n->get_long() == -121L );
  4000   match(ConL);
  4001   op_cost(0);
  4003   format %{ %}
  4004   interface(CONST_INTER);
  4005 %}
  4007 // Long immediate from 0 to 127.
  4008 // Used for a shorter form of long mul by 10.
  4009 operand immL_127() %{
  4010   predicate((0 <= n->get_long()) && (n->get_long() <= 127));
  4011   match(ConL);
  4012   op_cost(0);
  4014   format %{ %}
  4015   interface(CONST_INTER);
  4016 %}
  4018 // Operand for non-negtive long mask
  4019 operand immL_nonneg_mask() %{
  4020   predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
  4021   match(ConL);
  4023   op_cost(0);
  4024   format %{ %}
  4025   interface(CONST_INTER);
  4026 %}
  4028 operand immL_0_65535() %{
  4029   predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
  4030   match(ConL);
  4031   op_cost(0);
  4033   format %{ %}
  4034   interface(CONST_INTER);
  4035 %}
  4037 // Long Immediate: cheap (materialize in <= 3 instructions)
  4038 operand immL_cheap() %{
  4039   predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
  4040   match(ConL);
  4041   op_cost(0);
  4043   format %{ %}
  4044   interface(CONST_INTER);
  4045 %}
  4047 // Long Immediate: expensive (materialize in > 3 instructions)
  4048 operand immL_expensive() %{
  4049   predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
  4050   match(ConL);
  4051   op_cost(0);
  4053   format %{ %}
  4054   interface(CONST_INTER);
  4055 %}
  4057 operand immL16() %{
  4058   predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
  4059   match(ConL);
  4061   op_cost(10);
  4062   format %{ %}
  4063   interface(CONST_INTER);
  4064 %}
  4066 operand immL16_sub() %{
  4067   predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
  4068   match(ConL);
  4070   op_cost(10);
  4071   format %{ %}
  4072   interface(CONST_INTER);
  4073 %}
  4075 // Long Immediate: low 32-bit mask
  4076 operand immL_32bits() %{
  4077   predicate(n->get_long() == 0xFFFFFFFFL);
  4078   match(ConL);
  4079   op_cost(20);
  4081   format %{ %}
  4082   interface(CONST_INTER);
  4083 %}
  4085 // Long Immediate 32-bit signed
  4086 operand immL32()
  4087 %{
  4088   predicate(n->get_long() == (int) (n->get_long()));
  4089   match(ConL);
  4091   op_cost(15);
  4092   format %{ %}
  4093   interface(CONST_INTER);
  4094 %}
  4097 //single-precision floating-point zero
  4098 operand immF0() %{
  4099   predicate(jint_cast(n->getf()) == 0);
  4100   match(ConF);
  4102   op_cost(5);
  4103   format %{ %}
  4104   interface(CONST_INTER);
  4105 %}
  4107 //single-precision floating-point immediate
  4108 operand immF() %{
  4109   match(ConF);
  4111   op_cost(20);
  4112   format %{ %}
  4113   interface(CONST_INTER);
  4114 %}
  4116 //double-precision floating-point zero
  4117 operand immD0() %{
  4118   predicate(jlong_cast(n->getd()) == 0);
  4119   match(ConD);
  4121   op_cost(5);
  4122   format %{ %}
  4123   interface(CONST_INTER);
  4124 %}
  4126 //double-precision floating-point immediate
  4127 operand immD() %{
  4128   match(ConD);
  4130   op_cost(20);
  4131   format %{ %}
  4132   interface(CONST_INTER);
  4133 %}
  4135 // Register Operands
  4136 // Integer Register
  4137 operand mRegI() %{
  4138   constraint(ALLOC_IN_RC(int_reg));
  4139   match(RegI);
  4141   format %{ %}
  4142   interface(REG_INTER);
  4143 %}
  4145 operand no_Ax_mRegI() %{
  4146   constraint(ALLOC_IN_RC(no_Ax_int_reg));
  4147   match(RegI);
  4148   match(mRegI);
  4150   format %{  %}
  4151   interface(REG_INTER);
  4152 %}
  4154 operand mS0RegI() %{
  4155   constraint(ALLOC_IN_RC(s0_reg));
  4156   match(RegI);
  4157   match(mRegI);
  4159   format %{ "S0" %}
  4160   interface(REG_INTER);
  4161 %}
  4163 operand mS1RegI() %{
  4164   constraint(ALLOC_IN_RC(s1_reg));
  4165   match(RegI);
  4166   match(mRegI);
  4168   format %{ "S1" %}
  4169   interface(REG_INTER);
  4170 %}
  4172 operand mS2RegI() %{
  4173   constraint(ALLOC_IN_RC(s2_reg));
  4174   match(RegI);
  4175   match(mRegI);
  4177   format %{ "S2" %}
  4178   interface(REG_INTER);
  4179 %}
  4181 operand mS3RegI() %{
  4182   constraint(ALLOC_IN_RC(s3_reg));
  4183   match(RegI);
  4184   match(mRegI);
  4186   format %{ "S3" %}
  4187   interface(REG_INTER);
  4188 %}
  4190 operand mS4RegI() %{
  4191   constraint(ALLOC_IN_RC(s4_reg));
  4192   match(RegI);
  4193   match(mRegI);
  4195   format %{ "S4" %}
  4196   interface(REG_INTER);
  4197 %}
  4199 operand mS5RegI() %{
  4200   constraint(ALLOC_IN_RC(s5_reg));
  4201   match(RegI);
  4202   match(mRegI);
  4204   format %{ "S5" %}
  4205   interface(REG_INTER);
  4206 %}
  4208 operand mS6RegI() %{
  4209   constraint(ALLOC_IN_RC(s6_reg));
  4210   match(RegI);
  4211   match(mRegI);
  4213   format %{ "S6" %}
  4214   interface(REG_INTER);
  4215 %}
  4217 operand mS7RegI() %{
  4218   constraint(ALLOC_IN_RC(s7_reg));
  4219   match(RegI);
  4220   match(mRegI);
  4222   format %{ "S7" %}
  4223   interface(REG_INTER);
  4224 %}
  4227 operand mT0RegI() %{
  4228   constraint(ALLOC_IN_RC(t0_reg));
  4229   match(RegI);
  4230   match(mRegI);
  4232   format %{ "T0" %}
  4233   interface(REG_INTER);
  4234 %}
  4236 operand mT1RegI() %{
  4237   constraint(ALLOC_IN_RC(t1_reg));
  4238   match(RegI);
  4239   match(mRegI);
  4241   format %{ "T1" %}
  4242   interface(REG_INTER);
  4243 %}
  4245 operand mT2RegI() %{
  4246   constraint(ALLOC_IN_RC(t2_reg));
  4247   match(RegI);
  4248   match(mRegI);
  4250   format %{ "T2" %}
  4251   interface(REG_INTER);
  4252 %}
  4254 operand mT3RegI() %{
  4255   constraint(ALLOC_IN_RC(t3_reg));
  4256   match(RegI);
  4257   match(mRegI);
  4259   format %{ "T3" %}
  4260   interface(REG_INTER);
  4261 %}
  4263 operand mT8RegI() %{
  4264   constraint(ALLOC_IN_RC(t8_reg));
  4265   match(RegI);
  4266   match(mRegI);
  4268   format %{ "T8" %}
  4269   interface(REG_INTER);
  4270 %}
  4272 operand mT9RegI() %{
  4273   constraint(ALLOC_IN_RC(t9_reg));
  4274   match(RegI);
  4275   match(mRegI);
  4277   format %{ "T9" %}
  4278   interface(REG_INTER);
  4279 %}
  4281 operand mA0RegI() %{
  4282   constraint(ALLOC_IN_RC(a0_reg));
  4283   match(RegI);
  4284   match(mRegI);
  4286   format %{ "A0" %}
  4287   interface(REG_INTER);
  4288 %}
  4290 operand mA1RegI() %{
  4291   constraint(ALLOC_IN_RC(a1_reg));
  4292   match(RegI);
  4293   match(mRegI);
  4295   format %{ "A1" %}
  4296   interface(REG_INTER);
  4297 %}
  4299 operand mA2RegI() %{
  4300   constraint(ALLOC_IN_RC(a2_reg));
  4301   match(RegI);
  4302   match(mRegI);
  4304   format %{ "A2" %}
  4305   interface(REG_INTER);
  4306 %}
  4308 operand mA3RegI() %{
  4309   constraint(ALLOC_IN_RC(a3_reg));
  4310   match(RegI);
  4311   match(mRegI);
  4313   format %{ "A3" %}
  4314   interface(REG_INTER);
  4315 %}
  4317 operand mA4RegI() %{
  4318   constraint(ALLOC_IN_RC(a4_reg));
  4319   match(RegI);
  4320   match(mRegI);
  4322   format %{ "A4" %}
  4323   interface(REG_INTER);
  4324 %}
  4326 operand mA5RegI() %{
  4327   constraint(ALLOC_IN_RC(a5_reg));
  4328   match(RegI);
  4329   match(mRegI);
  4331   format %{ "A5" %}
  4332   interface(REG_INTER);
  4333 %}
  4335 operand mA6RegI() %{
  4336   constraint(ALLOC_IN_RC(a6_reg));
  4337   match(RegI);
  4338   match(mRegI);
  4340   format %{ "A6" %}
  4341   interface(REG_INTER);
  4342 %}
  4344 operand mA7RegI() %{
  4345   constraint(ALLOC_IN_RC(a7_reg));
  4346   match(RegI);
  4347   match(mRegI);
  4349   format %{ "A7" %}
  4350   interface(REG_INTER);
  4351 %}
  4353 operand mV0RegI() %{
  4354   constraint(ALLOC_IN_RC(v0_reg));
  4355   match(RegI);
  4356   match(mRegI);
  4358   format %{ "V0" %}
  4359   interface(REG_INTER);
  4360 %}
  4362 operand mV1RegI() %{
  4363   constraint(ALLOC_IN_RC(v1_reg));
  4364   match(RegI);
  4365   match(mRegI);
  4367   format %{ "V1" %}
  4368   interface(REG_INTER);
  4369 %}
  4371 operand mRegN() %{
  4372   constraint(ALLOC_IN_RC(int_reg));
  4373   match(RegN);
  4375   format %{ %}
  4376   interface(REG_INTER);
  4377 %}
  4379 operand t0_RegN() %{
  4380   constraint(ALLOC_IN_RC(t0_reg));
  4381   match(RegN);
  4382   match(mRegN);
  4384   format %{ %}
  4385   interface(REG_INTER);
  4386 %}
  4388 operand t1_RegN() %{
  4389   constraint(ALLOC_IN_RC(t1_reg));
  4390   match(RegN);
  4391   match(mRegN);
  4393   format %{ %}
  4394   interface(REG_INTER);
  4395 %}
  4397 operand t2_RegN() %{
  4398   constraint(ALLOC_IN_RC(t2_reg));
  4399   match(RegN);
  4400   match(mRegN);
  4402   format %{ %}
  4403   interface(REG_INTER);
  4404 %}
  4406 operand t3_RegN() %{
  4407   constraint(ALLOC_IN_RC(t3_reg));
  4408   match(RegN);
  4409   match(mRegN);
  4411   format %{ %}
  4412   interface(REG_INTER);
  4413 %}
  4415 operand t8_RegN() %{
  4416   constraint(ALLOC_IN_RC(t8_reg));
  4417   match(RegN);
  4418   match(mRegN);
  4420   format %{ %}
  4421   interface(REG_INTER);
  4422 %}
  4424 operand t9_RegN() %{
  4425   constraint(ALLOC_IN_RC(t9_reg));
  4426   match(RegN);
  4427   match(mRegN);
  4429   format %{ %}
  4430   interface(REG_INTER);
  4431 %}
  4433 operand a0_RegN() %{
  4434   constraint(ALLOC_IN_RC(a0_reg));
  4435   match(RegN);
  4436   match(mRegN);
  4438   format %{ %}
  4439   interface(REG_INTER);
  4440 %}
  4442 operand a1_RegN() %{
  4443   constraint(ALLOC_IN_RC(a1_reg));
  4444   match(RegN);
  4445   match(mRegN);
  4447   format %{ %}
  4448   interface(REG_INTER);
  4449 %}
  4451 operand a2_RegN() %{
  4452   constraint(ALLOC_IN_RC(a2_reg));
  4453   match(RegN);
  4454   match(mRegN);
  4456   format %{ %}
  4457   interface(REG_INTER);
  4458 %}
  4460 operand a3_RegN() %{
  4461   constraint(ALLOC_IN_RC(a3_reg));
  4462   match(RegN);
  4463   match(mRegN);
  4465   format %{ %}
  4466   interface(REG_INTER);
  4467 %}
  4469 operand a4_RegN() %{
  4470   constraint(ALLOC_IN_RC(a4_reg));
  4471   match(RegN);
  4472   match(mRegN);
  4474   format %{ %}
  4475   interface(REG_INTER);
  4476 %}
  4478 operand a5_RegN() %{
  4479   constraint(ALLOC_IN_RC(a5_reg));
  4480   match(RegN);
  4481   match(mRegN);
  4483   format %{ %}
  4484   interface(REG_INTER);
  4485 %}
  4487 operand a6_RegN() %{
  4488   constraint(ALLOC_IN_RC(a6_reg));
  4489   match(RegN);
  4490   match(mRegN);
  4492   format %{ %}
  4493   interface(REG_INTER);
  4494 %}
  4496 operand a7_RegN() %{
  4497   constraint(ALLOC_IN_RC(a7_reg));
  4498   match(RegN);
  4499   match(mRegN);
  4501   format %{ %}
  4502   interface(REG_INTER);
  4503 %}
  4505 operand s0_RegN() %{
  4506   constraint(ALLOC_IN_RC(s0_reg));
  4507   match(RegN);
  4508   match(mRegN);
  4510   format %{ %}
  4511   interface(REG_INTER);
  4512 %}
  4514 operand s1_RegN() %{
  4515   constraint(ALLOC_IN_RC(s1_reg));
  4516   match(RegN);
  4517   match(mRegN);
  4519   format %{ %}
  4520   interface(REG_INTER);
  4521 %}
  4523 operand s2_RegN() %{
  4524   constraint(ALLOC_IN_RC(s2_reg));
  4525   match(RegN);
  4526   match(mRegN);
  4528   format %{ %}
  4529   interface(REG_INTER);
  4530 %}
  4532 operand s3_RegN() %{
  4533   constraint(ALLOC_IN_RC(s3_reg));
  4534   match(RegN);
  4535   match(mRegN);
  4537   format %{ %}
  4538   interface(REG_INTER);
  4539 %}
  4541 operand s4_RegN() %{
  4542   constraint(ALLOC_IN_RC(s4_reg));
  4543   match(RegN);
  4544   match(mRegN);
  4546   format %{ %}
  4547   interface(REG_INTER);
  4548 %}
  4550 operand s5_RegN() %{
  4551   constraint(ALLOC_IN_RC(s5_reg));
  4552   match(RegN);
  4553   match(mRegN);
  4555   format %{ %}
  4556   interface(REG_INTER);
  4557 %}
  4559 operand s6_RegN() %{
  4560   constraint(ALLOC_IN_RC(s6_reg));
  4561   match(RegN);
  4562   match(mRegN);
  4564   format %{ %}
  4565   interface(REG_INTER);
  4566 %}
  4568 operand s7_RegN() %{
  4569   constraint(ALLOC_IN_RC(s7_reg));
  4570   match(RegN);
  4571   match(mRegN);
  4573   format %{ %}
  4574   interface(REG_INTER);
  4575 %}
  4577 operand v0_RegN() %{
  4578   constraint(ALLOC_IN_RC(v0_reg));
  4579   match(RegN);
  4580   match(mRegN);
  4582   format %{ %}
  4583   interface(REG_INTER);
  4584 %}
  4586 operand v1_RegN() %{
  4587   constraint(ALLOC_IN_RC(v1_reg));
  4588   match(RegN);
  4589   match(mRegN);
  4591   format %{ %}
  4592   interface(REG_INTER);
  4593 %}
  4595 // Pointer Register
  4596 operand mRegP() %{
  4597   constraint(ALLOC_IN_RC(p_reg));
  4598   match(RegP);
  4599   match(a0_RegP);
  4601   format %{  %}
  4602   interface(REG_INTER);
  4603 %}
  4605 operand no_T8_mRegP() %{
  4606   constraint(ALLOC_IN_RC(no_T8_p_reg));
  4607   match(RegP);
  4608   match(mRegP);
  4610   format %{  %}
  4611   interface(REG_INTER);
  4612 %}
  4614 operand s0_RegP()
  4615 %{
  4616   constraint(ALLOC_IN_RC(s0_long_reg));
  4617   match(RegP);
  4618   match(mRegP);
  4619   match(no_T8_mRegP);
  4621   format %{ %}
  4622   interface(REG_INTER);
  4623 %}
  4625 operand s1_RegP()
  4626 %{
  4627   constraint(ALLOC_IN_RC(s1_long_reg));
  4628   match(RegP);
  4629   match(mRegP);
  4630   match(no_T8_mRegP);
  4632   format %{ %}
  4633   interface(REG_INTER);
  4634 %}
  4636 operand s2_RegP()
  4637 %{
  4638   constraint(ALLOC_IN_RC(s2_long_reg));
  4639   match(RegP);
  4640   match(mRegP);
  4641   match(no_T8_mRegP);
  4643   format %{ %}
  4644   interface(REG_INTER);
  4645 %}
  4647 operand s3_RegP()
  4648 %{
  4649   constraint(ALLOC_IN_RC(s3_long_reg));
  4650   match(RegP);
  4651   match(mRegP);
  4652   match(no_T8_mRegP);
  4654   format %{ %}
  4655   interface(REG_INTER);
  4656 %}
  4658 operand s4_RegP()
  4659 %{
  4660   constraint(ALLOC_IN_RC(s4_long_reg));
  4661   match(RegP);
  4662   match(mRegP);
  4663   match(no_T8_mRegP);
  4665   format %{ %}
  4666   interface(REG_INTER);
  4667 %}
  4669 operand s5_RegP()
  4670 %{
  4671   constraint(ALLOC_IN_RC(s5_long_reg));
  4672   match(RegP);
  4673   match(mRegP);
  4674   match(no_T8_mRegP);
  4676   format %{ %}
  4677   interface(REG_INTER);
  4678 %}
  4680 operand s6_RegP()
  4681 %{
  4682   constraint(ALLOC_IN_RC(s6_long_reg));
  4683   match(RegP);
  4684   match(mRegP);
  4685   match(no_T8_mRegP);
  4687   format %{ %}
  4688   interface(REG_INTER);
  4689 %}
  4691 operand s7_RegP()
  4692 %{
  4693   constraint(ALLOC_IN_RC(s7_long_reg));
  4694   match(RegP);
  4695   match(mRegP);
  4696   match(no_T8_mRegP);
  4698   format %{ %}
  4699   interface(REG_INTER);
  4700 %}
  4702 operand t0_RegP()
  4703 %{
  4704   constraint(ALLOC_IN_RC(t0_long_reg));
  4705   match(RegP);
  4706   match(mRegP);
  4707   match(no_T8_mRegP);
  4709   format %{ %}
  4710   interface(REG_INTER);
  4711 %}
  4713 operand t1_RegP()
  4714 %{
  4715   constraint(ALLOC_IN_RC(t1_long_reg));
  4716   match(RegP);
  4717   match(mRegP);
  4718   match(no_T8_mRegP);
  4720   format %{ %}
  4721   interface(REG_INTER);
  4722 %}
  4724 operand t2_RegP()
  4725 %{
  4726   constraint(ALLOC_IN_RC(t2_long_reg));
  4727   match(RegP);
  4728   match(mRegP);
  4729   match(no_T8_mRegP);
  4731   format %{ %}
  4732   interface(REG_INTER);
  4733 %}
  4735 operand t3_RegP()
  4736 %{
  4737   constraint(ALLOC_IN_RC(t3_long_reg));
  4738   match(RegP);
  4739   match(mRegP);
  4740   match(no_T8_mRegP);
  4742   format %{ %}
  4743   interface(REG_INTER);
  4744 %}
  4746 operand t8_RegP()
  4747 %{
  4748   constraint(ALLOC_IN_RC(t8_long_reg));
  4749   match(RegP);
  4750   match(mRegP);
  4752   format %{ %}
  4753   interface(REG_INTER);
  4754 %}
  4756 operand t9_RegP()
  4757 %{
  4758   constraint(ALLOC_IN_RC(t9_long_reg));
  4759   match(RegP);
  4760   match(mRegP);
  4761   match(no_T8_mRegP);
  4763   format %{ %}
  4764   interface(REG_INTER);
  4765 %}
  4767 operand a0_RegP()
  4768 %{
  4769   constraint(ALLOC_IN_RC(a0_long_reg));
  4770   match(RegP);
  4771   match(mRegP);
  4772   match(no_T8_mRegP);
  4774   format %{ %}
  4775   interface(REG_INTER);
  4776 %}
  4778 operand a1_RegP()
  4779 %{
  4780   constraint(ALLOC_IN_RC(a1_long_reg));
  4781   match(RegP);
  4782   match(mRegP);
  4783   match(no_T8_mRegP);
  4785   format %{ %}
  4786   interface(REG_INTER);
  4787 %}
  4789 operand a2_RegP()
  4790 %{
  4791   constraint(ALLOC_IN_RC(a2_long_reg));
  4792   match(RegP);
  4793   match(mRegP);
  4794   match(no_T8_mRegP);
  4796   format %{ %}
  4797   interface(REG_INTER);
  4798 %}
  4800 operand a3_RegP()
  4801 %{
  4802   constraint(ALLOC_IN_RC(a3_long_reg));
  4803   match(RegP);
  4804   match(mRegP);
  4805   match(no_T8_mRegP);
  4807   format %{ %}
  4808   interface(REG_INTER);
  4809 %}
  4811 operand a4_RegP()
  4812 %{
  4813   constraint(ALLOC_IN_RC(a4_long_reg));
  4814   match(RegP);
  4815   match(mRegP);
  4816   match(no_T8_mRegP);
  4818   format %{ %}
  4819   interface(REG_INTER);
  4820 %}
  4823 operand a5_RegP()
  4824 %{
  4825   constraint(ALLOC_IN_RC(a5_long_reg));
  4826   match(RegP);
  4827   match(mRegP);
  4828   match(no_T8_mRegP);
  4830   format %{ %}
  4831   interface(REG_INTER);
  4832 %}
  4834 operand a6_RegP()
  4835 %{
  4836   constraint(ALLOC_IN_RC(a6_long_reg));
  4837   match(RegP);
  4838   match(mRegP);
  4839   match(no_T8_mRegP);
  4841   format %{ %}
  4842   interface(REG_INTER);
  4843 %}
  4845 operand a7_RegP()
  4846 %{
  4847   constraint(ALLOC_IN_RC(a7_long_reg));
  4848   match(RegP);
  4849   match(mRegP);
  4850   match(no_T8_mRegP);
  4852   format %{ %}
  4853   interface(REG_INTER);
  4854 %}
  4856 operand v0_RegP()
  4857 %{
  4858   constraint(ALLOC_IN_RC(v0_long_reg));
  4859   match(RegP);
  4860   match(mRegP);
  4861   match(no_T8_mRegP);
  4863   format %{ %}
  4864   interface(REG_INTER);
  4865 %}
  4867 operand v1_RegP()
  4868 %{
  4869   constraint(ALLOC_IN_RC(v1_long_reg));
  4870   match(RegP);
  4871   match(mRegP);
  4872   match(no_T8_mRegP);
  4874   format %{ %}
  4875   interface(REG_INTER);
  4876 %}
  4878 /*
  4879 operand mSPRegP(mRegP reg) %{
  4880   constraint(ALLOC_IN_RC(sp_reg));
  4881   match(reg);
  4883   format %{ "SP"  %}
  4884   interface(REG_INTER);
  4885 %}
  4887 operand mFPRegP(mRegP reg) %{
  4888   constraint(ALLOC_IN_RC(fp_reg));
  4889   match(reg);
  4891   format %{ "FP"  %}
  4892   interface(REG_INTER);
  4893 %}
  4894 */
  4896 operand mRegL() %{
  4897   constraint(ALLOC_IN_RC(long_reg));
  4898   match(RegL);
  4900   format %{ %}
  4901   interface(REG_INTER);
  4902 %}
  4904 operand v0RegL() %{
  4905   constraint(ALLOC_IN_RC(v0_long_reg));
  4906   match(RegL);
  4907   match(mRegL);
  4909   format %{ %}
  4910   interface(REG_INTER);
  4911 %}
  4913 operand v1RegL() %{
  4914   constraint(ALLOC_IN_RC(v1_long_reg));
  4915   match(RegL);
  4916   match(mRegL);
  4918   format %{ %}
  4919   interface(REG_INTER);
  4920 %}
  4922 operand a0RegL() %{
  4923   constraint(ALLOC_IN_RC(a0_long_reg));
  4924   match(RegL);
  4925   match(mRegL);
  4927   format %{ "A0" %}
  4928   interface(REG_INTER);
  4929 %}
  4931 operand a1RegL() %{
  4932   constraint(ALLOC_IN_RC(a1_long_reg));
  4933   match(RegL);
  4934   match(mRegL);
  4936   format %{ %}
  4937   interface(REG_INTER);
  4938 %}
  4940 operand a2RegL() %{
  4941   constraint(ALLOC_IN_RC(a2_long_reg));
  4942   match(RegL);
  4943   match(mRegL);
  4945   format %{ %}
  4946   interface(REG_INTER);
  4947 %}
  4949 operand a3RegL() %{
  4950   constraint(ALLOC_IN_RC(a3_long_reg));
  4951   match(RegL);
  4952   match(mRegL);
  4954   format %{ %}
  4955   interface(REG_INTER);
  4956 %}
  4958 operand t0RegL() %{
  4959   constraint(ALLOC_IN_RC(t0_long_reg));
  4960   match(RegL);
  4961   match(mRegL);
  4963   format %{ %}
  4964   interface(REG_INTER);
  4965 %}
  4967 operand t1RegL() %{
  4968   constraint(ALLOC_IN_RC(t1_long_reg));
  4969   match(RegL);
  4970   match(mRegL);
  4972   format %{ %}
  4973   interface(REG_INTER);
  4974 %}
  4976 operand t2RegL() %{
  4977   constraint(ALLOC_IN_RC(t2_long_reg));
  4978   match(RegL);
  4979   match(mRegL);
  4981   format %{ %}
  4982   interface(REG_INTER);
  4983 %}
  4985 operand t3RegL() %{
  4986   constraint(ALLOC_IN_RC(t3_long_reg));
  4987   match(RegL);
  4988   match(mRegL);
  4990   format %{ %}
  4991   interface(REG_INTER);
  4992 %}
  4994 operand t8RegL() %{
  4995   constraint(ALLOC_IN_RC(t8_long_reg));
  4996   match(RegL);
  4997   match(mRegL);
  4999   format %{ %}
  5000   interface(REG_INTER);
  5001 %}
  5003 operand a4RegL() %{
  5004   constraint(ALLOC_IN_RC(a4_long_reg));
  5005   match(RegL);
  5006   match(mRegL);
  5008   format %{ %}
  5009   interface(REG_INTER);
  5010 %}
  5012 operand a5RegL() %{
  5013   constraint(ALLOC_IN_RC(a5_long_reg));
  5014   match(RegL);
  5015   match(mRegL);
  5017   format %{ %}
  5018   interface(REG_INTER);
  5019 %}
  5021 operand a6RegL() %{
  5022   constraint(ALLOC_IN_RC(a6_long_reg));
  5023   match(RegL);
  5024   match(mRegL);
  5026   format %{ %}
  5027   interface(REG_INTER);
  5028 %}
  5030 operand a7RegL() %{
  5031   constraint(ALLOC_IN_RC(a7_long_reg));
  5032   match(RegL);
  5033   match(mRegL);
  5035   format %{ %}
  5036   interface(REG_INTER);
  5037 %}
  5039 operand s0RegL() %{
  5040   constraint(ALLOC_IN_RC(s0_long_reg));
  5041   match(RegL);
  5042   match(mRegL);
  5044   format %{ %}
  5045   interface(REG_INTER);
  5046 %}
  5048 operand s1RegL() %{
  5049   constraint(ALLOC_IN_RC(s1_long_reg));
  5050   match(RegL);
  5051   match(mRegL);
  5053   format %{ %}
  5054   interface(REG_INTER);
  5055 %}
  5057 operand s2RegL() %{
  5058   constraint(ALLOC_IN_RC(s2_long_reg));
  5059   match(RegL);
  5060   match(mRegL);
  5062   format %{ %}
  5063   interface(REG_INTER);
  5064 %}
  5066 operand s3RegL() %{
  5067   constraint(ALLOC_IN_RC(s3_long_reg));
  5068   match(RegL);
  5069   match(mRegL);
  5071   format %{ %}
  5072   interface(REG_INTER);
  5073 %}
  5075 operand s4RegL() %{
  5076   constraint(ALLOC_IN_RC(s4_long_reg));
  5077   match(RegL);
  5078   match(mRegL);
  5080   format %{ %}
  5081   interface(REG_INTER);
  5082 %}
  5084 operand s7RegL() %{
  5085   constraint(ALLOC_IN_RC(s7_long_reg));
  5086   match(RegL);
  5087   match(mRegL);
  5089   format %{ %}
  5090   interface(REG_INTER);
  5091 %}
  5093 // Floating register operands
  5094 operand regF() %{
  5095   constraint(ALLOC_IN_RC(flt_reg));
  5096   match(RegF);
  5098   format %{ %}
  5099   interface(REG_INTER);
  5100 %}
  5102 //Double Precision Floating register operands
  5103 operand regD() %{
  5104   constraint(ALLOC_IN_RC(dbl_reg));
  5105   match(RegD);
  5107   format %{ %}
  5108   interface(REG_INTER);
  5109 %}
  5111 //----------Memory Operands----------------------------------------------------
  5112 // Indirect Memory Operand
  5113 operand indirect(mRegP reg) %{
  5114   constraint(ALLOC_IN_RC(p_reg));
  5115   match(reg);
  5117   format %{ "[$reg] @ indirect" %}
  5118   interface(MEMORY_INTER) %{
  5119     base($reg);
  5120     index(0x0);  /* NO_INDEX */
  5121     scale(0x0);
  5122     disp(0x0);
  5123   %}
  5124 %}
  5126 // Indirect Memory Plus Short Offset Operand
  5127 operand indOffset8(mRegP reg, immL8 off)
  5128 %{
  5129   constraint(ALLOC_IN_RC(p_reg));
  5130   match(AddP reg off);
  5132   op_cost(10);
  5133   format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
  5134   interface(MEMORY_INTER) %{
  5135     base($reg);
  5136     index(0x0); /* NO_INDEX */
  5137     scale(0x0);
  5138     disp($off);
  5139   %}
  5140 %}
  5142 // Indirect Memory Times Scale Plus Index Register
  5143 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
  5144 %{
  5145   constraint(ALLOC_IN_RC(p_reg));
  5146   match(AddP reg (LShiftL lreg scale));
  5148   op_cost(10);
  5149   format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
  5150   interface(MEMORY_INTER) %{
  5151     base($reg);
  5152     index($lreg);
  5153     scale($scale);
  5154     disp(0x0);
  5155   %}
  5156 %}
  5159 // [base + index + offset]
  5160 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
  5161 %{
  5162   constraint(ALLOC_IN_RC(p_reg));
  5163   op_cost(5);
  5164   match(AddP (AddP base index) off);
  5166   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
  5167   interface(MEMORY_INTER) %{
  5168     base($base);
  5169     index($index);
  5170     scale(0x0);
  5171     disp($off);
  5172   %}
  5173 %}
  5175 // [base + index + offset]
  5176 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
  5177 %{
  5178   constraint(ALLOC_IN_RC(p_reg));
  5179   op_cost(5);
  5180   match(AddP (AddP base (ConvI2L index)) off);
  5182   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
  5183   interface(MEMORY_INTER) %{
  5184     base($base);
  5185     index($index);
  5186     scale(0x0);
  5187     disp($off);
  5188   %}
  5189 %}
  5191 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5192 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
  5193 %{
  5194   constraint(ALLOC_IN_RC(p_reg));
  5195   match(AddP (AddP reg (LShiftL lreg scale)) off);
  5197   op_cost(10);
  5198   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
  5199   interface(MEMORY_INTER) %{
  5200     base($reg);
  5201     index($lreg);
  5202     scale($scale);
  5203     disp($off);
  5204   %}
  5205 %}
  5207 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
  5208 %{
  5209   constraint(ALLOC_IN_RC(p_reg));
  5210   match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
  5212   op_cost(10);
  5213   format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
  5214   interface(MEMORY_INTER) %{
  5215     base($reg);
  5216     index($ireg);
  5217     scale($scale);
  5218     disp($off);
  5219   %}
  5220 %}
  5222 // [base + index<<scale + offset]
  5223 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
  5224 %{
  5225   constraint(ALLOC_IN_RC(p_reg));
  5226   //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5227   op_cost(10);
  5228   match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
  5230   format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
  5231   interface(MEMORY_INTER) %{
  5232     base($base);
  5233     index($index);
  5234     scale($scale);
  5235     disp($off);
  5236   %}
  5237 %}
  5239 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5240 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
  5241 %{
  5242   predicate(Universe::narrow_oop_shift() == 0);
  5243   constraint(ALLOC_IN_RC(p_reg));
  5244   match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
  5246   op_cost(10);
  5247   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
  5248   interface(MEMORY_INTER) %{
  5249     base($reg);
  5250     index($lreg);
  5251     scale($scale);
  5252     disp($off);
  5253   %}
  5254 %}
  5256 // [base + index<<scale + offset] for compressd Oops
  5257 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
  5258 %{
  5259   constraint(ALLOC_IN_RC(p_reg));
  5260   //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5261   predicate(Universe::narrow_oop_shift() == 0);
  5262   op_cost(10);
  5263   match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
  5265   format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
  5266   interface(MEMORY_INTER) %{
  5267     base($base);
  5268     index($index);
  5269     scale($scale);
  5270     disp($off);
  5271   %}
  5272 %}
  5274 //FIXME: I think it's better to limit the immI to be 16-bit at most!
  5275 // Indirect Memory Plus Long Offset Operand
  5276 operand indOffset32(mRegP reg, immL32 off) %{
  5277   constraint(ALLOC_IN_RC(p_reg));
  5278   op_cost(20);
  5279   match(AddP reg off);
  5281   format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
  5282   interface(MEMORY_INTER) %{
  5283     base($reg);
  5284     index(0x0);   /* NO_INDEX */
  5285     scale(0x0);
  5286     disp($off);
  5287   %}
  5288 %}
  5290 // Indirect Memory Plus Index Register
  5291 operand indIndex(mRegP addr, mRegL index) %{
  5292   constraint(ALLOC_IN_RC(p_reg));
  5293   match(AddP addr index);
  5295   op_cost(20);
  5296   format %{"[$addr + $index] @ indIndex" %}
  5297   interface(MEMORY_INTER) %{
  5298     base($addr);
  5299     index($index);
  5300     scale(0x0);
  5301     disp(0x0);
  5302   %}
  5303 %}
  5305 operand indirectNarrowKlass(mRegN reg)
  5306 %{
  5307   predicate(Universe::narrow_klass_shift() == 0);
  5308   constraint(ALLOC_IN_RC(p_reg));
  5309   op_cost(10);
  5310   match(DecodeNKlass reg);
  5312   format %{ "[$reg] @ indirectNarrowKlass" %}
  5313   interface(MEMORY_INTER) %{
  5314     base($reg);
  5315     index(0x0);
  5316     scale(0x0);
  5317     disp(0x0);
  5318   %}
  5319 %}
  5321 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
  5322 %{
  5323   predicate(Universe::narrow_klass_shift() == 0);
  5324   constraint(ALLOC_IN_RC(p_reg));
  5325   op_cost(10);
  5326   match(AddP (DecodeNKlass reg) off);
  5328   format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
  5329   interface(MEMORY_INTER) %{
  5330     base($reg);
  5331     index(0x0);
  5332     scale(0x0);
  5333     disp($off);
  5334   %}
  5335 %}
  5337 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
  5338 %{
  5339   predicate(Universe::narrow_klass_shift() == 0);
  5340   constraint(ALLOC_IN_RC(p_reg));
  5341   op_cost(10);
  5342   match(AddP (DecodeNKlass reg) off);
  5344   format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
  5345   interface(MEMORY_INTER) %{
  5346     base($reg);
  5347     index(0x0);
  5348     scale(0x0);
  5349     disp($off);
  5350   %}
  5351 %}
  5353 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
  5354 %{
  5355   predicate(Universe::narrow_klass_shift() == 0);
  5356   constraint(ALLOC_IN_RC(p_reg));
  5357   match(AddP (AddP (DecodeNKlass reg) lreg) off);
  5359   op_cost(10);
  5360   format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
  5361   interface(MEMORY_INTER) %{
  5362     base($reg);
  5363     index($lreg);
  5364     scale(0x0);
  5365     disp($off);
  5366   %}
  5367 %}
  5369 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
  5370 %{
  5371   predicate(Universe::narrow_klass_shift() == 0);
  5372   constraint(ALLOC_IN_RC(p_reg));
  5373   match(AddP (DecodeNKlass reg) lreg);
  5375   op_cost(10);
  5376   format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
  5377   interface(MEMORY_INTER) %{
  5378     base($reg);
  5379     index($lreg);
  5380     scale(0x0);
  5381     disp(0x0);
  5382   %}
  5383 %}
  5385 // Indirect Memory Operand
  5386 operand indirectNarrow(mRegN reg)
  5387 %{
  5388   predicate(Universe::narrow_oop_shift() == 0);
  5389   constraint(ALLOC_IN_RC(p_reg));
  5390   op_cost(10);
  5391   match(DecodeN reg);
  5393   format %{ "[$reg] @ indirectNarrow" %}
  5394   interface(MEMORY_INTER) %{
  5395     base($reg);
  5396     index(0x0);
  5397     scale(0x0);
  5398     disp(0x0);
  5399   %}
  5400 %}
  5402 // Indirect Memory Plus Short Offset Operand
  5403 operand indOffset8Narrow(mRegN reg, immL8 off)
  5404 %{
  5405   predicate(Universe::narrow_oop_shift() == 0);
  5406   constraint(ALLOC_IN_RC(p_reg));
  5407   op_cost(10);
  5408   match(AddP (DecodeN reg) off);
  5410   format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
  5411   interface(MEMORY_INTER) %{
  5412     base($reg);
  5413     index(0x0);
  5414     scale(0x0);
  5415     disp($off);
  5416   %}
  5417 %}
  5419 // Indirect Memory Plus Index Register Plus Offset Operand
  5420 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
  5421 %{
  5422   predicate(Universe::narrow_oop_shift() == 0);
  5423   constraint(ALLOC_IN_RC(p_reg));
  5424   match(AddP (AddP (DecodeN reg) lreg) off);
  5426   op_cost(10);
  5427   format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
  5428   interface(MEMORY_INTER) %{
  5429     base($reg);
  5430     index($lreg);
  5431     scale(0x0);
  5432     disp($off);
  5433   %}
  5434 %}
  5436 //----------Load Long Memory Operands------------------------------------------
  5437 // The load-long idiom will use it's address expression again after loading
  5438 // the first word of the long.  If the load-long destination overlaps with
  5439 // registers used in the addressing expression, the 2nd half will be loaded
  5440 // from a clobbered address.  Fix this by requiring that load-long use
  5441 // address registers that do not overlap with the load-long target.
  5443 // load-long support
  5444 operand load_long_RegP() %{
  5445   constraint(ALLOC_IN_RC(p_reg));
  5446   match(RegP);
  5447   match(mRegP);
  5448   op_cost(100);
  5449   format %{  %}
  5450   interface(REG_INTER);
  5451 %}
  5453 // Indirect Memory Operand Long
  5454 operand load_long_indirect(load_long_RegP reg) %{
  5455   constraint(ALLOC_IN_RC(p_reg));
  5456   match(reg);
  5458   format %{ "[$reg]" %}
  5459   interface(MEMORY_INTER) %{
  5460     base($reg);
  5461     index(0x0);
  5462     scale(0x0);
  5463     disp(0x0);
  5464   %}
  5465 %}
  5467 // Indirect Memory Plus Long Offset Operand
  5468 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
  5469   match(AddP reg off);
  5471   format %{ "[$reg + $off]" %}
  5472   interface(MEMORY_INTER) %{
  5473     base($reg);
  5474     index(0x0);
  5475     scale(0x0);
  5476     disp($off);
  5477   %}
  5478 %}
  5480 //----------Conditional Branch Operands----------------------------------------
  5481 // Comparison Op  - This is the operation of the comparison, and is limited to
  5482 //                  the following set of codes:
  5483 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
  5484 //
  5485 // Other attributes of the comparison, such as unsignedness, are specified
  5486 // by the comparison instruction that sets a condition code flags register.
  5487 // That result is represented by a flags operand whose subtype is appropriate
  5488 // to the unsignedness (etc.) of the comparison.
  5489 //
  5490 // Later, the instruction which matches both the Comparison Op (a Bool) and
  5491 // the flags (produced by the Cmp) specifies the coding of the comparison op
  5492 // by matching a specific subtype of Bool operand below, such as cmpOpU.
  5494 // Comparision Code
  5495 operand cmpOp() %{
  5496   match(Bool);
  5498   format %{ "" %}
  5499   interface(COND_INTER) %{
  5500     equal(0x01);
  5501     not_equal(0x02);
  5502     greater(0x03);
  5503     greater_equal(0x04);
  5504     less(0x05);
  5505     less_equal(0x06);
  5506     overflow(0x7);
  5507     no_overflow(0x8);
  5508   %}
  5509 %}
  5512 // Comparision Code
  5513 // Comparison Code, unsigned compare.  Used by FP also, with
  5514 // C2 (unordered) turned into GT or LT already.  The other bits
  5515 // C0 and C3 are turned into Carry & Zero flags.
  5516 operand cmpOpU() %{
  5517   match(Bool);
  5519   format %{ "" %}
  5520   interface(COND_INTER) %{
  5521     equal(0x01);
  5522     not_equal(0x02);
  5523     greater(0x03);
  5524     greater_equal(0x04);
  5525     less(0x05);
  5526     less_equal(0x06);
  5527     overflow(0x7);
  5528     no_overflow(0x8);
  5529   %}
  5530 %}
  5533 //----------Special Memory Operands--------------------------------------------
  5534 // Stack Slot Operand - This operand is used for loading and storing temporary
  5535 //                      values on the stack where a match requires a value to
  5536 //                      flow through memory.
  5537 operand stackSlotP(sRegP reg) %{
  5538   constraint(ALLOC_IN_RC(stack_slots));
  5539   // No match rule because this operand is only generated in matching
  5540   op_cost(50);
  5541   format %{ "[$reg]" %}
  5542   interface(MEMORY_INTER) %{
  5543     base(0x1d);  // SP
  5544     index(0x0);  // No Index
  5545     scale(0x0);  // No Scale
  5546     disp($reg);  // Stack Offset
  5547   %}
  5548 %}
  5550 operand stackSlotI(sRegI reg) %{
  5551   constraint(ALLOC_IN_RC(stack_slots));
  5552   // No match rule because this operand is only generated in matching
  5553   op_cost(50);
  5554   format %{ "[$reg]" %}
  5555   interface(MEMORY_INTER) %{
  5556     base(0x1d);  // SP
  5557     index(0x0);  // No Index
  5558     scale(0x0);  // No Scale
  5559     disp($reg);  // Stack Offset
  5560   %}
  5561 %}
  5563 operand stackSlotF(sRegF reg) %{
  5564   constraint(ALLOC_IN_RC(stack_slots));
  5565   // No match rule because this operand is only generated in matching
  5566   op_cost(50);
  5567   format %{ "[$reg]" %}
  5568   interface(MEMORY_INTER) %{
  5569     base(0x1d);  // SP
  5570     index(0x0);  // No Index
  5571     scale(0x0);  // No Scale
  5572     disp($reg);  // Stack Offset
  5573   %}
  5574 %}
  5576 operand stackSlotD(sRegD reg) %{
  5577   constraint(ALLOC_IN_RC(stack_slots));
  5578   // No match rule because this operand is only generated in matching
  5579   op_cost(50);
  5580   format %{ "[$reg]" %}
  5581   interface(MEMORY_INTER) %{
  5582     base(0x1d);  // SP
  5583     index(0x0);  // No Index
  5584     scale(0x0);  // No Scale
  5585     disp($reg);  // Stack Offset
  5586   %}
  5587 %}
  5589 operand stackSlotL(sRegL reg) %{
  5590   constraint(ALLOC_IN_RC(stack_slots));
  5591   // No match rule because this operand is only generated in matching
  5592   op_cost(50);
  5593   format %{ "[$reg]" %}
  5594   interface(MEMORY_INTER) %{
  5595     base(0x1d);  // SP
  5596     index(0x0);  // No Index
  5597     scale(0x0);  // No Scale
  5598     disp($reg);  // Stack Offset
  5599   %}
  5600 %}
  5603 //------------------------OPERAND CLASSES--------------------------------------
  5604 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
  5605 opclass memory( indirect, indirectNarrow, indOffset8, indOffset32, indIndex, indIndexScale, load_long_indirect, load_long_indOffset32, baseIndexOffset8, baseIndexOffset8_convI2L, indIndexScaleOffset8, indIndexScaleOffset8_convI2L, basePosIndexScaleOffset8, indIndexScaleOffsetNarrow, indPosIndexI2LScaleOffset8Narrow, indOffset8Narrow, indIndexOffset8Narrow);
  5608 //----------PIPELINE-----------------------------------------------------------
  5609 // Rules which define the behavior of the target architectures pipeline.
  5611 pipeline %{
  5613   //----------ATTRIBUTES---------------------------------------------------------
  5614   attributes %{
  5615     fixed_size_instructions;          // Fixed size instructions
  5616     branch_has_delay_slot;      // branch have delay slot in gs2
  5617     max_instructions_per_bundle = 1;     // 1 instruction per bundle
  5618     max_bundles_per_cycle = 4;         // Up to 4 bundles per cycle
  5619          bundle_unit_size=4;
  5620     instruction_unit_size = 4;           // An instruction is 4 bytes long
  5621     instruction_fetch_unit_size = 16;    // The processor fetches one line
  5622     instruction_fetch_units = 1;         // of 16 bytes
  5624     // List of nop instructions
  5625     nops( MachNop );
  5626   %}
  5628   //----------RESOURCES----------------------------------------------------------
  5629   // Resources are the functional units available to the machine
  5631   resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4,  ALU1, ALU2,  ALU = ALU1 | ALU2,  FPU1, FPU2, FPU = FPU1 | FPU2,  MEM,  BR);
  5633   //----------PIPELINE DESCRIPTION-----------------------------------------------
  5634   // Pipeline Description specifies the stages in the machine's pipeline
  5636   // IF: fetch
  5637   // ID: decode
  5638   // RD: read
  5639   // CA: caculate
  5640   // WB: write back
  5641   // CM: commit
  5643   pipe_desc(IF, ID, RD, CA, WB, CM);
  5646   //----------PIPELINE CLASSES---------------------------------------------------
  5647   // Pipeline Classes describe the stages in which input and output are
  5648   // referenced by the hardware pipeline.
  5650   //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
  5651   pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
  5652     single_instruction;
  5653     src1   : RD(read);
  5654     src2   : RD(read);
  5655     dst    : WB(write)+1;
  5656     DECODE : ID;
  5657     ALU    : CA;
  5658   %}
  5660   //No.19 Integer mult operation : dst <-- reg1 mult reg2
  5661   pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
  5662     src1   : RD(read);
  5663     src2   : RD(read);
  5664     dst    : WB(write)+5;
  5665     DECODE : ID;
  5666     ALU2   : CA;
  5667   %}
  5669   pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  5670     src1   : RD(read);
  5671     src2   : RD(read);
  5672     dst    : WB(write)+10;
  5673     DECODE : ID;
  5674     ALU2   : CA;
  5675   %}
  5677   //No.19 Integer div operation : dst <-- reg1 div reg2
  5678   pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
  5679     src1   : RD(read);
  5680     src2   : RD(read);
  5681     dst    : WB(write)+10;
  5682     DECODE : ID;
  5683     ALU2   : CA;
  5684   %}
  5686   //No.19 Integer mod operation : dst <-- reg1 mod reg2
  5687   pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
  5688     instruction_count(2);
  5689     src1   : RD(read);
  5690     src2   : RD(read);
  5691     dst    : WB(write)+10;
  5692     DECODE : ID;
  5693     ALU2   : CA;
  5694   %}
  5696   //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
  5697   pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
  5698     instruction_count(2);
  5699     src1   : RD(read);
  5700     src2   : RD(read);
  5701     dst    : WB(write);
  5702     DECODE : ID;
  5703     ALU    : CA;
  5704   %}
  5706   //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
  5707   pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
  5708     instruction_count(2);
  5709     src    : RD(read);
  5710     dst    : WB(write);
  5711     DECODE : ID;
  5712     ALU    : CA;
  5713   %}
  5715   //no.16 load Long from memory :
  5716   pipe_class ialu_loadL(mRegL dst, memory mem) %{
  5717     instruction_count(2);
  5718     mem    : RD(read);
  5719     dst    : WB(write)+5;
  5720     DECODE : ID;
  5721     MEM    : RD;
  5722   %}
  5724   //No.17 Store Long to Memory :
  5725   pipe_class ialu_storeL(mRegL src, memory mem) %{
  5726     instruction_count(2);
  5727     mem    : RD(read);
  5728     src    : RD(read);
  5729     DECODE : ID;
  5730     MEM    : RD;
  5731   %}
  5733   //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
  5734   pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
  5735          single_instruction;
  5736     src    : RD(read);
  5737     dst    : WB(write);
  5738     DECODE : ID;
  5739     ALU    : CA;
  5740   %}
  5742   //No.3 Integer move operation : dst <-- reg
  5743   pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
  5744     src    : RD(read);
  5745     dst    : WB(write);
  5746     DECODE : ID;
  5747     ALU    : CA;
  5748   %}
  5750   //No.4 No instructions : do nothing
  5751   pipe_class empty( ) %{
  5752     instruction_count(0);
  5753   %}
  5755   //No.5 UnConditional branch :
  5756   pipe_class pipe_jump( label labl ) %{
  5757     multiple_bundles;
  5758     DECODE : ID;
  5759     BR     : RD;
  5760   %}
  5762   //No.6 ALU Conditional branch :
  5763   pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
  5764     multiple_bundles;
  5765     src1   : RD(read);
  5766     src2   : RD(read);
  5767     DECODE : ID;
  5768     BR     : RD;
  5769   %}
  5771   //no.7 load integer from memory :
  5772   pipe_class ialu_loadI(mRegI dst, memory mem) %{
  5773     mem    : RD(read);
  5774     dst    : WB(write)+3;
  5775     DECODE : ID;
  5776     MEM    : RD;
  5777   %}
  5779   //No.8 Store Integer to Memory :
  5780   pipe_class ialu_storeI(mRegI src, memory mem) %{
  5781     mem    : RD(read);
  5782     src    : RD(read);
  5783     DECODE : ID;
  5784     MEM    : RD;
  5785   %}
  5788   //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
  5789   pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
  5790     src1   : RD(read);
  5791     src2   : RD(read);
  5792     dst    : WB(write);
  5793     DECODE : ID;
  5794     FPU    : CA;
  5795   %}
  5797   //No.22 Floating div operation : dst <-- reg1 div reg2
  5798   pipe_class fpu_div(regF dst, regF src1, regF src2) %{
  5799     src1   : RD(read);
  5800     src2   : RD(read);
  5801     dst    : WB(write);
  5802     DECODE : ID;
  5803     FPU2   : CA;
  5804   %}
  5806   pipe_class fcvt_I2D(regD dst, mRegI src) %{
  5807     src    : RD(read);
  5808     dst    : WB(write);
  5809     DECODE : ID;
  5810     FPU1   : CA;
  5811   %}
  5813   pipe_class fcvt_D2I(mRegI dst, regD src) %{
  5814     src    : RD(read);
  5815     dst    : WB(write);
  5816     DECODE : ID;
  5817     FPU1   : CA;
  5818   %}
  5820   pipe_class pipe_mfc1(mRegI dst, regD src) %{
  5821     src    : RD(read);
  5822     dst    : WB(write);
  5823     DECODE : ID;
  5824     MEM    : RD;
  5825   %}
  5827   pipe_class pipe_mtc1(regD dst, mRegI src) %{
  5828     src    : RD(read);
  5829     dst    : WB(write);
  5830     DECODE : ID;
  5831     MEM    : RD(5);
  5832   %}
  5834   //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
  5835   pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
  5836     multiple_bundles;
  5837     src1   : RD(read);
  5838     src2   : RD(read);
  5839     dst    : WB(write);
  5840     DECODE : ID;
  5841     FPU2   : CA;
  5842   %}
  5844   //No.11 Load Floating from Memory :
  5845   pipe_class fpu_loadF(regF dst, memory mem) %{
  5846     instruction_count(1);
  5847     mem    : RD(read);
  5848     dst    : WB(write)+3;
  5849     DECODE : ID;
  5850     MEM    : RD;
  5851   %}
  5853   //No.12 Store Floating to Memory :
  5854   pipe_class fpu_storeF(regF src, memory mem) %{
  5855     instruction_count(1);
  5856     mem    : RD(read);
  5857     src    : RD(read);
  5858     DECODE : ID;
  5859     MEM    : RD;
  5860   %}
  5862   //No.13 FPU Conditional branch :
  5863   pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
  5864     multiple_bundles;
  5865     src1   : RD(read);
  5866     src2   : RD(read);
  5867     DECODE : ID;
  5868     BR     : RD;
  5869   %}
  5871 //No.14 Floating FPU reg operation : dst <-- op reg
  5872   pipe_class fpu1_regF(regF dst, regF src) %{
  5873     src    : RD(read);
  5874     dst    : WB(write);
  5875     DECODE : ID;
  5876     FPU    : CA;
  5877   %}
  5879   pipe_class long_memory_op() %{
  5880     instruction_count(10); multiple_bundles; force_serialization;
  5881     fixed_latency(30);
  5882   %}
  5884   pipe_class simple_call() %{
  5885    instruction_count(10); multiple_bundles; force_serialization;
  5886    fixed_latency(200);
  5887    BR     : RD;
  5888   %}
  5890   pipe_class call() %{
  5891     instruction_count(10); multiple_bundles; force_serialization;
  5892     fixed_latency(200);
  5893   %}
  5895   //FIXME:
  5896   //No.9 Piple slow : for multi-instructions
  5897   pipe_class pipe_slow(  ) %{
  5898     instruction_count(20);
  5899     force_serialization;
  5900     multiple_bundles;
  5901     fixed_latency(50);
  5902   %}
  5904 %}
  5908 //----------INSTRUCTIONS-------------------------------------------------------
  5909 //
  5910 // match      -- States which machine-independent subtree may be replaced
  5911 //               by this instruction.
  5912 // ins_cost   -- The estimated cost of this instruction is used by instruction
  5913 //               selection to identify a minimum cost tree of machine
  5914 //               instructions that matches a tree of machine-independent
  5915 //               instructions.
  5916 // format     -- A string providing the disassembly for this instruction.
  5917 //               The value of an instruction's operand may be inserted
  5918 //               by referring to it with a '$' prefix.
  5919 // opcode     -- Three instruction opcodes may be provided.  These are referred
  5920 //               to within an encode class as $primary, $secondary, and $tertiary
  5921 //               respectively.  The primary opcode is commonly used to
  5922 //               indicate the type of machine instruction, while secondary
  5923 //               and tertiary are often used for prefix options or addressing
  5924 //               modes.
  5925 // ins_encode -- A list of encode classes with parameters. The encode class
  5926 //               name must have been defined in an 'enc_class' specification
  5927 //               in the encode section of the architecture description.
  5930 // Load Integer
  5931 instruct loadI(mRegI dst, memory mem) %{
  5932   match(Set dst (LoadI mem));
  5934   ins_cost(125);
  5935   format %{ "lw    $dst, $mem   #@loadI" %}
  5936   ins_encode (load_I_enc(dst, mem));
  5937   ins_pipe( ialu_loadI );
  5938 %}
  5940 instruct loadI_convI2L(mRegL dst, memory mem) %{
  5941   match(Set dst (ConvI2L (LoadI mem)));
  5943   ins_cost(125);
  5944   format %{ "lw    $dst, $mem   #@loadI_convI2L" %}
  5945   ins_encode (load_I_enc(dst, mem));
  5946   ins_pipe( ialu_loadI );
  5947 %}
  5949 // Load Integer (32 bit signed) to Byte (8 bit signed)
  5950 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  5951   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
  5953   ins_cost(125);
  5954   format %{ "lb  $dst, $mem\t# int -> byte #@loadI2B" %}
  5955   ins_encode(load_B_enc(dst, mem));
  5956   ins_pipe(ialu_loadI);
  5957 %}
  5959 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
  5960 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
  5961   match(Set dst (AndI (LoadI mem) mask));
  5963   ins_cost(125);
  5964   format %{ "lbu  $dst, $mem\t# int -> ubyte #@loadI2UB" %}
  5965   ins_encode(load_UB_enc(dst, mem));
  5966   ins_pipe(ialu_loadI);
  5967 %}
  5969 // Load Integer (32 bit signed) to Short (16 bit signed)
  5970 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
  5971   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
  5973   ins_cost(125);
  5974   format %{ "lh  $dst, $mem\t# int -> short #@loadI2S" %}
  5975   ins_encode(load_S_enc(dst, mem));
  5976   ins_pipe(ialu_loadI);
  5977 %}
  5979 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
  5980 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
  5981   match(Set dst (AndI (LoadI mem) mask));
  5983   ins_cost(125);
  5984   format %{ "lhu  $dst, $mem\t# int -> ushort/char #@loadI2US" %}
  5985   ins_encode(load_C_enc(dst, mem));
  5986   ins_pipe(ialu_loadI);
  5987 %}
  5989 // Load Long.
  5990 instruct loadL(mRegL dst, memory mem) %{
  5991 //  predicate(!((LoadLNode*)n)->require_atomic_access());
  5992   match(Set dst (LoadL mem));
  5994   ins_cost(250);
  5995   format %{ "ld    $dst, $mem   #@loadL" %}
  5996   ins_encode(load_L_enc(dst, mem));
  5997   ins_pipe( ialu_loadL );
  5998 %}
  6000 // Load Long - UNaligned
  6001 instruct loadL_unaligned(mRegL dst, memory mem) %{
  6002   match(Set dst (LoadL_unaligned mem));
  6004   // FIXME: Need more effective ldl/ldr
  6005   ins_cost(450);
  6006   format %{ "ld    $dst, $mem   #@loadL_unaligned\n\t" %}
  6007   ins_encode(load_L_enc(dst, mem));
  6008   ins_pipe( ialu_loadL );
  6009 %}
  6011 // Store Long
  6012 instruct storeL_reg(memory mem, mRegL src) %{
  6013   match(Set mem (StoreL mem src));
  6015   ins_cost(200);
  6016   format %{ "sd    $mem,   $src #@storeL_reg\n" %}
  6017   ins_encode(store_L_reg_enc(mem, src));
  6018   ins_pipe( ialu_storeL );
  6019 %}
  6021 instruct storeL_immL0(memory mem, immL0 zero) %{
  6022   match(Set mem (StoreL mem zero));
  6024   ins_cost(180);
  6025   format %{ "sd    zero, $mem #@storeL_immL0" %}
  6026   ins_encode(store_L_immL0_enc(mem, zero));
  6027   ins_pipe( ialu_storeL );
  6028 %}
  6030 instruct storeL_imm(memory mem, immL src) %{
  6031   match(Set mem (StoreL mem src));
  6033   ins_cost(200);
  6034   format %{ "sd    $src, $mem #@storeL_imm" %}
  6035   ins_encode(store_L_immL_enc(mem, src));
  6036   ins_pipe( ialu_storeL );
  6037 %}
  6039 // Load Compressed Pointer
  6040 instruct loadN(mRegN dst, memory mem)
  6041 %{
  6042    match(Set dst (LoadN mem));
  6044    ins_cost(125); // XXX
  6045    format %{ "lwu    $dst, $mem\t# compressed ptr @ loadN" %}
  6046    ins_encode (load_N_enc(dst, mem));
  6047    ins_pipe( ialu_loadI ); // XXX
  6048 %}
  6050 instruct loadN2P(mRegP dst, memory mem)
  6051 %{
  6052    match(Set dst (DecodeN (LoadN mem)));
  6053    predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6055    ins_cost(125); // XXX
  6056    format %{ "lwu    $dst, $mem\t# @ loadN2P" %}
  6057    ins_encode (load_N_enc(dst, mem));
  6058    ins_pipe( ialu_loadI ); // XXX
  6059 %}
  6061 // Load Pointer
  6062 instruct loadP(mRegP dst, memory mem) %{
  6063   match(Set dst (LoadP mem));
  6065   ins_cost(125);
  6066   format %{ "ld    $dst, $mem #@loadP" %}
  6067   ins_encode (load_P_enc(dst, mem));
  6068   ins_pipe( ialu_loadI );
  6069 %}
  6071 // Load Klass Pointer
  6072 instruct loadKlass(mRegP dst, memory mem) %{
  6073   match(Set dst (LoadKlass mem));
  6075   ins_cost(125);
  6076   format %{ "MOV    $dst,$mem @ loadKlass" %}
  6077   ins_encode (load_P_enc(dst, mem));
  6078   ins_pipe( ialu_loadI );
  6079 %}
  6081 // Load narrow Klass Pointer
  6082 instruct loadNKlass(mRegN dst, memory mem)
  6083 %{
  6084   match(Set dst (LoadNKlass mem));
  6086   ins_cost(125); // XXX
  6087   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
  6088   ins_encode (load_N_enc(dst, mem));
  6089   ins_pipe( ialu_loadI ); // XXX
  6090 %}
  6092 instruct loadN2PKlass(mRegP dst, memory mem)
  6093 %{
  6094   match(Set dst (DecodeNKlass (LoadNKlass mem)));
  6095   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6097   ins_cost(125); // XXX
  6098   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
  6099   ins_encode (load_N_enc(dst, mem));
  6100   ins_pipe( ialu_loadI ); // XXX
  6101 %}
  6103 // Load Constant
  6104 instruct loadConI(mRegI dst, immI src) %{
  6105   match(Set dst src);
  6107   ins_cost(150);
  6108   format %{ "mov    $dst, $src #@loadConI" %}
  6109   ins_encode %{
  6110     Register dst = $dst$$Register;
  6111     int    value = $src$$constant;
  6112     __ move(dst, value);
  6113   %}
  6114   ins_pipe( ialu_regI_regI );
  6115 %}
  6118 instruct loadConL_set64(mRegL dst, immL src) %{
  6119   match(Set dst src);
  6120   ins_cost(120);
  6121   format %{ "li   $dst, $src @ loadConL_set64" %}
  6122   ins_encode %{
  6123     __ set64($dst$$Register, $src$$constant);
  6124   %}
  6125   ins_pipe(ialu_regL_regL);
  6126 %}
  6128 /*
  6129 // Load long value from constant table (predicated by immL_expensive).
  6130 instruct loadConL_load(mRegL dst, immL_expensive src) %{
  6131   match(Set dst src);
  6132   ins_cost(150);
  6133   format %{ "ld  $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
  6134   ins_encode %{
  6135     int con_offset = $constantoffset($src);
  6137     if (Assembler::is_simm16(con_offset)) {
  6138        __ ld($dst$$Register, $constanttablebase, con_offset);
  6139     } else {
  6140        __ set64(AT, con_offset);
  6141        if (UseLoongsonISA) {
  6142           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6143        } else {
  6144           __ daddu(AT, $constanttablebase, AT);
  6145           __ ld($dst$$Register, AT, 0);
  6148   %}
  6149   ins_pipe(ialu_loadI);
  6150 %}
  6151 */
  6153 instruct loadConL16(mRegL dst, immL16 src) %{
  6154   match(Set dst src);
  6155   ins_cost(105);
  6156   format %{ "mov    $dst, $src #@loadConL16" %}
  6157   ins_encode %{
  6158     Register dst_reg = as_Register($dst$$reg);
  6159     int      value   = $src$$constant;
  6160     __ daddiu(dst_reg, R0, value);
  6161   %}
  6162   ins_pipe( ialu_regL_regL );
  6163 %}
  6166 instruct loadConL0(mRegL dst, immL0 src) %{
  6167   match(Set dst src);
  6168   ins_cost(100);
  6169   format %{ "mov    $dst, zero #@loadConL0" %}
  6170   ins_encode %{
  6171     Register dst_reg = as_Register($dst$$reg);
  6172     __ daddu(dst_reg, R0, R0);
  6173   %}
  6174   ins_pipe( ialu_regL_regL );
  6175 %}
  6177 // Load Range
  6178 instruct loadRange(mRegI dst, memory mem) %{
  6179   match(Set dst (LoadRange mem));
  6181   ins_cost(125);
  6182   format %{ "MOV    $dst,$mem @ loadRange" %}
  6183   ins_encode(load_I_enc(dst, mem));
  6184   ins_pipe( ialu_loadI );
  6185 %}
  6188 instruct storeP(memory mem, mRegP src ) %{
  6189   match(Set mem (StoreP mem src));
  6191   ins_cost(125);
  6192   format %{ "sd    $src, $mem #@storeP" %}
  6193   ins_encode(store_P_reg_enc(mem, src));
  6194   ins_pipe( ialu_storeI );
  6195 %}
  6197 // Store NULL Pointer, mark word, or other simple pointer constant.
  6198 instruct storeImmP0(memory mem, immP0 zero) %{
  6199   match(Set mem (StoreP mem zero));
  6201   ins_cost(125);
  6202   format %{ "mov    $mem, $zero #@storeImmP0" %}
  6203   ins_encode(store_P_immP0_enc(mem));
  6204   ins_pipe( ialu_storeI );
  6205 %}
  6207 // Store Byte Immediate
  6208 instruct storeImmB(memory mem, immI8 src) %{
  6209   match(Set mem (StoreB mem src));
  6211   ins_cost(150);
  6212   format %{ "movb   $mem, $src #@storeImmB" %}
  6213   ins_encode(store_B_immI_enc(mem, src));
  6214   ins_pipe( ialu_storeI );
  6215 %}
  6217 // Store Compressed Pointer
  6218 instruct storeN(memory mem, mRegN src)
  6219 %{
  6220   match(Set mem (StoreN mem src));
  6222   ins_cost(125); // XXX
  6223   format %{ "sw    $mem, $src\t# compressed ptr @ storeN" %}
  6224   ins_encode(store_N_reg_enc(mem, src));
  6225   ins_pipe( ialu_storeI );
  6226 %}
  6228 instruct storeP2N(memory mem, mRegP src)
  6229 %{
  6230   match(Set mem (StoreN mem (EncodeP src)));
  6231   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6233   ins_cost(125); // XXX
  6234   format %{ "sw    $mem, $src\t# @ storeP2N" %}
  6235   ins_encode(store_N_reg_enc(mem, src));
  6236   ins_pipe( ialu_storeI );
  6237 %}
  6239 instruct storeNKlass(memory mem, mRegN src)
  6240 %{
  6241   match(Set mem (StoreNKlass mem src));
  6243   ins_cost(125); // XXX
  6244   format %{ "sw    $mem, $src\t# compressed klass ptr @ storeNKlass" %}
  6245   ins_encode(store_N_reg_enc(mem, src));
  6246   ins_pipe( ialu_storeI );
  6247 %}
  6249 instruct storeP2NKlass(memory mem, mRegP src)
  6250 %{
  6251   match(Set mem (StoreNKlass mem (EncodePKlass src)));
  6252   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6254   ins_cost(125); // XXX
  6255   format %{ "sw    $mem, $src\t# @ storeP2NKlass" %}
  6256   ins_encode(store_N_reg_enc(mem, src));
  6257   ins_pipe( ialu_storeI );
  6258 %}
  6260 instruct storeImmN0(memory mem, immN0 zero)
  6261 %{
  6262   match(Set mem (StoreN mem zero));
  6264   ins_cost(125); // XXX
  6265   format %{ "storeN0    zero, $mem\t# compressed ptr" %}
  6266   ins_encode(storeImmN0_enc(mem, zero));
  6267   ins_pipe( ialu_storeI );
  6268 %}
  6270 // Store Byte
  6271 instruct storeB(memory mem, mRegI src) %{
  6272   match(Set mem (StoreB mem src));
  6274   ins_cost(125);
  6275   format %{ "sb    $src, $mem #@storeB" %}
  6276   ins_encode(store_B_reg_enc(mem, src));
  6277   ins_pipe( ialu_storeI );
  6278 %}
  6280 instruct storeB_convL2I(memory mem, mRegL src) %{
  6281   match(Set mem (StoreB mem (ConvL2I src)));
  6283   ins_cost(125);
  6284   format %{ "sb    $src, $mem #@storeB_convL2I" %}
  6285   ins_encode(store_B_reg_enc(mem, src));
  6286   ins_pipe( ialu_storeI );
  6287 %}
  6289 // Load Byte (8bit signed)
  6290 instruct loadB(mRegI dst, memory mem) %{
  6291   match(Set dst (LoadB mem));
  6293   ins_cost(125);
  6294   format %{ "lb   $dst, $mem #@loadB" %}
  6295   ins_encode(load_B_enc(dst, mem));
  6296   ins_pipe( ialu_loadI );
  6297 %}
  6299 instruct loadB_convI2L(mRegL dst, memory mem) %{
  6300   match(Set dst (ConvI2L (LoadB mem)));
  6302   ins_cost(125);
  6303   format %{ "lb   $dst, $mem #@loadB_convI2L" %}
  6304   ins_encode(load_B_enc(dst, mem));
  6305   ins_pipe( ialu_loadI );
  6306 %}
  6308 // Load Byte (8bit UNsigned)
  6309 instruct loadUB(mRegI dst, memory mem) %{
  6310   match(Set dst (LoadUB mem));
  6312   ins_cost(125);
  6313   format %{ "lbu   $dst, $mem #@loadUB" %}
  6314   ins_encode(load_UB_enc(dst, mem));
  6315   ins_pipe( ialu_loadI );
  6316 %}
  6318 instruct loadUB_convI2L(mRegL dst, memory mem) %{
  6319   match(Set dst (ConvI2L (LoadUB mem)));
  6321   ins_cost(125);
  6322   format %{ "lbu   $dst, $mem #@loadUB_convI2L" %}
  6323   ins_encode(load_UB_enc(dst, mem));
  6324   ins_pipe( ialu_loadI );
  6325 %}
  6327 // Load Short (16bit signed)
  6328 instruct loadS(mRegI dst, memory mem) %{
  6329   match(Set dst (LoadS mem));
  6331   ins_cost(125);
  6332   format %{ "lh   $dst, $mem #@loadS" %}
  6333   ins_encode(load_S_enc(dst, mem));
  6334   ins_pipe( ialu_loadI );
  6335 %}
  6337 // Load Short (16 bit signed) to Byte (8 bit signed)
  6338 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  6339   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
  6341   ins_cost(125);
  6342   format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
  6343   ins_encode(load_B_enc(dst, mem));
  6344   ins_pipe(ialu_loadI);
  6345 %}
  6347 instruct loadS_convI2L(mRegL dst, memory mem) %{
  6348   match(Set dst (ConvI2L (LoadS mem)));
  6350   ins_cost(125);
  6351   format %{ "lh   $dst, $mem #@loadS_convI2L" %}
  6352   ins_encode(load_S_enc(dst, mem));
  6353   ins_pipe( ialu_loadI );
  6354 %}
  6356 // Store Integer Immediate
  6357 instruct storeImmI(memory mem, immI src) %{
  6358   match(Set mem (StoreI mem src));
  6360   ins_cost(150);
  6361   format %{ "mov    $mem, $src #@storeImmI" %}
  6362   ins_encode(store_I_immI_enc(mem, src));
  6363   ins_pipe( ialu_storeI );
  6364 %}
  6366 // Store Integer
  6367 instruct storeI(memory mem, mRegI src) %{
  6368   match(Set mem (StoreI mem src));
  6370   ins_cost(125);
  6371   format %{ "sw    $mem, $src #@storeI" %}
  6372   ins_encode(store_I_reg_enc(mem, src));
  6373   ins_pipe( ialu_storeI );
  6374 %}
  6376 instruct storeI_convL2I(memory mem, mRegL src) %{
  6377   match(Set mem (StoreI mem (ConvL2I src)));
  6379   ins_cost(125);
  6380   format %{ "sw    $mem, $src #@storeI_convL2I" %}
  6381   ins_encode(store_I_reg_enc(mem, src));
  6382   ins_pipe( ialu_storeI );
  6383 %}
  6385 // Load Float
  6386 instruct loadF(regF dst, memory mem) %{
  6387   match(Set dst (LoadF mem));
  6389   ins_cost(150);
  6390   format %{ "loadF $dst, $mem #@loadF" %}
  6391   ins_encode(load_F_enc(dst, mem));
  6392   ins_pipe( ialu_loadI );
  6393 %}
  6395 instruct loadConP_general(mRegP dst, immP src) %{
  6396   match(Set dst src);
  6398   ins_cost(120);
  6399   format %{ "li   $dst, $src #@loadConP_general" %}
  6401   ins_encode %{
  6402     Register dst = $dst$$Register;
  6403     long* value = (long*)$src$$constant;
  6405     if($src->constant_reloc() == relocInfo::metadata_type){
  6406       int klass_index = __ oop_recorder()->find_index((Klass*)value);
  6407       RelocationHolder rspec = metadata_Relocation::spec(klass_index);
  6409       __ relocate(rspec);
  6410       __ patchable_set48(dst, (long)value);
  6411     }else if($src->constant_reloc() == relocInfo::oop_type){
  6412       int oop_index = __ oop_recorder()->find_index((jobject)value);
  6413       RelocationHolder rspec = oop_Relocation::spec(oop_index);
  6415       __ relocate(rspec);
  6416       __ patchable_set48(dst, (long)value);
  6417     } else if ($src->constant_reloc() == relocInfo::none) {
  6418         __ set64(dst, (long)value);
  6420   %}
  6422   ins_pipe( ialu_regI_regI );
  6423 %}
  6425 /*
  6426 instruct loadConP_load(mRegP dst, immP_load src) %{
  6427   match(Set dst src);
  6429   ins_cost(100);
  6430   format %{ "ld     $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
  6432   ins_encode %{
  6434     int con_offset = $constantoffset($src);
  6436     if (Assembler::is_simm16(con_offset)) {
  6437        __ ld($dst$$Register, $constanttablebase, con_offset);
  6438     } else {
  6439        __ set64(AT, con_offset);
  6440        if (UseLoongsonISA) {
  6441           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6442        } else {
  6443           __ daddu(AT, $constanttablebase, AT);
  6444           __ ld($dst$$Register, AT, 0);
  6447   %}
  6449   ins_pipe(ialu_loadI);
  6450 %}
  6451 */
  6453 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
  6454   match(Set dst src);
  6456   ins_cost(80);
  6457   format %{ "li    $dst, $src @ loadConP_no_oop_cheap" %}
  6459   ins_encode %{
  6460     __ set64($dst$$Register, $src$$constant);
  6461   %}
  6463   ins_pipe(ialu_regI_regI);
  6464 %}
  6467 instruct loadConP_poll(mRegP dst, immP_poll src) %{
  6468   match(Set dst src);
  6470   ins_cost(50);
  6471   format %{ "li   $dst, $src #@loadConP_poll" %}
  6473   ins_encode %{
  6474     Register dst = $dst$$Register;
  6475     intptr_t value = (intptr_t)$src$$constant;
  6477     __ set64(dst, (jlong)value);
  6478   %}
  6480   ins_pipe( ialu_regI_regI );
  6481 %}
  6483 instruct loadConP0(mRegP dst, immP0 src)
  6484 %{
  6485   match(Set dst src);
  6487   ins_cost(50);
  6488   format %{ "mov    $dst, R0\t# ptr" %}
  6489   ins_encode %{
  6490      Register dst_reg = $dst$$Register;
  6491      __ daddu(dst_reg, R0, R0);
  6492   %}
  6493   ins_pipe( ialu_regI_regI );
  6494 %}
  6496 instruct loadConN0(mRegN dst, immN0 src) %{
  6497   match(Set dst src);
  6498   format %{ "move    $dst, R0\t# compressed NULL ptr" %}
  6499   ins_encode %{
  6500     __ move($dst$$Register, R0);
  6501   %}
  6502   ins_pipe( ialu_regI_regI );
  6503 %}
  6505 instruct loadConN(mRegN dst, immN src) %{
  6506   match(Set dst src);
  6508   ins_cost(125);
  6509   format %{ "li    $dst, $src\t# compressed ptr @ loadConN" %}
  6510   ins_encode %{
  6511     Register dst = $dst$$Register;
  6512     __ set_narrow_oop(dst, (jobject)$src$$constant);
  6513   %}
  6514   ins_pipe( ialu_regI_regI ); // XXX
  6515 %}
  6517 instruct loadConNKlass(mRegN dst, immNKlass src) %{
  6518   match(Set dst src);
  6520   ins_cost(125);
  6521   format %{ "li    $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
  6522   ins_encode %{
  6523     Register dst = $dst$$Register;
  6524     __ set_narrow_klass(dst, (Klass*)$src$$constant);
  6525   %}
  6526   ins_pipe( ialu_regI_regI ); // XXX
  6527 %}
  6529 //FIXME
  6530 // Tail Call; Jump from runtime stub to Java code.
  6531 // Also known as an 'interprocedural jump'.
  6532 // Target of jump will eventually return to caller.
  6533 // TailJump below removes the return address.
  6534 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
  6535   match(TailCall jump_target method_oop );
  6536   ins_cost(300);
  6537   format %{ "JMP    $jump_target \t# @TailCalljmpInd" %}
  6539   ins_encode %{
  6540     Register target = $jump_target$$Register;
  6541     Register    oop = $method_oop$$Register;
  6543     // RA will be used in generate_forward_exception()
  6544     __ push(RA);
  6546     __ move(S3, oop);
  6547     __ jr(target);
  6548     __ delayed()->nop();
  6549   %}
  6551   ins_pipe( pipe_jump );
  6552 %}
  6554 // Create exception oop: created by stack-crawling runtime code.
  6555 // Created exception is now available to this handler, and is setup
  6556 // just prior to jumping to this handler.  No code emitted.
  6557 instruct CreateException( a0_RegP ex_oop )
  6558 %{
  6559   match(Set ex_oop (CreateEx));
  6561   // use the following format syntax
  6562   format %{ "# exception oop is in A0; no code emitted @CreateException" %}
  6563   ins_encode %{
  6564     // X86 leaves this function empty
  6565     __ block_comment("CreateException is empty in MIPS");
  6566   %}
  6567   ins_pipe( empty );
  6568 //  ins_pipe( pipe_jump );
  6569 %}
  6572 /* The mechanism of exception handling is clear now.
  6574 - Common try/catch:
  6575   [stubGenerator_mips.cpp] generate_forward_exception()
  6576       |- V0, V1 are created
  6577       |- T9 <= SharedRuntime::exception_handler_for_return_address
  6578       `- jr T9
  6579            `- the caller's exception_handler
  6580                  `- jr OptoRuntime::exception_blob
  6581                         `- here
  6582 - Rethrow(e.g. 'unwind'):
  6583   * The callee:
  6584      |- an exception is triggered during execution
  6585      `- exits the callee method through RethrowException node
  6586           |- The callee pushes exception_oop(T0) and exception_pc(RA)
  6587           `- The callee jumps to OptoRuntime::rethrow_stub()
  6588   * In OptoRuntime::rethrow_stub:
  6589      |- The VM calls _rethrow_Java to determine the return address in the caller method
  6590      `- exits the stub with tailjmpInd
  6591           |- pops exception_oop(V0) and exception_pc(V1)
  6592           `- jumps to the return address(usually an exception_handler)
  6593   * The caller:
  6594      `- continues processing the exception_blob with V0/V1
  6595 */
  6597 /*
  6598 Disassembling OptoRuntime::rethrow_stub()
  6600 ; locals
  6601    0x2d3bf320: addiu sp, sp, 0xfffffff8
  6602    0x2d3bf324: sw ra, 0x4(sp)
  6603    0x2d3bf328: sw fp, 0x0(sp)
  6604    0x2d3bf32c: addu fp, sp, zero
  6605    0x2d3bf330: addiu sp, sp, 0xfffffff0
  6606    0x2d3bf334: sw ra, 0x8(sp)
  6607    0x2d3bf338: sw t0, 0x4(sp)
  6608    0x2d3bf33c: sw sp, 0x0(sp)
  6610 ; get_thread(S2)
  6611    0x2d3bf340: addu s2, sp, zero
  6612    0x2d3bf344: srl s2, s2, 12
  6613    0x2d3bf348: sll s2, s2, 2
  6614    0x2d3bf34c: lui at, 0x2c85
  6615    0x2d3bf350: addu at, at, s2
  6616    0x2d3bf354: lw s2, 0xffffcc80(at)
  6618    0x2d3bf358: lw s0, 0x0(sp)
  6619    0x2d3bf35c: sw s0, 0x118(s2)    // last_sp -> threa
  6620    0x2d3bf360: sw s2, 0xc(sp)
  6622 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
  6623    0x2d3bf364: lw a0, 0x4(sp)
  6624    0x2d3bf368: lw a1, 0xc(sp)
  6625    0x2d3bf36c: lw a2, 0x8(sp)
  6626   ;; Java_To_Runtime
  6627    0x2d3bf370: lui t9, 0x2c34
  6628    0x2d3bf374: addiu t9, t9, 0xffff8a48
  6629    0x2d3bf378: jalr t9
  6630    0x2d3bf37c: nop
  6632    0x2d3bf380: addu s3, v0, zero     ; S3: SharedRuntime::raw_exception_handler_for_return_address()
  6634    0x2d3bf384: lw s0, 0xc(sp)
  6635    0x2d3bf388: sw zero, 0x118(s0)
  6636    0x2d3bf38c: sw zero, 0x11c(s0)
  6637    0x2d3bf390: lw s1, 0x144(s0)      ; ex_oop: S1
  6638    0x2d3bf394: addu s2, s0, zero
  6639    0x2d3bf398: sw zero, 0x144(s2)
  6640    0x2d3bf39c: lw s0, 0x4(s2)
  6641    0x2d3bf3a0: addiu s4, zero, 0x0
  6642    0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
  6643    0x2d3bf3a8: nop
  6644    0x2d3bf3ac: addiu sp, sp, 0x10
  6645    0x2d3bf3b0: addiu sp, sp, 0x8
  6646    0x2d3bf3b4: lw ra, 0xfffffffc(sp)
  6647    0x2d3bf3b8: lw fp, 0xfffffff8(sp)
  6648    0x2d3bf3bc: lui at, 0x2b48
  6649    0x2d3bf3c0: lw at, 0x100(at)
  6651 ; tailjmpInd: Restores exception_oop & exception_pc
  6652    0x2d3bf3c4: addu v1, ra, zero
  6653    0x2d3bf3c8: addu v0, s1, zero
  6654    0x2d3bf3cc: jr s3
  6655    0x2d3bf3d0: nop
  6656 ; Exception:
  6657    0x2d3bf3d4: lui s1, 0x2cc8    ; generate_forward_exception()
  6658    0x2d3bf3d8: addiu s1, s1, 0x40
  6659    0x2d3bf3dc: addiu s2, zero, 0x0
  6660    0x2d3bf3e0: addiu sp, sp, 0x10
  6661    0x2d3bf3e4: addiu sp, sp, 0x8
  6662    0x2d3bf3e8: lw ra, 0xfffffffc(sp)
  6663    0x2d3bf3ec: lw fp, 0xfffffff8(sp)
  6664    0x2d3bf3f0: lui at, 0x2b48
  6665    0x2d3bf3f4: lw at, 0x100(at)
  6666 ; TailCalljmpInd
  6667               __ push(RA);    ; to be used in generate_forward_exception()
  6668    0x2d3bf3f8: addu t7, s2, zero
  6669    0x2d3bf3fc: jr s1
  6670    0x2d3bf400: nop
  6671 */
  6672 // Rethrow exception:
  6673 // The exception oop will come in the first argument position.
  6674 // Then JUMP (not call) to the rethrow stub code.
  6675 instruct RethrowException()
  6676 %{
  6677   match(Rethrow);
  6679   // use the following format syntax
  6680   format %{ "JMP    rethrow_stub #@RethrowException" %}
  6681   ins_encode %{
  6682     __ block_comment("@ RethrowException");
  6684     cbuf.set_insts_mark();
  6685     cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
  6687     // call OptoRuntime::rethrow_stub to get the exception handler in parent method
  6688     __ patchable_jump((address)OptoRuntime::rethrow_stub());
  6689   %}
  6690   ins_pipe( pipe_jump );
  6691 %}
  6693 // ============================================================================
  6694 // Branch Instructions --- long offset versions
  6696 // Jump Direct
  6697 instruct jmpDir_long(label labl) %{
  6698   match(Goto);
  6699   effect(USE labl);
  6701   ins_cost(300);
  6702   format %{ "JMP    $labl #@jmpDir_long" %}
  6704   ins_encode %{
  6705     Label* L = $labl$$label;
  6706     __ jmp_far(*L);
  6707   %}
  6709   ins_pipe( pipe_jump );
  6710   //ins_pc_relative(1);
  6711 %}
  6713 // Jump Direct Conditional - Label defines a relative address from Jcc+1
  6714 instruct  jmpLoopEnd_long(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
  6715   match(CountedLoopEnd cop (CmpI src1 src2));
  6716   effect(USE labl);
  6718   ins_cost(300);
  6719   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_long" %}
  6720   ins_encode %{
  6721     Register op1 = $src1$$Register;
  6722     Register op2 = $src2$$Register;
  6723     Label*     L = $labl$$label;
  6724     int     flag = $cop$$cmpcode;
  6726     switch(flag) {
  6727       case 0x01: //equal
  6728         __ beq_long(op1, op2, *L);
  6729         break;
  6730       case 0x02: //not_equal
  6731         __ bne_long(op1, op2, *L);
  6732         break;
  6733       case 0x03: //above
  6734         __ slt(AT, op2, op1);
  6735         __ bne_long(AT, R0, *L);
  6736         break;
  6737       case 0x04: //above_equal
  6738         __ slt(AT, op1, op2);
  6739         __ beq_long(AT, R0, *L);
  6740         break;
  6741       case 0x05: //below
  6742         __ slt(AT, op1, op2);
  6743         __ bne_long(AT, R0, *L);
  6744         break;
  6745       case 0x06: //below_equal
  6746         __ slt(AT, op2, op1);
  6747         __ beq_long(AT, R0, *L);
  6748         break;
  6749       default:
  6750         Unimplemented();
  6752   %}
  6753   ins_pipe( pipe_jump );
  6754   ins_pc_relative(1);
  6755 %}
  6757 instruct  jmpLoopEnd_reg_immI_long(cmpOp cop, mRegI src1, immI src2, label labl) %{
  6758   match(CountedLoopEnd cop (CmpI src1 src2));
  6759   effect(USE labl);
  6761   ins_cost(300);
  6762   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI_long" %}
  6763   ins_encode %{
  6764     Register op1 = $src1$$Register;
  6765     Register op2 = AT;
  6766     Label*     L = $labl$$label;
  6767     int     flag = $cop$$cmpcode;
  6769     __ move(op2, $src2$$constant);
  6771     switch(flag) {
  6772       case 0x01: //equal
  6773         __ beq_long(op1, op2, *L);
  6774         break;
  6775       case 0x02: //not_equal
  6776         __ bne_long(op1, op2, *L);
  6777         break;
  6778       case 0x03: //above
  6779         __ slt(AT, op2, op1);
  6780         __ bne_long(AT, R0, *L);
  6781         break;
  6782       case 0x04: //above_equal
  6783         __ slt(AT, op1, op2);
  6784         __ beq_long(AT, R0, *L);
  6785         break;
  6786       case 0x05: //below
  6787         __ slt(AT, op1, op2);
  6788         __ bne_long(AT, R0, *L);
  6789         break;
  6790       case 0x06: //below_equal
  6791         __ slt(AT, op2, op1);
  6792         __ beq_long(AT, R0, *L);
  6793         break;
  6794       default:
  6795         Unimplemented();
  6797   %}
  6798   ins_pipe( pipe_jump );
  6799   ins_pc_relative(1);
  6800 %}
  6803 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
  6804 instruct jmpCon_flags_long(cmpOp cop, FlagsReg cr, label labl) %{
  6805   match(If cop cr);
  6806   effect(USE labl);
  6808   ins_cost(300);
  6809   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags_long" %}
  6811   ins_encode %{
  6812     Label*    L =  $labl$$label;
  6813     switch($cop$$cmpcode) {
  6814       case 0x01: //equal
  6815         __ bne_long(AT, R0, *L);
  6816         break;
  6817       case 0x02: //not equal
  6818         __ beq_long(AT, R0, *L);
  6819         break;
  6820       default:
  6821         Unimplemented();
  6823   %}
  6825   ins_pipe( pipe_jump );
  6826   ins_pc_relative(1);
  6827 %}
  6829 // Conditional jumps
  6830 instruct branchConP_zero_long(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  6831   match(If cmp (CmpP op1 zero));
  6832   effect(USE labl);
  6834   ins_cost(180);
  6835   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero_long" %}
  6837   ins_encode %{
  6838     Register op1 = $op1$$Register;
  6839     Register op2 = R0;
  6840     Label*    L  = $labl$$label;
  6841     int     flag = $cmp$$cmpcode;
  6843     switch(flag) {
  6844       case 0x01: //equal
  6845         __ beq_long(op1, op2, *L);
  6846         break;
  6847       case 0x02: //not_equal
  6848         __ bne_long(op1, op2, *L);
  6849         break;
  6850       default:
  6851         Unimplemented();
  6853   %}
  6855   ins_pc_relative(1);
  6856   ins_pipe( pipe_alu_branch );
  6857 %}
  6859 instruct branchConN2P_zero_long(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  6860   match(If cmp (CmpP (DecodeN op1) zero));
  6861   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6862   effect(USE labl);
  6864   ins_cost(180);
  6865   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero_long" %}
  6867   ins_encode %{
  6868     Register op1 = $op1$$Register;
  6869     Register op2 = R0;
  6870     Label*    L  = $labl$$label;
  6871     int     flag = $cmp$$cmpcode;
  6873     switch(flag)
  6875       case 0x01: //equal
  6876         __ beq_long(op1, op2, *L);
  6877         break;
  6878       case 0x02: //not_equal
  6879         __ bne_long(op1, op2, *L);
  6880         break;
  6881       default:
  6882         Unimplemented();
  6884   %}
  6886   ins_pc_relative(1);
  6887   ins_pipe( pipe_alu_branch );
  6888 %}
  6891 instruct branchConP_long(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  6892   match(If cmp (CmpP op1 op2));
  6893 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  6894   effect(USE labl);
  6896   ins_cost(200);
  6897   format %{ "b$cmp   $op1, $op2, $labl #@branchConP_long" %}
  6899   ins_encode %{
  6900     Register op1 = $op1$$Register;
  6901     Register op2 = $op2$$Register;
  6902     Label*    L  = $labl$$label;
  6903     int     flag = $cmp$$cmpcode;
  6905     switch(flag) {
  6906       case 0x01: //equal
  6907         __ beq_long(op1, op2, *L);
  6908         break;
  6909       case 0x02: //not_equal
  6910         __ bne_long(op1, op2, *L);
  6911         break;
  6912       case 0x03: //above
  6913         __ sltu(AT, op2, op1);
  6914         __ bne_long(R0, AT, *L);
  6915         break;
  6916       case 0x04: //above_equal
  6917         __ sltu(AT, op1, op2);
  6918         __ beq_long(AT, R0, *L);
  6919         break;
  6920       case 0x05: //below
  6921         __ sltu(AT, op1, op2);
  6922         __ bne_long(R0, AT, *L);
  6923         break;
  6924       case 0x06: //below_equal
  6925         __ sltu(AT, op2, op1);
  6926         __ beq_long(AT, R0, *L);
  6927        break;
  6928       default:
  6929           Unimplemented();
  6931   %}
  6933   ins_pc_relative(1);
  6934   ins_pipe( pipe_alu_branch );
  6935 %}
  6937 instruct cmpN_null_branch_long(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  6938   match(If cmp (CmpN op1 null));
  6939   effect(USE labl);
  6941   ins_cost(180);
  6942   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  6943             "BP$cmp   $labl @ cmpN_null_branch_long" %}
  6944   ins_encode %{
  6945     Register op1 = $op1$$Register;
  6946     Register op2 = R0;
  6947     Label*    L  = $labl$$label;
  6948     int     flag = $cmp$$cmpcode;
  6950     switch(flag) {
  6951     case 0x01: //equal
  6952       __ beq_long(op1, op2, *L);
  6953       break;
  6954     case 0x02: //not_equal
  6955       __ bne_long(op1, op2, *L);
  6956       break;
  6957     default:
  6958           Unimplemented();
  6960   %}
  6961 //TODO: pipe_branchP or create pipe_branchN LEE
  6962   ins_pc_relative(1);
  6963   ins_pipe( pipe_alu_branch );
  6964 %}
  6966 instruct cmpN_reg_branch_long(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  6967   match(If cmp (CmpN op1 op2));
  6968   effect(USE labl);
  6970   ins_cost(180);
  6971   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  6972             "BP$cmp   $labl @ cmpN_reg_branch_long" %}
  6973   ins_encode %{
  6974     Register op1_reg = $op1$$Register;
  6975     Register op2_reg = $op2$$Register;
  6976     Label*    L  = $labl$$label;
  6977     int     flag = $cmp$$cmpcode;
  6979     switch(flag) {
  6980     case 0x01: //equal
  6981       __ beq_long(op1_reg, op2_reg, *L);
  6982       break;
  6983     case 0x02: //not_equal
  6984       __ bne_long(op1_reg, op2_reg, *L);
  6985       break;
  6986     case 0x03: //above
  6987       __ sltu(AT, op2_reg, op1_reg);
  6988       __ bne_long(R0, AT, *L);
  6989       break;
  6990     case 0x04: //above_equal
  6991       __ sltu(AT, op1_reg, op2_reg);
  6992       __ beq_long(AT, R0, *L);
  6993       break;
  6994     case 0x05: //below
  6995       __ sltu(AT, op1_reg, op2_reg);
  6996       __ bne_long(R0, AT, *L);
  6997       break;
  6998     case 0x06: //below_equal
  6999       __ sltu(AT, op2_reg, op1_reg);
  7000       __ beq_long(AT, R0, *L);
  7001       break;
  7002     default:
  7003       Unimplemented();
  7005   %}
  7006   ins_pc_relative(1);
  7007   ins_pipe( pipe_alu_branch );
  7008 %}
  7010 instruct branchConIU_reg_reg_long(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  7011   match( If cmp (CmpU src1 src2) );
  7012   effect(USE labl);
  7013   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg_long" %}
  7015   ins_encode %{
  7016     Register op1 = $src1$$Register;
  7017     Register op2 = $src2$$Register;
  7018     Label*     L = $labl$$label;
  7019     int     flag = $cmp$$cmpcode;
  7021     switch(flag) {
  7022       case 0x01: //equal
  7023         __ beq_long(op1, op2, *L);
  7024         break;
  7025       case 0x02: //not_equal
  7026         __ bne_long(op1, op2, *L);
  7027         break;
  7028       case 0x03: //above
  7029         __ sltu(AT, op2, op1);
  7030         __ bne_long(AT, R0, *L);
  7031         break;
  7032       case 0x04: //above_equal
  7033         __ sltu(AT, op1, op2);
  7034         __ beq_long(AT, R0, *L);
  7035         break;
  7036       case 0x05: //below
  7037         __ sltu(AT, op1, op2);
  7038         __ bne_long(AT, R0, *L);
  7039         break;
  7040       case 0x06: //below_equal
  7041         __ sltu(AT, op2, op1);
  7042         __ beq_long(AT, R0, *L);
  7043         break;
  7044       default:
  7045         Unimplemented();
  7047   %}
  7049   ins_pc_relative(1);
  7050   ins_pipe( pipe_alu_branch );
  7051 %}
  7054 instruct branchConIU_reg_imm_long(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  7055   match( If cmp (CmpU src1 src2) );
  7056   effect(USE labl);
  7057   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm_long" %}
  7059   ins_encode %{
  7060     Register op1 = $src1$$Register;
  7061     int      val = $src2$$constant;
  7062     Label*     L = $labl$$label;
  7063     int     flag = $cmp$$cmpcode;
  7065     __ move(AT, val);
  7066     switch(flag) {
  7067       case 0x01: //equal
  7068         __ beq_long(op1, AT, *L);
  7069         break;
  7070       case 0x02: //not_equal
  7071         __ bne_long(op1, AT, *L);
  7072         break;
  7073       case 0x03: //above
  7074         __ sltu(AT, AT, op1);
  7075         __ bne_long(R0, AT, *L);
  7076         break;
  7077       case 0x04: //above_equal
  7078         __ sltu(AT, op1, AT);
  7079         __ beq_long(AT, R0, *L);
  7080         break;
  7081       case 0x05: //below
  7082         __ sltu(AT, op1, AT);
  7083         __ bne_long(R0, AT, *L);
  7084         break;
  7085       case 0x06: //below_equal
  7086         __ sltu(AT, AT, op1);
  7087         __ beq_long(AT, R0, *L);
  7088        break;
  7089       default:
  7090         Unimplemented();
  7092   %}
  7094   ins_pc_relative(1);
  7095   ins_pipe( pipe_alu_branch );
  7096 %}
  7098 instruct branchConI_reg_reg_long(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  7099   match( If cmp (CmpI src1 src2) );
  7100   effect(USE labl);
  7101   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg_long" %}
  7103   ins_encode %{
  7104     Register op1 = $src1$$Register;
  7105     Register op2 = $src2$$Register;
  7106     Label*     L = $labl$$label;
  7107     int     flag = $cmp$$cmpcode;
  7109     switch(flag) {
  7110       case 0x01: //equal
  7111         __ beq_long(op1, op2, *L);
  7112         break;
  7113       case 0x02: //not_equal
  7114         __ bne_long(op1, op2, *L);
  7115         break;
  7116       case 0x03: //above
  7117         __ slt(AT, op2, op1);
  7118         __ bne_long(R0, AT, *L);
  7119         break;
  7120       case 0x04: //above_equal
  7121         __ slt(AT, op1, op2);
  7122         __ beq_long(AT, R0, *L);
  7123         break;
  7124       case 0x05: //below
  7125         __ slt(AT, op1, op2);
  7126         __ bne_long(R0, AT, *L);
  7127         break;
  7128       case 0x06: //below_equal
  7129         __ slt(AT, op2, op1);
  7130         __ beq_long(AT, R0, *L);
  7131         break;
  7132       default:
  7133         Unimplemented();
  7135   %}
  7137   ins_pc_relative(1);
  7138   ins_pipe( pipe_alu_branch );
  7139 %}
  7141 instruct branchConI_reg_imm0_long(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  7142   match( If cmp (CmpI src1 src2) );
  7143   effect(USE labl);
  7144   ins_cost(170);
  7145   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0_long" %}
  7147   ins_encode %{
  7148     Register op1 = $src1$$Register;
  7149     Label*     L =  $labl$$label;
  7150     int     flag = $cmp$$cmpcode;
  7152     switch(flag) {
  7153       case 0x01: //equal
  7154         __ beq_long(op1, R0, *L);
  7155         break;
  7156       case 0x02: //not_equal
  7157         __ bne_long(op1, R0, *L);
  7158         break;
  7159       case 0x03: //greater
  7160         __ slt(AT, R0, op1);
  7161         __ bne_long(R0, AT, *L);
  7162         break;
  7163       case 0x04: //greater_equal
  7164         __ slt(AT, op1, R0);
  7165         __ beq_long(AT, R0, *L);
  7166         break;
  7167       case 0x05: //less
  7168         __ slt(AT, op1, R0);
  7169         __ bne_long(R0, AT, *L);
  7170         break;
  7171       case 0x06: //less_equal
  7172         __ slt(AT, R0, op1);
  7173         __ beq_long(AT, R0, *L);
  7174         break;
  7175       default:
  7176         Unimplemented();
  7178   %}
  7180   ins_pc_relative(1);
  7181   ins_pipe( pipe_alu_branch );
  7182 %}
  7184 instruct branchConI_reg_imm_long(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  7185   match( If cmp (CmpI src1 src2) );
  7186   effect(USE labl);
  7187   ins_cost(200);
  7188   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm_long" %}
  7190   ins_encode %{
  7191     Register op1 = $src1$$Register;
  7192     int      val = $src2$$constant;
  7193     Label*     L =  $labl$$label;
  7194     int     flag = $cmp$$cmpcode;
  7196     __ move(AT, val);
  7197     switch(flag) {
  7198       case 0x01: //equal
  7199         __ beq_long(op1, AT, *L);
  7200         break;
  7201       case 0x02: //not_equal
  7202         __ bne_long(op1, AT, *L);
  7203         break;
  7204       case 0x03: //greater
  7205         __ slt(AT, AT, op1);
  7206         __ bne_long(R0, AT, *L);
  7207         break;
  7208       case 0x04: //greater_equal
  7209         __ slt(AT, op1, AT);
  7210         __ beq_long(AT, R0, *L);
  7211         break;
  7212       case 0x05: //less
  7213         __ slt(AT, op1, AT);
  7214         __ bne_long(R0, AT, *L);
  7215         break;
  7216       case 0x06: //less_equal
  7217         __ slt(AT, AT, op1);
  7218         __ beq_long(AT, R0, *L);
  7219        break;
  7220       default:
  7221           Unimplemented();
  7223   %}
  7225   ins_pc_relative(1);
  7226   ins_pipe( pipe_alu_branch );
  7227 %}
  7229 instruct branchConIU_reg_imm0_long(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  7230   match( If cmp (CmpU src1 zero) );
  7231   effect(USE labl);
  7232   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0_long" %}
  7234   ins_encode %{
  7235     Register op1 = $src1$$Register;
  7236     Label*     L = $labl$$label;
  7237     int     flag = $cmp$$cmpcode;
  7239     switch(flag) {
  7240       case 0x01: //equal
  7241         __ beq_long(op1, R0, *L);
  7242         break;
  7243       case 0x02: //not_equal
  7244         __ bne_long(op1, R0, *L);
  7245         break;
  7246       case 0x03: //above
  7247         __ bne_long(R0, op1, *L);
  7248         break;
  7249       case 0x04: //above_equal
  7250         __ beq_long(R0, R0, *L);
  7251         break;
  7252       case 0x05: //below
  7253         return;
  7254         break;
  7255       case 0x06: //below_equal
  7256         __ beq_long(op1, R0, *L);
  7257         break;
  7258       default:
  7259         Unimplemented();
  7261   %}
  7263   ins_pc_relative(1);
  7264   ins_pipe( pipe_alu_branch );
  7265 %}
  7268 instruct branchConIU_reg_immI16_long(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  7269   match( If cmp (CmpU src1 src2) );
  7270   effect(USE labl);
  7271   ins_cost(180);
  7272   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16_long" %}
  7274   ins_encode %{
  7275     Register op1 = $src1$$Register;
  7276     int      val = $src2$$constant;
  7277     Label*     L = $labl$$label;
  7278     int     flag = $cmp$$cmpcode;
  7280     switch(flag) {
  7281       case 0x01: //equal
  7282         __ move(AT, val);
  7283         __ beq_long(op1, AT, *L);
  7284         break;
  7285       case 0x02: //not_equal
  7286         __ move(AT, val);
  7287         __ bne_long(op1, AT, *L);
  7288         break;
  7289       case 0x03: //above
  7290         __ move(AT, val);
  7291         __ sltu(AT, AT, op1);
  7292         __ bne_long(R0, AT, *L);
  7293         break;
  7294       case 0x04: //above_equal
  7295         __ sltiu(AT, op1, val);
  7296         __ beq_long(AT, R0, *L);
  7297         break;
  7298       case 0x05: //below
  7299         __ sltiu(AT, op1, val);
  7300         __ bne_long(R0, AT, *L);
  7301         break;
  7302       case 0x06: //below_equal
  7303         __ move(AT, val);
  7304         __ sltu(AT, AT, op1);
  7305         __ beq_long(AT, R0, *L);
  7306         break;
  7307       default:
  7308         Unimplemented();
  7310   %}
  7312   ins_pc_relative(1);
  7313   ins_pipe( pipe_alu_branch );
  7314 %}
  7317 instruct branchConL_regL_regL_long(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  7318   match( If cmp (CmpL src1 src2) );
  7319   effect(USE labl);
  7320   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL_long" %}
  7321   ins_cost(250);
  7323   ins_encode %{
  7324     Register opr1_reg = as_Register($src1$$reg);
  7325     Register opr2_reg = as_Register($src2$$reg);
  7327     Label*   target = $labl$$label;
  7328     int     flag = $cmp$$cmpcode;
  7330     switch(flag) {
  7331       case 0x01: //equal
  7332         __ beq_long(opr1_reg, opr2_reg, *target);
  7333         break;
  7335       case 0x02: //not_equal
  7336         __ bne_long(opr1_reg, opr2_reg, *target);
  7337         break;
  7339       case 0x03: //greater
  7340         __ slt(AT, opr2_reg, opr1_reg);
  7341         __ bne_long(AT, R0, *target);
  7342         break;
  7344       case 0x04: //greater_equal
  7345         __ slt(AT, opr1_reg, opr2_reg);
  7346         __ beq_long(AT, R0, *target);
  7347         break;
  7349       case 0x05: //less
  7350         __ slt(AT, opr1_reg, opr2_reg);
  7351         __ bne_long(AT, R0, *target);
  7352         break;
  7354       case 0x06: //less_equal
  7355         __ slt(AT, opr2_reg, opr1_reg);
  7356         __ beq_long(AT, R0, *target);
  7357         break;
  7359       default:
  7360         Unimplemented();
  7362   %}
  7365   ins_pc_relative(1);
  7366   ins_pipe( pipe_alu_branch );
  7367 %}
  7369 instruct branchConL_regL_immL0_long(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  7370   match( If cmp (CmpL src1 zero) );
  7371   effect(USE labl);
  7372   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0_long" %}
  7373   ins_cost(150);
  7375   ins_encode %{
  7376     Register opr1_reg = as_Register($src1$$reg);
  7377     Register opr2_reg = R0;
  7379     Label*   target = $labl$$label;
  7380     int     flag = $cmp$$cmpcode;
  7382     switch(flag) {
  7383       case 0x01: //equal
  7384         __ beq_long(opr1_reg, opr2_reg, *target);
  7385         break;
  7387       case 0x02: //not_equal
  7388         __ bne_long(opr1_reg, opr2_reg, *target);
  7389         break;
  7391       case 0x03: //greater
  7392         __ slt(AT, opr2_reg, opr1_reg);
  7393         __ bne_long(AT, R0, *target);
  7394         break;
  7396       case 0x04: //greater_equal
  7397         __ slt(AT, opr1_reg, opr2_reg);
  7398         __ beq_long(AT, R0, *target);
  7399         break;
  7401       case 0x05: //less
  7402         __ slt(AT, opr1_reg, opr2_reg);
  7403         __ bne_long(AT, R0, *target);
  7404         break;
  7406       case 0x06: //less_equal
  7407         __ slt(AT, opr2_reg, opr1_reg);
  7408         __ beq_long(AT, R0, *target);
  7409         break;
  7411       default:
  7412         Unimplemented();
  7414   %}
  7417   ins_pc_relative(1);
  7418   ins_pipe( pipe_alu_branch );
  7419 %}
  7421 instruct branchConL_regL_immL_long(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  7422   match( If cmp (CmpL src1 src2) );
  7423   effect(USE labl);
  7424   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL_long" %}
  7425   ins_cost(180);
  7427   ins_encode %{
  7428     Register opr1_reg = as_Register($src1$$reg);
  7429     Register opr2_reg = AT;
  7431     Label*   target = $labl$$label;
  7432     int     flag = $cmp$$cmpcode;
  7434     __ set64(opr2_reg, $src2$$constant);
  7436     switch(flag) {
  7437       case 0x01: //equal
  7438         __ beq_long(opr1_reg, opr2_reg, *target);
  7439         break;
  7441       case 0x02: //not_equal
  7442         __ bne_long(opr1_reg, opr2_reg, *target);
  7443         break;
  7445       case 0x03: //greater
  7446         __ slt(AT, opr2_reg, opr1_reg);
  7447         __ bne_long(AT, R0, *target);
  7448         break;
  7450       case 0x04: //greater_equal
  7451         __ slt(AT, opr1_reg, opr2_reg);
  7452         __ beq_long(AT, R0, *target);
  7453         break;
  7455       case 0x05: //less
  7456         __ slt(AT, opr1_reg, opr2_reg);
  7457         __ bne_long(AT, R0, *target);
  7458         break;
  7460       case 0x06: //less_equal
  7461         __ slt(AT, opr2_reg, opr1_reg);
  7462         __ beq_long(AT, R0, *target);
  7463         break;
  7465       default:
  7466         Unimplemented();
  7468   %}
  7471   ins_pc_relative(1);
  7472   ins_pipe( pipe_alu_branch );
  7473 %}
  7476 //FIXME
  7477 instruct branchConF_reg_reg_long(cmpOp cmp, regF src1, regF src2, label labl) %{
  7478   match( If cmp (CmpF src1 src2) );
  7479   effect(USE labl);
  7480   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg_long" %}
  7482   ins_encode %{
  7483     FloatRegister reg_op1 = $src1$$FloatRegister;
  7484     FloatRegister reg_op2 = $src2$$FloatRegister;
  7485     Label*     L =  $labl$$label;
  7486     int     flag = $cmp$$cmpcode;
  7488     switch(flag) {
  7489       case 0x01: //equal
  7490         __ c_eq_s(reg_op1, reg_op2);
  7491         __ bc1t_long(*L);
  7492         break;
  7493       case 0x02: //not_equal
  7494         __ c_eq_s(reg_op1, reg_op2);
  7495         __ bc1f_long(*L);
  7496         break;
  7497       case 0x03: //greater
  7498         __ c_ule_s(reg_op1, reg_op2);
  7499         __ bc1f_long(*L);
  7500         break;
  7501       case 0x04: //greater_equal
  7502         __ c_ult_s(reg_op1, reg_op2);
  7503         __ bc1f_long(*L);
  7504         break;
  7505       case 0x05: //less
  7506         __ c_ult_s(reg_op1, reg_op2);
  7507         __ bc1t_long(*L);
  7508         break;
  7509       case 0x06: //less_equal
  7510         __ c_ule_s(reg_op1, reg_op2);
  7511         __ bc1t_long(*L);
  7512         break;
  7513       default:
  7514         Unimplemented();
  7516   %}
  7518   ins_pc_relative(1);
  7519   ins_pipe(pipe_slow);
  7520 %}
  7522 instruct branchConD_reg_reg_long(cmpOp cmp, regD src1, regD src2, label labl) %{
  7523   match( If cmp (CmpD src1 src2) );
  7524   effect(USE labl);
  7525   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg_long" %}
  7527   ins_encode %{
  7528     FloatRegister reg_op1 = $src1$$FloatRegister;
  7529     FloatRegister reg_op2 = $src2$$FloatRegister;
  7530     Label*     L =  $labl$$label;
  7531     int     flag = $cmp$$cmpcode;
  7533     switch(flag) {
  7534       case 0x01: //equal
  7535         __ c_eq_d(reg_op1, reg_op2);
  7536         __ bc1t_long(*L);
  7537         break;
  7538       case 0x02: //not_equal
  7539         // c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
  7540         __ c_eq_d(reg_op1, reg_op2);
  7541         __ bc1f_long(*L);
  7542         break;
  7543       case 0x03: //greater
  7544         __ c_ule_d(reg_op1, reg_op2);
  7545         __ bc1f_long(*L);
  7546         break;
  7547       case 0x04: //greater_equal
  7548         __ c_ult_d(reg_op1, reg_op2);
  7549         __ bc1f_long(*L);
  7550         break;
  7551       case 0x05: //less
  7552         __ c_ult_d(reg_op1, reg_op2);
  7553         __ bc1t_long(*L);
  7554         break;
  7555       case 0x06: //less_equal
  7556         __ c_ule_d(reg_op1, reg_op2);
  7557         __ bc1t_long(*L);
  7558         break;
  7559       default:
  7560         Unimplemented();
  7562   %}
  7564   ins_pc_relative(1);
  7565   ins_pipe(pipe_slow);
  7566 %}
  7569 // ============================================================================
  7570 // Branch Instructions -- short offset versions
  7572 // Jump Direct
  7573 instruct jmpDir_short(label labl) %{
  7574   match(Goto);
  7575   effect(USE labl);
  7577   ins_cost(300);
  7578   format %{ "JMP    $labl #@jmpDir_short" %}
  7580   ins_encode %{
  7581     Label &L = *($labl$$label);
  7582     if(&L)
  7583        __ b(L);
  7584     else
  7585        __ b(int(0));
  7586     __ delayed()->nop();
  7587   %}
  7589     ins_pipe( pipe_jump );
  7590     ins_pc_relative(1);
  7591     ins_short_branch(1);
  7592 %}
  7594 // Jump Direct Conditional - Label defines a relative address from Jcc+1
  7595 instruct  jmpLoopEnd_short(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
  7596   match(CountedLoopEnd cop (CmpI src1 src2));
  7597   effect(USE labl);
  7599   ins_cost(300);
  7600   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_short" %}
  7601   ins_encode %{
  7602     Register op1 = $src1$$Register;
  7603     Register op2 = $src2$$Register;
  7604     Label     &L = *($labl$$label);
  7605     int     flag = $cop$$cmpcode;
  7607     switch(flag) {
  7608       case 0x01: //equal
  7609         if (&L)
  7610           __ beq(op1, op2, L);
  7611         else
  7612           __ beq(op1, op2, (int)0);
  7613         break;
  7614       case 0x02: //not_equal
  7615         if (&L)
  7616           __ bne(op1, op2, L);
  7617         else
  7618           __ bne(op1, op2, (int)0);
  7619         break;
  7620       case 0x03: //above
  7621         __ slt(AT, op2, op1);
  7622         if(&L)
  7623           __ bne(AT, R0, L);
  7624         else
  7625           __ bne(AT, R0, (int)0);
  7626         break;
  7627       case 0x04: //above_equal
  7628         __ slt(AT, op1, op2);
  7629         if(&L)
  7630           __ beq(AT, R0, L);
  7631         else
  7632           __ beq(AT, R0, (int)0);
  7633         break;
  7634       case 0x05: //below
  7635         __ slt(AT, op1, op2);
  7636         if(&L)
  7637           __ bne(AT, R0, L);
  7638         else
  7639           __ bne(AT, R0, (int)0);
  7640         break;
  7641       case 0x06: //below_equal
  7642         __ slt(AT, op2, op1);
  7643         if(&L)
  7644           __ beq(AT, R0, L);
  7645         else
  7646           __ beq(AT, R0, (int)0);
  7647         break;
  7648       default:
  7649         Unimplemented();
  7651     __ delayed()->nop();
  7652   %}
  7653   ins_pipe( pipe_jump );
  7654   ins_pc_relative(1);
  7655   ins_short_branch(1);
  7656 %}
  7658 instruct  jmpLoopEnd_reg_immI_short(cmpOp cop, mRegI src1, immI src2, label labl) %{
  7659   match(CountedLoopEnd cop (CmpI src1 src2));
  7660   effect(USE labl);
  7662   ins_cost(300);
  7663   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI_short" %}
  7664   ins_encode %{
  7665     Register op1 = $src1$$Register;
  7666     Register op2 = AT;
  7667     Label     &L = *($labl$$label);
  7668     int     flag = $cop$$cmpcode;
  7670     __ move(op2, $src2$$constant);
  7672     switch(flag) {
  7673       case 0x01: //equal
  7674         if (&L)
  7675           __ beq(op1, op2, L);
  7676         else
  7677           __ beq(op1, op2, (int)0);
  7678         break;
  7679       case 0x02: //not_equal
  7680         if (&L)
  7681           __ bne(op1, op2, L);
  7682         else
  7683           __ bne(op1, op2, (int)0);
  7684         break;
  7685       case 0x03: //above
  7686         __ slt(AT, op2, op1);
  7687         if(&L)
  7688           __ bne(AT, R0, L);
  7689         else
  7690           __ bne(AT, R0, (int)0);
  7691         break;
  7692       case 0x04: //above_equal
  7693         __ slt(AT, op1, op2);
  7694         if(&L)
  7695           __ beq(AT, R0, L);
  7696         else
  7697           __ beq(AT, R0, (int)0);
  7698         break;
  7699       case 0x05: //below
  7700         __ slt(AT, op1, op2);
  7701         if(&L)
  7702           __ bne(AT, R0, L);
  7703         else
  7704           __ bne(AT, R0, (int)0);
  7705         break;
  7706       case 0x06: //below_equal
  7707         __ slt(AT, op2, op1);
  7708         if(&L)
  7709           __ beq(AT, R0, L);
  7710         else
  7711           __ beq(AT, R0, (int)0);
  7712         break;
  7713       default:
  7714         Unimplemented();
  7716     __ delayed()->nop();
  7717   %}
  7718   ins_pipe( pipe_jump );
  7719   ins_pc_relative(1);
  7720   ins_short_branch(1);
  7721 %}
  7724 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
  7725 instruct jmpCon_flags_short(cmpOp cop, FlagsReg cr, label labl) %{
  7726   match(If cop cr);
  7727   effect(USE labl);
  7729   ins_cost(300);
  7730   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags_short" %}
  7732   ins_encode %{
  7733     Label    &L =  *($labl$$label);
  7734     switch($cop$$cmpcode) {
  7735       case 0x01: //equal
  7736         if (&L)
  7737           __ bne(AT, R0, L);
  7738         else
  7739           __ bne(AT, R0, (int)0);
  7740         break;
  7741       case 0x02: //not equal
  7742         if (&L)
  7743           __ beq(AT, R0, L);
  7744         else
  7745           __ beq(AT, R0, (int)0);
  7746         break;
  7747       default:
  7748         Unimplemented();
  7750     __ delayed()->nop();
  7751   %}
  7753   ins_pipe( pipe_jump );
  7754   ins_pc_relative(1);
  7755   ins_short_branch(1);
  7756 %}
  7758 // Conditional jumps
  7759 instruct branchConP_zero_short(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  7760   match(If cmp (CmpP op1 zero));
  7761   effect(USE labl);
  7763   ins_cost(180);
  7764   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero_short" %}
  7766   ins_encode %{
  7767     Register op1 = $op1$$Register;
  7768     Register op2 = R0;
  7769     Label    &L  = *($labl$$label);
  7770     int     flag = $cmp$$cmpcode;
  7772     switch(flag) {
  7773       case 0x01: //equal
  7774         if (&L)
  7775           __ beq(op1, op2, L);
  7776         else
  7777           __ beq(op1, op2, (int)0);
  7778         break;
  7779       case 0x02: //not_equal
  7780         if (&L)
  7781           __ bne(op1, op2, L);
  7782         else
  7783           __ bne(op1, op2, (int)0);
  7784         break;
  7785       default:
  7786         Unimplemented();
  7788     __ delayed()->nop();
  7789   %}
  7791   ins_pc_relative(1);
  7792   ins_pipe( pipe_alu_branch );
  7793   ins_short_branch(1);
  7794 %}
  7796 instruct branchConN2P_zero_short(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  7797   match(If cmp (CmpP (DecodeN op1) zero));
  7798   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  7799   effect(USE labl);
  7801   ins_cost(180);
  7802   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero_short" %}
  7804   ins_encode %{
  7805     Register op1 = $op1$$Register;
  7806     Register op2 = R0;
  7807     Label    &L  = *($labl$$label);
  7808     int     flag = $cmp$$cmpcode;
  7810     switch(flag)
  7812       case 0x01: //equal
  7813         if (&L)
  7814           __ beq(op1, op2, L);
  7815         else
  7816           __ beq(op1, op2, (int)0);
  7817         break;
  7818       case 0x02: //not_equal
  7819         if (&L)
  7820           __ bne(op1, op2, L);
  7821         else
  7822           __ bne(op1, op2, (int)0);
  7823         break;
  7824       default:
  7825         Unimplemented();
  7827     __ delayed()->nop();
  7828   %}
  7830   ins_pc_relative(1);
  7831   ins_pipe( pipe_alu_branch );
  7832   ins_short_branch(1);
  7833 %}
  7836 instruct branchConP_short(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  7837   match(If cmp (CmpP op1 op2));
  7838 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  7839   effect(USE labl);
  7841   ins_cost(200);
  7842   format %{ "b$cmp   $op1, $op2, $labl #@branchConP_short" %}
  7844   ins_encode %{
  7845     Register op1 = $op1$$Register;
  7846     Register op2 = $op2$$Register;
  7847     Label    &L  = *($labl$$label);
  7848     int     flag = $cmp$$cmpcode;
  7850     switch(flag) {
  7851       case 0x01: //equal
  7852         if (&L)
  7853           __ beq(op1, op2, L);
  7854         else
  7855           __ beq(op1, op2, (int)0);
  7856         break;
  7857       case 0x02: //not_equal
  7858         if (&L)
  7859           __ bne(op1, op2, L);
  7860         else
  7861           __ bne(op1, op2, (int)0);
  7862         break;
  7863       case 0x03: //above
  7864         __ sltu(AT, op2, op1);
  7865         if(&L)
  7866           __ bne(R0, AT, L);
  7867         else
  7868                 __ bne(R0, AT, (int)0);
  7869         break;
  7870       case 0x04: //above_equal
  7871         __ sltu(AT, op1, op2);
  7872         if(&L)
  7873                  __ beq(AT, R0, L);
  7874         else
  7875                  __ beq(AT, R0, (int)0);
  7876         break;
  7877       case 0x05: //below
  7878         __ sltu(AT, op1, op2);
  7879         if(&L)
  7880            __ bne(R0, AT, L);
  7881         else
  7882            __ bne(R0, AT, (int)0);
  7883         break;
  7884       case 0x06: //below_equal
  7885         __ sltu(AT, op2, op1);
  7886         if(&L)
  7887           __ beq(AT, R0, L);
  7888         else
  7889           __ beq(AT, R0, (int)0);
  7890        break;
  7891       default:
  7892           Unimplemented();
  7894     __ delayed()->nop();
  7895   %}
  7897   ins_pc_relative(1);
  7898   ins_pipe( pipe_alu_branch );
  7899   ins_short_branch(1);
  7900 %}
  7902 instruct cmpN_null_branch_short(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  7903   match(If cmp (CmpN op1 null));
  7904   effect(USE labl);
  7906   ins_cost(180);
  7907   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  7908             "BP$cmp   $labl @ cmpN_null_branch_short" %}
  7909   ins_encode %{
  7910     Register op1 = $op1$$Register;
  7911     Register op2 = R0;
  7912     Label    &L  = *($labl$$label);
  7913     int     flag = $cmp$$cmpcode;
  7915     switch(flag) {
  7916     case 0x01: //equal
  7917       if (&L)
  7918         __ beq(op1, op2, L);
  7919       else
  7920         __ beq(op1, op2, (int)0);
  7921       break;
  7922     case 0x02: //not_equal
  7923       if (&L)
  7924         __ bne(op1, op2, L);
  7925       else
  7926         __ bne(op1, op2, (int)0);
  7927       break;
  7928     default:
  7929           Unimplemented();
  7931     __ delayed()->nop();
  7932   %}
  7933 //TODO: pipe_branchP or create pipe_branchN LEE
  7934   ins_pc_relative(1);
  7935   ins_pipe( pipe_alu_branch );
  7936   ins_short_branch(1);
  7937 %}
  7939 instruct cmpN_reg_branch_short(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  7940   match(If cmp (CmpN op1 op2));
  7941   effect(USE labl);
  7943   ins_cost(180);
  7944   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  7945             "BP$cmp   $labl @ cmpN_reg_branch_short" %}
  7946   ins_encode %{
  7947     Register op1_reg = $op1$$Register;
  7948     Register op2_reg = $op2$$Register;
  7949     Label    &L  = *($labl$$label);
  7950     int     flag = $cmp$$cmpcode;
  7952     switch(flag) {
  7953     case 0x01: //equal
  7954       if (&L)
  7955         __ beq(op1_reg, op2_reg, L);
  7956       else
  7957         __ beq(op1_reg, op2_reg, (int)0);
  7958       break;
  7959     case 0x02: //not_equal
  7960       if (&L)
  7961         __ bne(op1_reg, op2_reg, L);
  7962       else
  7963         __ bne(op1_reg, op2_reg, (int)0);
  7964       break;
  7965     case 0x03: //above
  7966       __ sltu(AT, op2_reg, op1_reg);
  7967       if(&L)
  7968         __ bne(R0, AT, L);
  7969       else
  7970         __ bne(R0, AT, (int)0);
  7971       break;
  7972     case 0x04: //above_equal
  7973       __ sltu(AT, op1_reg, op2_reg);
  7974       if(&L)
  7975         __ beq(AT, R0, L);
  7976       else
  7977         __ beq(AT, R0, (int)0);
  7978       break;
  7979     case 0x05: //below
  7980       __ sltu(AT, op1_reg, op2_reg);
  7981       if(&L)
  7982         __ bne(R0, AT, L);
  7983       else
  7984         __ bne(R0, AT, (int)0);
  7985       break;
  7986     case 0x06: //below_equal
  7987       __ sltu(AT, op2_reg, op1_reg);
  7988       if(&L)
  7989         __ beq(AT, R0, L);
  7990       else
  7991         __ beq(AT, R0, (int)0);
  7992       break;
  7993     default:
  7994       Unimplemented();
  7996     __ delayed()->nop();
  7997   %}
  7998   ins_pc_relative(1);
  7999   ins_pipe( pipe_alu_branch );
  8000   ins_short_branch(1);
  8001 %}
  8003 instruct branchConIU_reg_reg_short(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  8004   match( If cmp (CmpU src1 src2) );
  8005   effect(USE labl);
  8006   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg_short" %}
  8008   ins_encode %{
  8009     Register op1 = $src1$$Register;
  8010     Register op2 = $src2$$Register;
  8011     Label     &L = *($labl$$label);
  8012     int     flag = $cmp$$cmpcode;
  8014     switch(flag) {
  8015       case 0x01: //equal
  8016         if (&L)
  8017           __ beq(op1, op2, L);
  8018         else
  8019           __ beq(op1, op2, (int)0);
  8020         break;
  8021       case 0x02: //not_equal
  8022         if (&L)
  8023           __ bne(op1, op2, L);
  8024         else
  8025           __ bne(op1, op2, (int)0);
  8026         break;
  8027       case 0x03: //above
  8028         __ sltu(AT, op2, op1);
  8029         if(&L)
  8030           __ bne(AT, R0, L);
  8031         else
  8032                 __ bne(AT, R0, (int)0);
  8033         break;
  8034       case 0x04: //above_equal
  8035         __ sltu(AT, op1, op2);
  8036         if(&L)
  8037           __ beq(AT, R0, L);
  8038         else
  8039                 __ beq(AT, R0, (int)0);
  8040         break;
  8041       case 0x05: //below
  8042         __ sltu(AT, op1, op2);
  8043         if(&L)
  8044            __ bne(AT, R0, L);
  8045         else
  8046            __ bne(AT, R0, (int)0);
  8047         break;
  8048       case 0x06: //below_equal
  8049         __ sltu(AT, op2, op1);
  8050         if(&L)
  8051           __ beq(AT, R0, L);
  8052         else
  8053           __ beq(AT, R0, (int)0);
  8054         break;
  8055       default:
  8056         Unimplemented();
  8058     __ delayed()->nop();
  8059   %}
  8061   ins_pc_relative(1);
  8062   ins_pipe( pipe_alu_branch );
  8063   ins_short_branch(1);
  8064 %}
  8067 instruct branchConIU_reg_imm_short(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  8068   match( If cmp (CmpU src1 src2) );
  8069   effect(USE labl);
  8070   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm_short" %}
  8072   ins_encode %{
  8073     Register op1 = $src1$$Register;
  8074     int      val = $src2$$constant;
  8075     Label     &L = *($labl$$label);
  8076     int     flag = $cmp$$cmpcode;
  8078     __ move(AT, val);
  8079     switch(flag) {
  8080       case 0x01: //equal
  8081         if (&L)
  8082           __ beq(op1, AT, L);
  8083         else
  8084           __ beq(op1, AT, (int)0);
  8085         break;
  8086       case 0x02: //not_equal
  8087         if (&L)
  8088           __ bne(op1, AT, L);
  8089         else
  8090           __ bne(op1, AT, (int)0);
  8091         break;
  8092       case 0x03: //above
  8093         __ sltu(AT, AT, op1);
  8094         if(&L)
  8095           __ bne(R0, AT, L);
  8096         else
  8097                 __ bne(R0, AT, (int)0);
  8098         break;
  8099       case 0x04: //above_equal
  8100         __ sltu(AT, op1, AT);
  8101         if(&L)
  8102           __ beq(AT, R0, L);
  8103         else
  8104                 __ beq(AT, R0, (int)0);
  8105         break;
  8106       case 0x05: //below
  8107         __ sltu(AT, op1, AT);
  8108         if(&L)
  8109            __ bne(R0, AT, L);
  8110         else
  8111            __ bne(R0, AT, (int)0);
  8112         break;
  8113       case 0x06: //below_equal
  8114         __ sltu(AT, AT, op1);
  8115         if(&L)
  8116           __ beq(AT, R0, L);
  8117         else
  8118           __ beq(AT, R0, (int)0);
  8119        break;
  8120       default:
  8121         Unimplemented();
  8123     __ delayed()->nop();
  8124   %}
  8126   ins_pc_relative(1);
  8127   ins_pipe( pipe_alu_branch );
  8128   ins_short_branch(1);
  8129 %}
  8131 instruct branchConI_reg_reg_short(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  8132   match( If cmp (CmpI src1 src2) );
  8133   effect(USE labl);
  8134   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg_short" %}
  8136   ins_encode %{
  8137     Register op1 = $src1$$Register;
  8138     Register op2 = $src2$$Register;
  8139     Label     &L = *($labl$$label);
  8140     int     flag = $cmp$$cmpcode;
  8142     switch(flag) {
  8143       case 0x01: //equal
  8144         if (&L)
  8145           __ beq(op1, op2, L);
  8146         else
  8147           __ beq(op1, op2, (int)0);
  8148         break;
  8149       case 0x02: //not_equal
  8150         if (&L)
  8151           __ bne(op1, op2, L);
  8152         else
  8153           __ bne(op1, op2, (int)0);
  8154         break;
  8155       case 0x03: //above
  8156         __ slt(AT, op2, op1);
  8157         if(&L)
  8158           __ bne(R0, AT, L);
  8159         else
  8160                 __ bne(R0, AT, (int)0);
  8161         break;
  8162       case 0x04: //above_equal
  8163         __ slt(AT, op1, op2);
  8164         if(&L)
  8165           __ beq(AT, R0, L);
  8166         else
  8167                 __ beq(AT, R0, (int)0);
  8168         break;
  8169       case 0x05: //below
  8170         __ slt(AT, op1, op2);
  8171         if(&L)
  8172            __ bne(R0, AT, L);
  8173         else
  8174            __ bne(R0, AT, (int)0);
  8175         break;
  8176       case 0x06: //below_equal
  8177         __ slt(AT, op2, op1);
  8178         if(&L)
  8179           __ beq(AT, R0, L);
  8180         else
  8181           __ beq(AT, R0, (int)0);
  8182        break;
  8183       default:
  8184         Unimplemented();
  8186     __ delayed()->nop();
  8187   %}
  8189   ins_pc_relative(1);
  8190   ins_pipe( pipe_alu_branch );
  8191   ins_short_branch(1);
  8192 %}
  8194 instruct branchConI_reg_imm0_short(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  8195   match( If cmp (CmpI src1 src2) );
  8196   effect(USE labl);
  8197   ins_cost(170);
  8198   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0_short" %}
  8200   ins_encode %{
  8201     Register op1 = $src1$$Register;
  8202     Label     &L =  *($labl$$label);
  8203     int     flag = $cmp$$cmpcode;
  8205     switch(flag) {
  8206       case 0x01: //equal
  8207         if (&L)
  8208           __ beq(op1, R0, L);
  8209         else
  8210           __ beq(op1, R0, (int)0);
  8211         break;
  8212       case 0x02: //not_equal
  8213         if (&L)
  8214           __ bne(op1, R0, L);
  8215         else
  8216           __ bne(op1, R0, (int)0);
  8217         break;
  8218       case 0x03: //greater
  8219         if(&L)
  8220                __ bgtz(op1, L);
  8221         else
  8222                __ bgtz(op1, (int)0);
  8223         break;
  8224       case 0x04: //greater_equal
  8225         if(&L)
  8226                __ bgez(op1, L);
  8227         else
  8228                __ bgez(op1, (int)0);
  8229         break;
  8230       case 0x05: //less
  8231         if(&L)
  8232                 __ bltz(op1, L);
  8233         else
  8234                 __ bltz(op1, (int)0);
  8235         break;
  8236       case 0x06: //less_equal
  8237         if(&L)
  8238                __ blez(op1, L);
  8239         else
  8240                __ blez(op1, (int)0);
  8241        break;
  8242       default:
  8243         Unimplemented();
  8245     __ delayed()->nop();
  8246   %}
  8248   ins_pc_relative(1);
  8249   ins_pipe( pipe_alu_branch );
  8250   ins_short_branch(1);
  8251 %}
  8254 instruct branchConI_reg_imm_short(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  8255   match( If cmp (CmpI src1 src2) );
  8256   effect(USE labl);
  8257   ins_cost(200);
  8258   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm_short" %}
  8260   ins_encode %{
  8261     Register op1 = $src1$$Register;
  8262     int      val = $src2$$constant;
  8263     Label     &L =  *($labl$$label);
  8264     int     flag = $cmp$$cmpcode;
  8266     __ move(AT, val);
  8267     switch(flag) {
  8268       case 0x01: //equal
  8269         if (&L)
  8270           __ beq(op1, AT, L);
  8271         else
  8272           __ beq(op1, AT, (int)0);
  8273         break;
  8274       case 0x02: //not_equal
  8275         if (&L)
  8276           __ bne(op1, AT, L);
  8277         else
  8278           __ bne(op1, AT, (int)0);
  8279         break;
  8280       case 0x03: //greater
  8281         __ slt(AT, AT, op1);
  8282         if(&L)
  8283           __ bne(R0, AT, L);
  8284         else
  8285                 __ bne(R0, AT, (int)0);
  8286         break;
  8287       case 0x04: //greater_equal
  8288         __ slt(AT, op1, AT);
  8289         if(&L)
  8290           __ beq(AT, R0, L);
  8291         else
  8292                 __ beq(AT, R0, (int)0);
  8293         break;
  8294       case 0x05: //less
  8295         __ slt(AT, op1, AT);
  8296         if(&L)
  8297            __ bne(R0, AT, L);
  8298         else
  8299            __ bne(R0, AT, (int)0);
  8300         break;
  8301       case 0x06: //less_equal
  8302         __ slt(AT, AT, op1);
  8303         if(&L)
  8304           __ beq(AT, R0, L);
  8305         else
  8306           __ beq(AT, R0, (int)0);
  8307        break;
  8308       default:
  8309           Unimplemented();
  8311     __ delayed()->nop();
  8312   %}
  8314   ins_pc_relative(1);
  8315   ins_pipe( pipe_alu_branch );
  8316   ins_short_branch(1);
  8317 %}
  8319 instruct branchConIU_reg_imm0_short(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  8320   match( If cmp (CmpU src1 zero) );
  8321   effect(USE labl);
  8322   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0_short" %}
  8324   ins_encode %{
  8325     Register op1 = $src1$$Register;
  8326     Label     &L = *($labl$$label);
  8327     int     flag = $cmp$$cmpcode;
  8329     switch(flag) {
  8330       case 0x01: //equal
  8331         if (&L)
  8332           __ beq(op1, R0, L);
  8333         else
  8334           __ beq(op1, R0, (int)0);
  8335         break;
  8336       case 0x02: //not_equal
  8337         if (&L)
  8338           __ bne(op1, R0, L);
  8339         else
  8340           __ bne(op1, R0, (int)0);
  8341         break;
  8342       case 0x03: //above
  8343         if(&L)
  8344           __ bne(R0, op1, L);
  8345         else
  8346           __ bne(R0, op1, (int)0);
  8347         break;
  8348       case 0x04: //above_equal
  8349         if(&L)
  8350           __ beq(R0, R0, L);
  8351         else
  8352           __ beq(R0, R0, (int)0);
  8353         break;
  8354       case 0x05: //below
  8355         return;
  8356         break;
  8357       case 0x06: //below_equal
  8358         if(&L)
  8359           __ beq(op1, R0, L);
  8360         else
  8361           __ beq(op1, R0, (int)0);
  8362         break;
  8363       default:
  8364         Unimplemented();
  8366     __ delayed()->nop();
  8367     %}
  8369   ins_pc_relative(1);
  8370   ins_pipe( pipe_alu_branch );
  8371   ins_short_branch(1);
  8372 %}
  8375 instruct branchConIU_reg_immI16_short(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  8376   match( If cmp (CmpU src1 src2) );
  8377   effect(USE labl);
  8378   ins_cost(180);
  8379   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16_short" %}
  8381   ins_encode %{
  8382     Register op1 = $src1$$Register;
  8383     int      val = $src2$$constant;
  8384     Label     &L = *($labl$$label);
  8385     int     flag = $cmp$$cmpcode;
  8387     switch(flag) {
  8388       case 0x01: //equal
  8389         __ move(AT, val);
  8390         if (&L)
  8391           __ beq(op1, AT, L);
  8392         else
  8393           __ beq(op1, AT, (int)0);
  8394         break;
  8395       case 0x02: //not_equal
  8396         __ move(AT, val);
  8397         if (&L)
  8398           __ bne(op1, AT, L);
  8399         else
  8400           __ bne(op1, AT, (int)0);
  8401         break;
  8402       case 0x03: //above
  8403         __ move(AT, val);
  8404         __ sltu(AT, AT, op1);
  8405         if(&L)
  8406           __ bne(R0, AT, L);
  8407         else
  8408           __ bne(R0, AT, (int)0);
  8409         break;
  8410       case 0x04: //above_equal
  8411         __ sltiu(AT, op1, val);
  8412         if(&L)
  8413           __ beq(AT, R0, L);
  8414         else
  8415           __ beq(AT, R0, (int)0);
  8416         break;
  8417       case 0x05: //below
  8418         __ sltiu(AT, op1, val);
  8419         if(&L)
  8420           __ bne(R0, AT, L);
  8421         else
  8422           __ bne(R0, AT, (int)0);
  8423         break;
  8424       case 0x06: //below_equal
  8425         __ move(AT, val);
  8426         __ sltu(AT, AT, op1);
  8427         if(&L)
  8428           __ beq(AT, R0, L);
  8429         else
  8430           __ beq(AT, R0, (int)0);
  8431         break;
  8432       default:
  8433         Unimplemented();
  8435     __ delayed()->nop();
  8436   %}
  8438   ins_pc_relative(1);
  8439   ins_pipe( pipe_alu_branch );
  8440   ins_short_branch(1);
  8441 %}
  8444 instruct branchConL_regL_regL_short(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  8445   match( If cmp (CmpL src1 src2) );
  8446   effect(USE labl);
  8447   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL_short" %}
  8448   ins_cost(250);
  8450   ins_encode %{
  8451     Register opr1_reg = as_Register($src1$$reg);
  8452     Register opr2_reg = as_Register($src2$$reg);
  8454     Label   &target = *($labl$$label);
  8455     int     flag = $cmp$$cmpcode;
  8457     switch(flag) {
  8458       case 0x01: //equal
  8459         if (&target)
  8460           __ beq(opr1_reg, opr2_reg, target);
  8461         else
  8462           __ beq(opr1_reg, opr2_reg, (int)0);
  8463         __ delayed()->nop();
  8464         break;
  8466       case 0x02: //not_equal
  8467         if(&target)
  8468           __ bne(opr1_reg, opr2_reg, target);
  8469         else
  8470           __ bne(opr1_reg, opr2_reg, (int)0);
  8471         __ delayed()->nop();
  8472         break;
  8474       case 0x03: //greater
  8475         __ slt(AT, opr2_reg, opr1_reg);
  8476         if(&target)
  8477           __ bne(AT, R0, target);
  8478         else
  8479           __ bne(AT, R0, (int)0);
  8480         __ delayed()->nop();
  8481         break;
  8483       case 0x04: //greater_equal
  8484         __ slt(AT, opr1_reg, opr2_reg);
  8485         if(&target)
  8486           __ beq(AT, R0, target);
  8487         else
  8488           __ beq(AT, R0, (int)0);
  8489         __ delayed()->nop();
  8491         break;
  8493       case 0x05: //less
  8494         __ slt(AT, opr1_reg, opr2_reg);
  8495         if(&target)
  8496           __ bne(AT, R0, target);
  8497         else
  8498           __ bne(AT, R0, (int)0);
  8499         __ delayed()->nop();
  8501         break;
  8503       case 0x06: //less_equal
  8504         __ slt(AT, opr2_reg, opr1_reg);
  8506         if(&target)
  8507           __ beq(AT, R0, target);
  8508         else
  8509           __ beq(AT, R0, (int)0);
  8510         __ delayed()->nop();
  8512         break;
  8514       default:
  8515         Unimplemented();
  8517   %}
  8520   ins_pc_relative(1);
  8521   ins_pipe( pipe_alu_branch );
  8522   ins_short_branch(1);
  8523 %}
  8526 instruct branchConL_regL_immL0_short(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  8527   match( If cmp (CmpL src1 zero) );
  8528   effect(USE labl);
  8529   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0_short" %}
  8530   ins_cost(150);
  8532   ins_encode %{
  8533     Register opr1_reg = as_Register($src1$$reg);
  8534     Label   &target = *($labl$$label);
  8535     int     flag = $cmp$$cmpcode;
  8537     switch(flag) {
  8538       case 0x01: //equal
  8539         if (&target)
  8540            __ beq(opr1_reg, R0, target);
  8541         else
  8542            __ beq(opr1_reg, R0, int(0));
  8543         break;
  8545       case 0x02: //not_equal
  8546         if(&target)
  8547            __ bne(opr1_reg, R0, target);
  8548         else
  8549            __ bne(opr1_reg, R0, (int)0);
  8550         break;
  8552       case 0x03: //greater
  8553         if(&target)
  8554            __ bgtz(opr1_reg, target);
  8555         else
  8556            __ bgtz(opr1_reg, (int)0);
  8557        break;
  8559       case 0x04: //greater_equal
  8560         if(&target)
  8561            __ bgez(opr1_reg, target);
  8562         else
  8563            __ bgez(opr1_reg, (int)0);
  8564         break;
  8566       case 0x05: //less
  8567         __ slt(AT, opr1_reg, R0);
  8568         if(&target)
  8569            __ bne(AT, R0, target);
  8570         else
  8571            __ bne(AT, R0, (int)0);
  8572         break;
  8574       case 0x06: //less_equal
  8575         if (&target)
  8576            __ blez(opr1_reg, target);
  8577         else
  8578            __ blez(opr1_reg, int(0));
  8579         break;
  8581       default:
  8582           Unimplemented();
  8584     __ delayed()->nop();
  8585   %}
  8588   ins_pc_relative(1);
  8589   ins_pipe( pipe_alu_branch );
  8590   ins_short_branch(1);
  8591 %}
  8593 instruct branchConL_regL_immL_short(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  8594   match( If cmp (CmpL src1 src2) );
  8595   effect(USE labl);
  8596   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL_short" %}
  8597   ins_cost(180);
  8599   ins_encode %{
  8600     Register opr1_reg = as_Register($src1$$reg);
  8601     Register opr2_reg = AT;
  8603     Label   &target = *($labl$$label);
  8604     int     flag = $cmp$$cmpcode;
  8606     __ set64(opr2_reg, $src2$$constant);
  8608     switch(flag) {
  8609       case 0x01: //equal
  8610         if (&target)
  8611           __ beq(opr1_reg, opr2_reg, target);
  8612         else
  8613           __ beq(opr1_reg, opr2_reg, (int)0);
  8614         break;
  8616       case 0x02: //not_equal
  8617         if(&target)
  8618           __ bne(opr1_reg, opr2_reg, target);
  8619         else
  8620           __ bne(opr1_reg, opr2_reg, (int)0);
  8621         break;
  8623       case 0x03: //greater
  8624         __ slt(AT, opr2_reg, opr1_reg);
  8625         if(&target)
  8626           __ bne(AT, R0, target);
  8627         else
  8628           __ bne(AT, R0, (int)0);
  8629         break;
  8631       case 0x04: //greater_equal
  8632         __ slt(AT, opr1_reg, opr2_reg);
  8633         if(&target)
  8634           __ beq(AT, R0, target);
  8635         else
  8636           __ beq(AT, R0, (int)0);
  8637         break;
  8639       case 0x05: //less
  8640         __ slt(AT, opr1_reg, opr2_reg);
  8641         if(&target)
  8642           __ bne(AT, R0, target);
  8643         else
  8644           __ bne(AT, R0, (int)0);
  8645         break;
  8647       case 0x06: //less_equal
  8648         __ slt(AT, opr2_reg, opr1_reg);
  8649         if(&target)
  8650           __ beq(AT, R0, target);
  8651         else
  8652           __ beq(AT, R0, (int)0);
  8653         break;
  8655       default:
  8656         Unimplemented();
  8658     __ delayed()->nop();
  8659   %}
  8662   ins_pc_relative(1);
  8663   ins_pipe( pipe_alu_branch );
  8664   ins_short_branch(1);
  8665 %}
  8668 //FIXME
  8669 instruct branchConF_reg_reg_short(cmpOp cmp, regF src1, regF src2, label labl) %{
  8670   match( If cmp (CmpF src1 src2) );
  8671   effect(USE labl);
  8672   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg_short" %}
  8674   ins_encode %{
  8675     FloatRegister reg_op1 = $src1$$FloatRegister;
  8676     FloatRegister reg_op2 = $src2$$FloatRegister;
  8677     Label     &L =  *($labl$$label);
  8678     int     flag = $cmp$$cmpcode;
  8680     switch(flag) {
  8681       case 0x01: //equal
  8682         __ c_eq_s(reg_op1, reg_op2);
  8683         if (&L)
  8684           __ bc1t(L);
  8685         else
  8686           __ bc1t((int)0);
  8687         break;
  8688       case 0x02: //not_equal
  8689         __ c_eq_s(reg_op1, reg_op2);
  8690         if (&L)
  8691           __ bc1f(L);
  8692         else
  8693           __ bc1f((int)0);
  8694         break;
  8695       case 0x03: //greater
  8696         __ c_ule_s(reg_op1, reg_op2);
  8697         if(&L)
  8698           __ bc1f(L);
  8699         else
  8700           __ bc1f((int)0);
  8701         break;
  8702       case 0x04: //greater_equal
  8703         __ c_ult_s(reg_op1, reg_op2);
  8704         if(&L)
  8705           __ bc1f(L);
  8706         else
  8707           __ bc1f((int)0);
  8708         break;
  8709       case 0x05: //less
  8710         __ c_ult_s(reg_op1, reg_op2);
  8711         if(&L)
  8712           __ bc1t(L);
  8713         else
  8714           __ bc1t((int)0);
  8715         break;
  8716       case 0x06: //less_equal
  8717         __ c_ule_s(reg_op1, reg_op2);
  8718         if(&L)
  8719           __ bc1t(L);
  8720         else
  8721           __ bc1t((int)0);
  8722         break;
  8723       default:
  8724         Unimplemented();
  8726     __ delayed()->nop();
  8727   %}
  8729   ins_pc_relative(1);
  8730   ins_pipe(pipe_slow);
  8731   ins_short_branch(1);
  8732 %}
  8734 instruct branchConD_reg_reg_short(cmpOp cmp, regD src1, regD src2, label labl) %{
  8735   match( If cmp (CmpD src1 src2) );
  8736   effect(USE labl);
  8737   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg_short" %}
  8739   ins_encode %{
  8740     FloatRegister reg_op1 = $src1$$FloatRegister;
  8741     FloatRegister reg_op2 = $src2$$FloatRegister;
  8742     Label     &L =  *($labl$$label);
  8743     int     flag = $cmp$$cmpcode;
  8745     switch(flag) {
  8746       case 0x01: //equal
  8747         __ c_eq_d(reg_op1, reg_op2);
  8748         if (&L)
  8749           __ bc1t(L);
  8750         else
  8751           __ bc1t((int)0);
  8752         break;
  8753       case 0x02: //not_equal
  8754         // c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
  8755         __ c_eq_d(reg_op1, reg_op2);
  8756         if (&L)
  8757           __ bc1f(L);
  8758         else
  8759           __ bc1f((int)0);
  8760         break;
  8761       case 0x03: //greater
  8762         __ c_ule_d(reg_op1, reg_op2);
  8763         if(&L)
  8764           __ bc1f(L);
  8765         else
  8766           __ bc1f((int)0);
  8767         break;
  8768       case 0x04: //greater_equal
  8769         __ c_ult_d(reg_op1, reg_op2);
  8770         if(&L)
  8771           __ bc1f(L);
  8772         else
  8773           __ bc1f((int)0);
  8774         break;
  8775       case 0x05: //less
  8776         __ c_ult_d(reg_op1, reg_op2);
  8777         if(&L)
  8778           __ bc1t(L);
  8779         else
  8780           __ bc1t((int)0);
  8781         break;
  8782       case 0x06: //less_equal
  8783         __ c_ule_d(reg_op1, reg_op2);
  8784         if(&L)
  8785           __ bc1t(L);
  8786         else
  8787           __ bc1t((int)0);
  8788         break;
  8789       default:
  8790         Unimplemented();
  8792     __ delayed()->nop();
  8793   %}
  8795   ins_pc_relative(1);
  8796   ins_pipe(pipe_slow);
  8797   ins_short_branch(1);
  8798 %}
  8800 // =================== End of branch instructions ==========================
  8802 // Call Runtime Instruction
  8803 instruct CallRuntimeDirect(method meth) %{
  8804   match(CallRuntime );
  8805   effect(USE meth);
  8807   ins_cost(300);
  8808   format %{ "CALL,runtime #@CallRuntimeDirect" %}
  8809   ins_encode( Java_To_Runtime( meth ) );
  8810   ins_pipe( pipe_slow );
  8811   ins_alignment(16);
  8812 %}
  8816 //------------------------MemBar Instructions-------------------------------
  8817 //Memory barrier flavors
  8819 instruct membar_acquire() %{
  8820   match(MemBarAcquire);
  8821   ins_cost(400);
  8823   format %{ "MEMBAR-acquire @ membar_acquire" %}
  8824   ins_encode %{
  8825     __ sync();
  8826   %}
  8827   ins_pipe(empty);
  8828 %}
  8830 instruct load_fence() %{
  8831   match(LoadFence);
  8832   ins_cost(400);
  8834   format %{ "MEMBAR @ load_fence" %}
  8835   ins_encode %{
  8836     __ sync();
  8837   %}
  8838   ins_pipe(pipe_slow);
  8839 %}
  8841 instruct membar_acquire_lock()
  8842 %{
  8843   match(MemBarAcquireLock);
  8844   ins_cost(0);
  8846   size(0);
  8847   format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
  8848   ins_encode();
  8849   ins_pipe(empty);
  8850 %}
  8852 instruct membar_release() %{
  8853   match(MemBarRelease);
  8854   ins_cost(400);
  8856   format %{ "MEMBAR-release @ membar_release" %}
  8858   ins_encode %{
  8859     // Attention: DO NOT DELETE THIS GUY!
  8860     __ sync();
  8861   %}
  8863   ins_pipe(pipe_slow);
  8864 %}
  8866 instruct store_fence() %{
  8867   match(StoreFence);
  8868   ins_cost(400);
  8870   format %{ "MEMBAR @ store_fence" %}
  8872   ins_encode %{
  8873     __ sync();
  8874   %}
  8876   ins_pipe(pipe_slow);
  8877 %}
  8879 instruct membar_release_lock()
  8880 %{
  8881   match(MemBarReleaseLock);
  8882   ins_cost(0);
  8884   size(0);
  8885   format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
  8886   ins_encode();
  8887   ins_pipe(empty);
  8888 %}
  8891 instruct membar_volatile() %{
  8892   match(MemBarVolatile);
  8893   ins_cost(400);
  8895   format %{ "MEMBAR-volatile" %}
  8896   ins_encode %{
  8897     if( !os::is_MP() ) return;     // Not needed on single CPU
  8898     __ sync();
  8900   %}
  8901   ins_pipe(pipe_slow);
  8902 %}
  8904 instruct unnecessary_membar_volatile() %{
  8905   match(MemBarVolatile);
  8906   predicate(Matcher::post_store_load_barrier(n));
  8907   ins_cost(0);
  8909   size(0);
  8910   format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
  8911   ins_encode( );
  8912   ins_pipe(empty);
  8913 %}
  8915 instruct membar_storestore() %{
  8916   match(MemBarStoreStore);
  8918   ins_cost(400);
  8919   format %{ "MEMBAR-storestore @ membar_storestore" %}
  8920   ins_encode %{
  8921     __ sync();
  8922   %}
  8923   ins_pipe(empty);
  8924 %}
  8926 //----------Move Instructions--------------------------------------------------
  8927 instruct castX2P(mRegP dst, mRegL src) %{
  8928   match(Set dst (CastX2P src));
  8929   format %{ "castX2P  $dst, $src @ castX2P" %}
  8930   ins_encode %{
  8931     Register src = $src$$Register;
  8932     Register dst = $dst$$Register;
  8934   if(src != dst)
  8935     __ move(dst, src);
  8936   %}
  8937   ins_cost(10);
  8938   ins_pipe( ialu_regI_mov );
  8939 %}
  8941 instruct castP2X(mRegL dst, mRegP src ) %{
  8942   match(Set dst (CastP2X src));
  8944   format %{ "mov    $dst, $src\t  #@castP2X" %}
  8945   ins_encode %{
  8946     Register src = $src$$Register;
  8947     Register dst = $dst$$Register;
  8949   if(src != dst)
  8950     __ move(dst, src);
  8951   %}
  8952   ins_pipe( ialu_regI_mov );
  8953 %}
  8955 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
  8956   match(Set dst (MoveF2I src));
  8957   effect(DEF dst, USE src);
  8958   ins_cost(85);
  8959   format %{ "MoveF2I   $dst, $src @ MoveF2I_reg_reg" %}
  8960   ins_encode %{
  8961     Register dst = as_Register($dst$$reg);
  8962     FloatRegister src = as_FloatRegister($src$$reg);
  8964     __ mfc1(dst, src);
  8965   %}
  8966   ins_pipe( pipe_slow );
  8967 %}
  8969 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
  8970   match(Set dst (MoveI2F src));
  8971   effect(DEF dst, USE src);
  8972   ins_cost(85);
  8973   format %{ "MoveI2F   $dst, $src @ MoveI2F_reg_reg" %}
  8974   ins_encode %{
  8975     Register src = as_Register($src$$reg);
  8976     FloatRegister dst = as_FloatRegister($dst$$reg);
  8978     __ mtc1(src, dst);
  8979   %}
  8980   ins_pipe( pipe_slow );
  8981 %}
  8983 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
  8984   match(Set dst (MoveD2L src));
  8985   effect(DEF dst, USE src);
  8986   ins_cost(85);
  8987   format %{ "MoveD2L   $dst, $src @ MoveD2L_reg_reg" %}
  8988   ins_encode %{
  8989     Register dst = as_Register($dst$$reg);
  8990     FloatRegister src = as_FloatRegister($src$$reg);
  8992     __ dmfc1(dst, src);
  8993   %}
  8994   ins_pipe( pipe_slow );
  8995 %}
  8997 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
  8998   match(Set dst (MoveL2D src));
  8999   effect(DEF dst, USE src);
  9000   ins_cost(85);
  9001   format %{ "MoveL2D   $dst, $src @ MoveL2D_reg_reg" %}
  9002   ins_encode %{
  9003     FloatRegister dst = as_FloatRegister($dst$$reg);
  9004     Register src = as_Register($src$$reg);
  9006     __ dmtc1(src, dst);
  9007   %}
  9008   ins_pipe( pipe_slow );
  9009 %}
  9011 //----------Conditional Move---------------------------------------------------
  9012 // Conditional move
  9013 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9014   match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9015   ins_cost(80);
  9016   format %{
  9017              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpI_reg_reg\n"
  9018              "\tCMOV  $dst,$src \t @cmovI_cmpI_reg_reg"
  9019          %}
  9021   ins_encode %{
  9022     Register op1 = $tmp1$$Register;
  9023     Register op2 = $tmp2$$Register;
  9024     Register dst = $dst$$Register;
  9025     Register src = $src$$Register;
  9026     int     flag = $cop$$cmpcode;
  9028     switch(flag) {
  9029       case 0x01: //equal
  9030         __ subu32(AT, op1, op2);
  9031         __ movz(dst, src, AT);
  9032         break;
  9034       case 0x02: //not_equal
  9035         __ subu32(AT, op1, op2);
  9036         __ movn(dst, src, AT);
  9037         break;
  9039       case 0x03: //great
  9040         __ slt(AT, op2, op1);
  9041         __ movn(dst, src, AT);
  9042         break;
  9044       case 0x04: //great_equal
  9045         __ slt(AT, op1, op2);
  9046         __ movz(dst, src, AT);
  9047         break;
  9049       case 0x05: //less
  9050         __ slt(AT, op1, op2);
  9051         __ movn(dst, src, AT);
  9052         break;
  9054       case 0x06: //less_equal
  9055         __ slt(AT, op2, op1);
  9056         __ movz(dst, src, AT);
  9057        break;
  9059       default:
  9060         Unimplemented();
  9062   %}
  9064   ins_pipe( pipe_slow );
  9065 %}
  9067 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9068   match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9069   ins_cost(80);
  9070   format %{
  9071              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
  9072              "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
  9073          %}
  9074   ins_encode %{
  9075     Register op1 = $tmp1$$Register;
  9076     Register op2 = $tmp2$$Register;
  9077     Register dst = $dst$$Register;
  9078     Register src = $src$$Register;
  9079     int     flag = $cop$$cmpcode;
  9081     switch(flag) {
  9082       case 0x01: //equal
  9083         __ subu(AT, op1, op2);
  9084         __ movz(dst, src, AT);
  9085         break;
  9087       case 0x02: //not_equal
  9088         __ subu(AT, op1, op2);
  9089         __ movn(dst, src, AT);
  9090         break;
  9092       case 0x03: //above
  9093         __ sltu(AT, op2, op1);
  9094         __ movn(dst, src, AT);
  9095         break;
  9097       case 0x04: //above_equal
  9098         __ sltu(AT, op1, op2);
  9099         __ movz(dst, src, AT);
  9100         break;
  9102       case 0x05: //below
  9103         __ sltu(AT, op1, op2);
  9104         __ movn(dst, src, AT);
  9105         break;
  9107       case 0x06: //below_equal
  9108         __ sltu(AT, op2, op1);
  9109         __ movz(dst, src, AT);
  9110        break;
  9112       default:
  9113         Unimplemented();
  9115   %}
  9117   ins_pipe( pipe_slow );
  9118 %}
  9120 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9121   match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9122   ins_cost(80);
  9123   format %{
  9124              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
  9125              "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
  9126          %}
  9127   ins_encode %{
  9128     Register op1 = $tmp1$$Register;
  9129     Register op2 = $tmp2$$Register;
  9130     Register dst = $dst$$Register;
  9131     Register src = $src$$Register;
  9132     int     flag = $cop$$cmpcode;
  9134     switch(flag) {
  9135       case 0x01: //equal
  9136         __ subu32(AT, op1, op2);
  9137         __ movz(dst, src, AT);
  9138         break;
  9140       case 0x02: //not_equal
  9141         __ subu32(AT, op1, op2);
  9142         __ movn(dst, src, AT);
  9143         break;
  9145       case 0x03: //above
  9146         __ sltu(AT, op2, op1);
  9147         __ movn(dst, src, AT);
  9148         break;
  9150       case 0x04: //above_equal
  9151         __ sltu(AT, op1, op2);
  9152         __ movz(dst, src, AT);
  9153         break;
  9155       case 0x05: //below
  9156         __ sltu(AT, op1, op2);
  9157         __ movn(dst, src, AT);
  9158         break;
  9160       case 0x06: //below_equal
  9161         __ sltu(AT, op2, op1);
  9162         __ movz(dst, src, AT);
  9163        break;
  9165       default:
  9166           Unimplemented();
  9168   %}
  9170   ins_pipe( pipe_slow );
  9171 %}
  9173 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9174   match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9175   ins_cost(80);
  9176   format %{
  9177              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
  9178              "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
  9179          %}
  9180   ins_encode %{
  9181     Register op1 = $tmp1$$Register;
  9182     Register op2 = $tmp2$$Register;
  9183     Register dst = $dst$$Register;
  9184     Register src = $src$$Register;
  9185     int     flag = $cop$$cmpcode;
  9187     switch(flag) {
  9188       case 0x01: //equal
  9189         __ subu32(AT, op1, op2);
  9190         __ movz(dst, src, AT);
  9191         break;
  9193       case 0x02: //not_equal
  9194         __ subu32(AT, op1, op2);
  9195         __ movn(dst, src, AT);
  9196         break;
  9198       case 0x03: //above
  9199         __ sltu(AT, op2, op1);
  9200         __ movn(dst, src, AT);
  9201         break;
  9203       case 0x04: //above_equal
  9204         __ sltu(AT, op1, op2);
  9205         __ movz(dst, src, AT);
  9206         break;
  9208       case 0x05: //below
  9209         __ sltu(AT, op1, op2);
  9210         __ movn(dst, src, AT);
  9211         break;
  9213       case 0x06: //below_equal
  9214         __ sltu(AT, op2, op1);
  9215         __ movz(dst, src, AT);
  9216        break;
  9218       default:
  9219           Unimplemented();
  9221   %}
  9223   ins_pipe( pipe_slow );
  9224 %}
  9226 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9227   match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9228   ins_cost(80);
  9229   format %{
  9230              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpF_reg_reg\n"
  9231              "\tCMOV  $dst,$src \t @cmovP_cmpF_reg_reg"
  9232          %}
  9234   ins_encode %{
  9235     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9236     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9237     Register dst = $dst$$Register;
  9238     Register src = $src$$Register;
  9239     int     flag = $cop$$cmpcode;
  9241     switch(flag) {
  9242       case 0x01: //equal
  9243         __ c_eq_s(reg_op1, reg_op2);
  9244         __ movt(dst, src);
  9245         break;
  9246       case 0x02: //not_equal
  9247         __ c_eq_s(reg_op1, reg_op2);
  9248         __ movf(dst, src);
  9249         break;
  9250       case 0x03: //greater
  9251         __ c_ole_s(reg_op1, reg_op2);
  9252         __ movf(dst, src);
  9253         break;
  9254       case 0x04: //greater_equal
  9255         __ c_olt_s(reg_op1, reg_op2);
  9256         __ movf(dst, src);
  9257         break;
  9258       case 0x05: //less
  9259         __ c_ult_s(reg_op1, reg_op2);
  9260         __ movt(dst, src);
  9261         break;
  9262       case 0x06: //less_equal
  9263         __ c_ule_s(reg_op1, reg_op2);
  9264         __ movt(dst, src);
  9265         break;
  9266       default:
  9267         Unimplemented();
  9269   %}
  9270   ins_pipe( pipe_slow );
  9271 %}
  9273 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9274   match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9275   ins_cost(80);
  9276   format %{
  9277              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
  9278              "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
  9279          %}
  9280   ins_encode %{
  9281     Register op1 = $tmp1$$Register;
  9282     Register op2 = $tmp2$$Register;
  9283     Register dst = $dst$$Register;
  9284     Register src = $src$$Register;
  9285     int     flag = $cop$$cmpcode;
  9287     switch(flag) {
  9288       case 0x01: //equal
  9289         __ subu32(AT, op1, op2);
  9290         __ movz(dst, src, AT);
  9291         break;
  9293       case 0x02: //not_equal
  9294         __ subu32(AT, op1, op2);
  9295         __ movn(dst, src, AT);
  9296         break;
  9298       case 0x03: //above
  9299         __ sltu(AT, op2, op1);
  9300         __ movn(dst, src, AT);
  9301         break;
  9303       case 0x04: //above_equal
  9304         __ sltu(AT, op1, op2);
  9305         __ movz(dst, src, AT);
  9306         break;
  9308       case 0x05: //below
  9309         __ sltu(AT, op1, op2);
  9310         __ movn(dst, src, AT);
  9311         break;
  9313       case 0x06: //below_equal
  9314         __ sltu(AT, op2, op1);
  9315         __ movz(dst, src, AT);
  9316        break;
  9318       default:
  9319         Unimplemented();
  9321   %}
  9323   ins_pipe( pipe_slow );
  9324 %}
  9326 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9327   match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9328   ins_cost(80);
  9329   format %{
  9330              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
  9331              "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
  9332          %}
  9333   ins_encode %{
  9334     Register op1 = $tmp1$$Register;
  9335     Register op2 = $tmp2$$Register;
  9336     Register dst = $dst$$Register;
  9337     Register src = $src$$Register;
  9338     int     flag = $cop$$cmpcode;
  9340     switch(flag) {
  9341       case 0x01: //equal
  9342         __ subu(AT, op1, op2);
  9343         __ movz(dst, src, AT);
  9344         break;
  9346       case 0x02: //not_equal
  9347         __ subu(AT, op1, op2);
  9348         __ movn(dst, src, AT);
  9349         break;
  9351       case 0x03: //above
  9352         __ sltu(AT, op2, op1);
  9353         __ movn(dst, src, AT);
  9354         break;
  9356       case 0x04: //above_equal
  9357         __ sltu(AT, op1, op2);
  9358         __ movz(dst, src, AT);
  9359         break;
  9361       case 0x05: //below
  9362         __ sltu(AT, op1, op2);
  9363         __ movn(dst, src, AT);
  9364         break;
  9366       case 0x06: //below_equal
  9367         __ sltu(AT, op2, op1);
  9368         __ movz(dst, src, AT);
  9369         break;
  9371       default:
  9372         Unimplemented();
  9374   %}
  9376   ins_pipe( pipe_slow );
  9377 %}
  9379 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9380   match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9381   ins_cost(80);
  9382   format %{
  9383              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpD_reg_reg\n"
  9384              "\tCMOV  $dst,$src \t @cmovP_cmpD_reg_reg"
  9385          %}
  9386   ins_encode %{
  9387     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9388     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9389     Register dst = as_Register($dst$$reg);
  9390     Register src = as_Register($src$$reg);
  9392     int     flag = $cop$$cmpcode;
  9394     switch(flag) {
  9395       case 0x01: //equal
  9396         __ c_eq_d(reg_op1, reg_op2);
  9397         __ movt(dst, src);
  9398         break;
  9399       case 0x02: //not_equal
  9400         __ c_eq_d(reg_op1, reg_op2);
  9401         __ movf(dst, src);
  9402         break;
  9403       case 0x03: //greater
  9404         __ c_ole_d(reg_op1, reg_op2);
  9405         __ movf(dst, src);
  9406         break;
  9407       case 0x04: //greater_equal
  9408         __ c_olt_d(reg_op1, reg_op2);
  9409         __ movf(dst, src);
  9410         break;
  9411       case 0x05: //less
  9412         __ c_ult_d(reg_op1, reg_op2);
  9413         __ movt(dst, src);
  9414         break;
  9415       case 0x06: //less_equal
  9416         __ c_ule_d(reg_op1, reg_op2);
  9417         __ movt(dst, src);
  9418         break;
  9419       default:
  9420         Unimplemented();
  9422   %}
  9424   ins_pipe( pipe_slow );
  9425 %}
  9428 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9429   match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9430   ins_cost(80);
  9431   format %{
  9432              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
  9433              "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
  9434          %}
  9435   ins_encode %{
  9436     Register op1 = $tmp1$$Register;
  9437     Register op2 = $tmp2$$Register;
  9438     Register dst = $dst$$Register;
  9439     Register src = $src$$Register;
  9440     int     flag = $cop$$cmpcode;
  9442     switch(flag) {
  9443       case 0x01: //equal
  9444         __ subu32(AT, op1, op2);
  9445         __ movz(dst, src, AT);
  9446         break;
  9448       case 0x02: //not_equal
  9449         __ subu32(AT, op1, op2);
  9450         __ movn(dst, src, AT);
  9451         break;
  9453       case 0x03: //above
  9454         __ sltu(AT, op2, op1);
  9455         __ movn(dst, src, AT);
  9456         break;
  9458       case 0x04: //above_equal
  9459         __ sltu(AT, op1, op2);
  9460         __ movz(dst, src, AT);
  9461         break;
  9463       case 0x05: //below
  9464         __ sltu(AT, op1, op2);
  9465         __ movn(dst, src, AT);
  9466         break;
  9468       case 0x06: //below_equal
  9469         __ sltu(AT, op2, op1);
  9470         __ movz(dst, src, AT);
  9471         break;
  9473       default:
  9474         Unimplemented();
  9476   %}
  9478   ins_pipe( pipe_slow );
  9479 %}
  9482 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9483   match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9484   ins_cost(80);
  9485   format %{
  9486              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
  9487              "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
  9488          %}
  9489   ins_encode %{
  9490     Register op1 = $tmp1$$Register;
  9491     Register op2 = $tmp2$$Register;
  9492     Register dst = $dst$$Register;
  9493     Register src = $src$$Register;
  9494     int     flag = $cop$$cmpcode;
  9496     switch(flag) {
  9497       case 0x01: //equal
  9498         __ subu(AT, op1, op2);
  9499         __ movz(dst, src, AT);
  9500         break;
  9502       case 0x02: //not_equal
  9503         __ subu(AT, op1, op2);
  9504         __ movn(dst, src, AT);
  9505         break;
  9507       case 0x03: //above
  9508         __ sltu(AT, op2, op1);
  9509         __ movn(dst, src, AT);
  9510         break;
  9512       case 0x04: //above_equal
  9513         __ sltu(AT, op1, op2);
  9514         __ movz(dst, src, AT);
  9515         break;
  9517       case 0x05: //below
  9518         __ sltu(AT, op1, op2);
  9519         __ movn(dst, src, AT);
  9520         break;
  9522       case 0x06: //below_equal
  9523         __ sltu(AT, op2, op1);
  9524         __ movz(dst, src, AT);
  9525         break;
  9527       default:
  9528         Unimplemented();
  9530   %}
  9532   ins_pipe( pipe_slow );
  9533 %}
  9535 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  9536   match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9537   ins_cost(80);
  9538   format %{
  9539              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpL_reg_reg\n"
  9540              "\tCMOV  $dst,$src \t @cmovI_cmpL_reg_reg"
  9541          %}
  9542   ins_encode %{
  9543     Register opr1 = as_Register($tmp1$$reg);
  9544     Register opr2 = as_Register($tmp2$$reg);
  9545     Register dst     = $dst$$Register;
  9546     Register src     = $src$$Register;
  9547     int     flag = $cop$$cmpcode;
  9549     switch(flag) {
  9550       case 0x01: //equal
  9551         __ subu(AT, opr1, opr2);
  9552         __ movz(dst, src, AT);
  9553         break;
  9555       case 0x02: //not_equal
  9556         __ subu(AT, opr1, opr2);
  9557         __ movn(dst, src, AT);
  9558         break;
  9560       case 0x03: //greater
  9561         __ slt(AT, opr2, opr1);
  9562         __ movn(dst, src, AT);
  9563         break;
  9565       case 0x04: //greater_equal
  9566         __ slt(AT, opr1, opr2);
  9567         __ movz(dst, src, AT);
  9568         break;
  9570       case 0x05: //less
  9571         __ slt(AT, opr1, opr2);
  9572         __ movn(dst, src, AT);
  9573         break;
  9575       case 0x06: //less_equal
  9576         __ slt(AT, opr2, opr1);
  9577         __ movz(dst, src, AT);
  9578         break;
  9580       default:
  9581         Unimplemented();
  9583   %}
  9585   ins_pipe( pipe_slow );
  9586 %}
  9588 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  9589   match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9590   ins_cost(80);
  9591   format %{
  9592              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpL_reg_reg\n"
  9593              "\tCMOV  $dst,$src \t @cmovP_cmpL_reg_reg"
  9594          %}
  9595   ins_encode %{
  9596     Register opr1 = as_Register($tmp1$$reg);
  9597     Register opr2 = as_Register($tmp2$$reg);
  9598     Register dst     = $dst$$Register;
  9599     Register src     = $src$$Register;
  9600     int     flag = $cop$$cmpcode;
  9602     switch(flag) {
  9603       case 0x01: //equal
  9604         __ subu(AT, opr1, opr2);
  9605         __ movz(dst, src, AT);
  9606         break;
  9608       case 0x02: //not_equal
  9609         __ subu(AT, opr1, opr2);
  9610         __ movn(dst, src, AT);
  9611         break;
  9613       case 0x03: //greater
  9614         __ slt(AT, opr2, opr1);
  9615         __ movn(dst, src, AT);
  9616         break;
  9618       case 0x04: //greater_equal
  9619         __ slt(AT, opr1, opr2);
  9620         __ movz(dst, src, AT);
  9621         break;
  9623       case 0x05: //less
  9624         __ slt(AT, opr1, opr2);
  9625         __ movn(dst, src, AT);
  9626         break;
  9628       case 0x06: //less_equal
  9629         __ slt(AT, opr2, opr1);
  9630         __ movz(dst, src, AT);
  9631         break;
  9633       default:
  9634         Unimplemented();
  9636   %}
  9638   ins_pipe( pipe_slow );
  9639 %}
  9641 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9642   match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9643   ins_cost(80);
  9644   format %{
  9645              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpD_reg_reg\n"
  9646              "\tCMOV  $dst,$src \t @cmovI_cmpD_reg_reg"
  9647          %}
  9648   ins_encode %{
  9649     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9650     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9651     Register dst = as_Register($dst$$reg);
  9652     Register src = as_Register($src$$reg);
  9654     int     flag = $cop$$cmpcode;
  9656     switch(flag) {
  9657       case 0x01: //equal
  9658         __ c_eq_d(reg_op1, reg_op2);
  9659         __ movt(dst, src);
  9660         break;
  9661       case 0x02: //not_equal
  9662       // See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
  9663         __ c_eq_d(reg_op1, reg_op2);
  9664         __ movf(dst, src);
  9665         break;
  9666       case 0x03: //greater
  9667         __ c_ole_d(reg_op1, reg_op2);
  9668         __ movf(dst, src);
  9669         break;
  9670       case 0x04: //greater_equal
  9671         __ c_olt_d(reg_op1, reg_op2);
  9672         __ movf(dst, src);
  9673         break;
  9674       case 0x05: //less
  9675         __ c_ult_d(reg_op1, reg_op2);
  9676         __ movt(dst, src);
  9677         break;
  9678       case 0x06: //less_equal
  9679         __ c_ule_d(reg_op1, reg_op2);
  9680         __ movt(dst, src);
  9681         break;
  9682       default:
  9683         Unimplemented();
  9685   %}
  9687   ins_pipe( pipe_slow );
  9688 %}
  9691 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  9692   match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9693   ins_cost(80);
  9694   format %{
  9695              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
  9696              "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
  9697          %}
  9698   ins_encode %{
  9699     Register op1 = $tmp1$$Register;
  9700     Register op2 = $tmp2$$Register;
  9701     Register dst = $dst$$Register;
  9702     Register src = $src$$Register;
  9703     int     flag = $cop$$cmpcode;
  9705     switch(flag) {
  9706       case 0x01: //equal
  9707         __ subu(AT, op1, op2);
  9708         __ movz(dst, src, AT);
  9709         break;
  9711       case 0x02: //not_equal
  9712         __ subu(AT, op1, op2);
  9713         __ movn(dst, src, AT);
  9714         break;
  9716       case 0x03: //above
  9717         __ sltu(AT, op2, op1);
  9718         __ movn(dst, src, AT);
  9719         break;
  9721       case 0x04: //above_equal
  9722         __ sltu(AT, op1, op2);
  9723         __ movz(dst, src, AT);
  9724         break;
  9726       case 0x05: //below
  9727         __ sltu(AT, op1, op2);
  9728         __ movn(dst, src, AT);
  9729         break;
  9731       case 0x06: //below_equal
  9732         __ sltu(AT, op2, op1);
  9733         __ movz(dst, src, AT);
  9734        break;
  9736       default:
  9737         Unimplemented();
  9739   %}
  9741   ins_pipe( pipe_slow );
  9742 %}
  9744 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9745   match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9746   ins_cost(80);
  9747   format %{
  9748              "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
  9749              "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
  9750          %}
  9751   ins_encode %{
  9752     Register op1 = $tmp1$$Register;
  9753     Register op2 = $tmp2$$Register;
  9754     Register dst = $dst$$Register;
  9755     Register src = $src$$Register;
  9756     int     flag = $cop$$cmpcode;
  9758     switch(flag) {
  9759       case 0x01: //equal
  9760         __ subu32(AT, op1, op2);
  9761         __ movz(dst, src, AT);
  9762         break;
  9764       case 0x02: //not_equal
  9765         __ subu32(AT, op1, op2);
  9766         __ movn(dst, src, AT);
  9767         break;
  9769       case 0x03: //above
  9770         __ slt(AT, op2, op1);
  9771         __ movn(dst, src, AT);
  9772         break;
  9774       case 0x04: //above_equal
  9775         __ slt(AT, op1, op2);
  9776         __ movz(dst, src, AT);
  9777         break;
  9779       case 0x05: //below
  9780         __ slt(AT, op1, op2);
  9781         __ movn(dst, src, AT);
  9782         break;
  9784       case 0x06: //below_equal
  9785         __ slt(AT, op2, op1);
  9786         __ movz(dst, src, AT);
  9787         break;
  9789       default:
  9790         Unimplemented();
  9792   %}
  9794   ins_pipe( pipe_slow );
  9795 %}
  9797 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
  9798   match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  9799   ins_cost(80);
  9800   format %{
  9801              "CMP$cop  $tmp1, $tmp2\t  @cmovN_cmpL_reg_reg\n"
  9802              "\tCMOV  $dst,$src \t @cmovN_cmpL_reg_reg"
  9803          %}
  9804   ins_encode %{
  9805     Register opr1 = as_Register($tmp1$$reg);
  9806     Register opr2 = as_Register($tmp2$$reg);
  9807     Register dst  = $dst$$Register;
  9808     Register src  = $src$$Register;
  9809     int     flag  = $cop$$cmpcode;
  9811     switch(flag) {
  9812       case 0x01: //equal
  9813         __ subu(AT, opr1, opr2);
  9814         __ movz(dst, src, AT);
  9815         break;
  9817       case 0x02: //not_equal
  9818         __ subu(AT, opr1, opr2);
  9819         __ movn(dst, src, AT);
  9820         break;
  9822       case 0x03: //greater
  9823         __ slt(AT, opr2, opr1);
  9824         __ movn(dst, src, AT);
  9825         break;
  9827       case 0x04: //greater_equal
  9828         __ slt(AT, opr1, opr2);
  9829         __ movz(dst, src, AT);
  9830         break;
  9832       case 0x05: //less
  9833         __ slt(AT, opr1, opr2);
  9834         __ movn(dst, src, AT);
  9835         break;
  9837       case 0x06: //less_equal
  9838         __ slt(AT, opr2, opr1);
  9839         __ movz(dst, src, AT);
  9840         break;
  9842       default:
  9843         Unimplemented();
  9845   %}
  9847   ins_pipe( pipe_slow );
  9848 %}
  9850 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9851   match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9852   ins_cost(80);
  9853   format %{
  9854              "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
  9855              "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
  9856          %}
  9857   ins_encode %{
  9858     Register op1 = $tmp1$$Register;
  9859     Register op2 = $tmp2$$Register;
  9860     Register dst = $dst$$Register;
  9861     Register src = $src$$Register;
  9862     int     flag = $cop$$cmpcode;
  9864     switch(flag) {
  9865       case 0x01: //equal
  9866         __ subu32(AT, op1, op2);
  9867         __ movz(dst, src, AT);
  9868         break;
  9870       case 0x02: //not_equal
  9871         __ subu32(AT, op1, op2);
  9872         __ movn(dst, src, AT);
  9873         break;
  9875       case 0x03: //above
  9876         __ slt(AT, op2, op1);
  9877         __ movn(dst, src, AT);
  9878         break;
  9880       case 0x04: //above_equal
  9881         __ slt(AT, op1, op2);
  9882         __ movz(dst, src, AT);
  9883         break;
  9885       case 0x05: //below
  9886         __ slt(AT, op1, op2);
  9887         __ movn(dst, src, AT);
  9888         break;
  9890       case 0x06: //below_equal
  9891         __ slt(AT, op2, op1);
  9892         __ movz(dst, src, AT);
  9893        break;
  9895       default:
  9896         Unimplemented();
  9898   %}
  9900   ins_pipe( pipe_slow );
  9901 %}
  9903 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  9904   match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  9905   ins_cost(80);
  9906   format %{
  9907              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
  9908              "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
  9909          %}
  9910   ins_encode %{
  9911     Register op1 = $tmp1$$Register;
  9912     Register op2 = $tmp2$$Register;
  9913     Register dst = $dst$$Register;
  9914     Register src = $src$$Register;
  9915     int     flag = $cop$$cmpcode;
  9917     switch(flag) {
  9918       case 0x01: //equal
  9919         __ subu32(AT, op1, op2);
  9920         __ movz(dst, src, AT);
  9921         break;
  9923       case 0x02: //not_equal
  9924         __ subu32(AT, op1, op2);
  9925         __ movn(dst, src, AT);
  9926         break;
  9928       case 0x03: //above
  9929         __ sltu(AT, op2, op1);
  9930         __ movn(dst, src, AT);
  9931         break;
  9933       case 0x04: //above_equal
  9934         __ sltu(AT, op1, op2);
  9935         __ movz(dst, src, AT);
  9936         break;
  9938       case 0x05: //below
  9939         __ sltu(AT, op1, op2);
  9940         __ movn(dst, src, AT);
  9941         break;
  9943       case 0x06: //below_equal
  9944         __ sltu(AT, op2, op1);
  9945         __ movz(dst, src, AT);
  9946         break;
  9948       default:
  9949         Unimplemented();
  9951   %}
  9953   ins_pipe( pipe_slow );
  9954 %}
  9956 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9957   match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9958   ins_cost(80);
  9959   format %{
  9960              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpF_reg_reg\n"
  9961              "\tCMOV  $dst,$src \t @cmovL_cmpF_reg_reg"
  9962          %}
  9964   ins_encode %{
  9965     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9966     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9967     Register dst = $dst$$Register;
  9968     Register src = $src$$Register;
  9969     int     flag = $cop$$cmpcode;
  9971     switch(flag) {
  9972       case 0x01: //equal
  9973         __ c_eq_s(reg_op1, reg_op2);
  9974         __ movt(dst, src);
  9975         break;
  9976       case 0x02: //not_equal
  9977         __ c_eq_s(reg_op1, reg_op2);
  9978         __ movf(dst, src);
  9979         break;
  9980       case 0x03: //greater
  9981         __ c_ole_s(reg_op1, reg_op2);
  9982         __ movf(dst, src);
  9983         break;
  9984       case 0x04: //greater_equal
  9985         __ c_olt_s(reg_op1, reg_op2);
  9986         __ movf(dst, src);
  9987         break;
  9988       case 0x05: //less
  9989         __ c_ult_s(reg_op1, reg_op2);
  9990         __ movt(dst, src);
  9991         break;
  9992       case 0x06: //less_equal
  9993         __ c_ule_s(reg_op1, reg_op2);
  9994         __ movt(dst, src);
  9995        break;
  9996       default:
  9997         Unimplemented();
  9999   %}
 10000   ins_pipe( pipe_slow );
 10001 %}
 10003 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10004   match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10005   ins_cost(80);
 10006   format %{
 10007              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpI_reg_reg\n"
 10008              "\tCMOV  $dst,$src \t @cmovL_cmpI_reg_reg"
 10009          %}
 10011   ins_encode %{
 10012     Register op1 = $tmp1$$Register;
 10013     Register op2 = $tmp2$$Register;
 10014     Register dst = as_Register($dst$$reg);
 10015     Register src = as_Register($src$$reg);
 10016     int     flag = $cop$$cmpcode;
 10018     switch(flag)
 10020       case 0x01: //equal
 10021         __ subu32(AT, op1, op2);
 10022         __ movz(dst, src, AT);
 10023         break;
 10025       case 0x02: //not_equal
 10026         __ subu32(AT, op1, op2);
 10027         __ movn(dst, src, AT);
 10028         break;
 10030       case 0x03: //great
 10031         __ slt(AT, op2, op1);
 10032         __ movn(dst, src, AT);
 10033         break;
 10035       case 0x04: //great_equal
 10036         __ slt(AT, op1, op2);
 10037         __ movz(dst, src, AT);
 10038         break;
 10040       case 0x05: //less
 10041         __ slt(AT, op1, op2);
 10042         __ movn(dst, src, AT);
 10043         break;
 10045       case 0x06: //less_equal
 10046         __ slt(AT, op2, op1);
 10047         __ movz(dst, src, AT);
 10048        break;
 10050       default:
 10051         Unimplemented();
 10053   %}
 10055   ins_pipe( pipe_slow );
 10056 %}
 10058 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
 10059   match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
 10060   ins_cost(80);
 10061   format %{
 10062              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpL_reg_reg\n"
 10063              "\tCMOV  $dst,$src \t @cmovL_cmpL_reg_reg"
 10064          %}
 10065   ins_encode %{
 10066     Register opr1 = as_Register($tmp1$$reg);
 10067     Register opr2 = as_Register($tmp2$$reg);
 10068     Register dst  = as_Register($dst$$reg);
 10069     Register src  = as_Register($src$$reg);
 10070     int     flag = $cop$$cmpcode;
 10072     switch(flag) {
 10073       case 0x01: //equal
 10074         __ subu(AT, opr1, opr2);
 10075         __ movz(dst, src, AT);
 10076         break;
 10078       case 0x02: //not_equal
 10079         __ subu(AT, opr1, opr2);
 10080         __ movn(dst, src, AT);
 10081         break;
 10083       case 0x03: //greater
 10084         __ slt(AT, opr2, opr1);
 10085         __ movn(dst, src, AT);
 10086         break;
 10088       case 0x04: //greater_equal
 10089         __ slt(AT, opr1, opr2);
 10090         __ movz(dst, src, AT);
 10091         break;
 10093       case 0x05: //less
 10094         __ slt(AT, opr1, opr2);
 10095         __ movn(dst, src, AT);
 10096         break;
 10098       case 0x06: //less_equal
 10099        __ slt(AT, opr2, opr1);
 10100        __ movz(dst, src, AT);
 10101        break;
 10103       default:
 10104         Unimplemented();
 10106   %}
 10108   ins_pipe( pipe_slow );
 10109 %}
 10111 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
 10112   match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
 10113   ins_cost(80);
 10114   format %{
 10115              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
 10116              "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
 10117          %}
 10118   ins_encode %{
 10119     Register op1 = $tmp1$$Register;
 10120     Register op2 = $tmp2$$Register;
 10121     Register dst = $dst$$Register;
 10122     Register src = $src$$Register;
 10123     int     flag = $cop$$cmpcode;
 10125     switch(flag) {
 10126       case 0x01: //equal
 10127         __ subu32(AT, op1, op2);
 10128         __ movz(dst, src, AT);
 10129         break;
 10131       case 0x02: //not_equal
 10132         __ subu32(AT, op1, op2);
 10133         __ movn(dst, src, AT);
 10134         break;
 10136       case 0x03: //above
 10137         __ sltu(AT, op2, op1);
 10138         __ movn(dst, src, AT);
 10139         break;
 10141       case 0x04: //above_equal
 10142         __ sltu(AT, op1, op2);
 10143         __ movz(dst, src, AT);
 10144         break;
 10146       case 0x05: //below
 10147         __ sltu(AT, op1, op2);
 10148         __ movn(dst, src, AT);
 10149         break;
 10151       case 0x06: //below_equal
 10152         __ sltu(AT, op2, op1);
 10153         __ movz(dst, src, AT);
 10154         break;
 10156       default:
 10157         Unimplemented();
 10159   %}
 10161   ins_pipe( pipe_slow );
 10162 %}
 10165 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
 10166   match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
 10167   ins_cost(80);
 10168   format %{
 10169              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpD_reg_reg\n"
 10170              "\tCMOV  $dst,$src \t @cmovL_cmpD_reg_reg"
 10171          %}
 10172   ins_encode %{
 10173     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
 10174     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
 10175     Register dst = as_Register($dst$$reg);
 10176     Register src = as_Register($src$$reg);
 10178     int     flag = $cop$$cmpcode;
 10180     switch(flag) {
 10181       case 0x01: //equal
 10182         __ c_eq_d(reg_op1, reg_op2);
 10183         __ movt(dst, src);
 10184         break;
 10185       case 0x02: //not_equal
 10186         __ c_eq_d(reg_op1, reg_op2);
 10187         __ movf(dst, src);
 10188         break;
 10189       case 0x03: //greater
 10190         __ c_ole_d(reg_op1, reg_op2);
 10191         __ movf(dst, src);
 10192         break;
 10193       case 0x04: //greater_equal
 10194         __ c_olt_d(reg_op1, reg_op2);
 10195         __ movf(dst, src);
 10196         break;
 10197       case 0x05: //less
 10198         __ c_ult_d(reg_op1, reg_op2);
 10199         __ movt(dst, src);
 10200         break;
 10201       case 0x06: //less_equal
 10202         __ c_ule_d(reg_op1, reg_op2);
 10203         __ movt(dst, src);
 10204         break;
 10205       default:
 10206         Unimplemented();
 10208   %}
 10210   ins_pipe( pipe_slow );
 10211 %}
 10213 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
 10214   match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
 10215   ins_cost(200);
 10216   format %{
 10217              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpD_reg_reg\n"
 10218              "\tCMOV  $dst,$src \t @cmovD_cmpD_reg_reg"
 10219          %}
 10220   ins_encode %{
 10221     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
 10222     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
 10223     FloatRegister dst = as_FloatRegister($dst$$reg);
 10224     FloatRegister src = as_FloatRegister($src$$reg);
 10226     int     flag = $cop$$cmpcode;
 10228     switch(flag) {
 10229       case 0x01: //equal
 10230         __ c_eq_d(reg_op1, reg_op2);
 10231         __ movt_d(dst, src);
 10232         break;
 10233       case 0x02: //not_equal
 10234         __ c_eq_d(reg_op1, reg_op2);
 10235         __ movf_d(dst, src);
 10236         break;
 10237       case 0x03: //greater
 10238         __ c_ole_d(reg_op1, reg_op2);
 10239         __ movf_d(dst, src);
 10240         break;
 10241       case 0x04: //greater_equal
 10242         __ c_olt_d(reg_op1, reg_op2);
 10243         __ movf_d(dst, src);
 10244         break;
 10245       case 0x05: //less
 10246         __ c_ult_d(reg_op1, reg_op2);
 10247         __ movt_d(dst, src);
 10248         break;
 10249       case 0x06: //less_equal
 10250         __ c_ule_d(reg_op1, reg_op2);
 10251         __ movt_d(dst, src);
 10252         break;
 10253       default:
 10254         Unimplemented();
 10256   %}
 10258   ins_pipe( pipe_slow );
 10259 %}
 10261 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10262   match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10263   ins_cost(200);
 10264   format %{
 10265              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpI_reg_reg\n"
 10266              "\tCMOV  $dst, $src \t @cmovF_cmpI_reg_reg"
 10267          %}
 10269   ins_encode %{
 10270     Register op1 = $tmp1$$Register;
 10271     Register op2 = $tmp2$$Register;
 10272     FloatRegister dst = as_FloatRegister($dst$$reg);
 10273     FloatRegister src = as_FloatRegister($src$$reg);
 10274     int     flag = $cop$$cmpcode;
 10275     Label      L;
 10277     switch(flag) {
 10278       case 0x01: //equal
 10279         __ bne(op1, op2, L);
 10280         __ delayed()->nop();
 10281         __ mov_s(dst, src);
 10282         __ bind(L);
 10283         break;
 10284       case 0x02: //not_equal
 10285         __ beq(op1, op2, L);
 10286         __ delayed()->nop();
 10287         __ mov_s(dst, src);
 10288         __ bind(L);
 10289         break;
 10290       case 0x03: //great
 10291         __ slt(AT, op2, op1);
 10292         __ beq(AT, R0, L);
 10293         __ delayed()->nop();
 10294         __ mov_s(dst, src);
 10295         __ bind(L);
 10296         break;
 10297       case 0x04: //great_equal
 10298         __ slt(AT, op1, op2);
 10299         __ bne(AT, R0, L);
 10300         __ delayed()->nop();
 10301         __ mov_s(dst, src);
 10302         __ bind(L);
 10303         break;
 10304       case 0x05: //less
 10305         __ slt(AT, op1, op2);
 10306         __ beq(AT, R0, L);
 10307         __ delayed()->nop();
 10308         __ mov_s(dst, src);
 10309         __ bind(L);
 10310         break;
 10311       case 0x06: //less_equal
 10312         __ slt(AT, op2, op1);
 10313         __ bne(AT, R0, L);
 10314         __ delayed()->nop();
 10315         __ mov_s(dst, src);
 10316         __ bind(L);
 10317        break;
 10318       default:
 10319         Unimplemented();
 10321   %}
 10323   ins_pipe( pipe_slow );
 10324 %}
 10326 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
 10327   match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
 10328   ins_cost(200);
 10329   format %{
 10330              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpI_reg_reg\n"
 10331              "\tCMOV  $dst, $src \t @cmovD_cmpI_reg_reg"
 10332          %}
 10334   ins_encode %{
 10335     Register op1 = $tmp1$$Register;
 10336     Register op2 = $tmp2$$Register;
 10337     FloatRegister dst = as_FloatRegister($dst$$reg);
 10338     FloatRegister src = as_FloatRegister($src$$reg);
 10339     int     flag = $cop$$cmpcode;
 10340     Label      L;
 10342     switch(flag) {
 10343       case 0x01: //equal
 10344         __ bne(op1, op2, L);
 10345         __ delayed()->nop();
 10346         __ mov_d(dst, src);
 10347         __ bind(L);
 10348         break;
 10349       case 0x02: //not_equal
 10350         __ beq(op1, op2, L);
 10351         __ delayed()->nop();
 10352         __ mov_d(dst, src);
 10353         __ bind(L);
 10354         break;
 10355       case 0x03: //great
 10356         __ slt(AT, op2, op1);
 10357         __ beq(AT, R0, L);
 10358         __ delayed()->nop();
 10359         __ mov_d(dst, src);
 10360         __ bind(L);
 10361         break;
 10362       case 0x04: //great_equal
 10363         __ slt(AT, op1, op2);
 10364         __ bne(AT, R0, L);
 10365         __ delayed()->nop();
 10366         __ mov_d(dst, src);
 10367         __ bind(L);
 10368         break;
 10369       case 0x05: //less
 10370         __ slt(AT, op1, op2);
 10371         __ beq(AT, R0, L);
 10372         __ delayed()->nop();
 10373         __ mov_d(dst, src);
 10374         __ bind(L);
 10375         break;
 10376       case 0x06: //less_equal
 10377         __ slt(AT, op2, op1);
 10378         __ bne(AT, R0, L);
 10379         __ delayed()->nop();
 10380         __ mov_d(dst, src);
 10381         __ bind(L);
 10382         break;
 10383       default:
 10384         Unimplemented();
 10386   %}
 10388   ins_pipe( pipe_slow );
 10389 %}
 10391 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
 10392   match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
 10393   ins_cost(200);
 10394   format %{
 10395              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpP_reg_reg\n"
 10396              "\tCMOV  $dst, $src \t @cmovD_cmpP_reg_reg"
 10397          %}
 10399   ins_encode %{
 10400     Register op1 = $tmp1$$Register;
 10401     Register op2 = $tmp2$$Register;
 10402     FloatRegister dst = as_FloatRegister($dst$$reg);
 10403     FloatRegister src = as_FloatRegister($src$$reg);
 10404     int     flag = $cop$$cmpcode;
 10405     Label      L;
 10407     switch(flag) {
 10408       case 0x01: //equal
 10409         __ bne(op1, op2, L);
 10410         __ delayed()->nop();
 10411         __ mov_d(dst, src);
 10412         __ bind(L);
 10413         break;
 10414       case 0x02: //not_equal
 10415         __ beq(op1, op2, L);
 10416         __ delayed()->nop();
 10417         __ mov_d(dst, src);
 10418         __ bind(L);
 10419         break;
 10420       case 0x03: //great
 10421         __ slt(AT, op2, op1);
 10422         __ beq(AT, R0, L);
 10423         __ delayed()->nop();
 10424         __ mov_d(dst, src);
 10425         __ bind(L);
 10426         break;
 10427       case 0x04: //great_equal
 10428         __ slt(AT, op1, op2);
 10429         __ bne(AT, R0, L);
 10430         __ delayed()->nop();
 10431         __ mov_d(dst, src);
 10432         __ bind(L);
 10433         break;
 10434       case 0x05: //less
 10435         __ slt(AT, op1, op2);
 10436         __ beq(AT, R0, L);
 10437         __ delayed()->nop();
 10438         __ mov_d(dst, src);
 10439         __ bind(L);
 10440         break;
 10441       case 0x06: //less_equal
 10442         __ slt(AT, op2, op1);
 10443         __ bne(AT, R0, L);
 10444         __ delayed()->nop();
 10445         __ mov_d(dst, src);
 10446         __ bind(L);
 10447         break;
 10448       default:
 10449         Unimplemented();
 10451   %}
 10453   ins_pipe( pipe_slow );
 10454 %}
 10456 //FIXME
 10457 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10458   match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10459   ins_cost(80);
 10460   format %{
 10461              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpF_reg_reg\n"
 10462              "\tCMOV  $dst,$src \t @cmovI_cmpF_reg_reg"
 10463          %}
 10465   ins_encode %{
 10466     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10467     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10468     Register dst = $dst$$Register;
 10469     Register src = $src$$Register;
 10470     int     flag = $cop$$cmpcode;
 10472     switch(flag) {
 10473       case 0x01: //equal
 10474         __ c_eq_s(reg_op1, reg_op2);
 10475         __ movt(dst, src);
 10476         break;
 10477       case 0x02: //not_equal
 10478         __ c_eq_s(reg_op1, reg_op2);
 10479         __ movf(dst, src);
 10480         break;
 10481       case 0x03: //greater
 10482         __ c_ole_s(reg_op1, reg_op2);
 10483         __ movf(dst, src);
 10484         break;
 10485       case 0x04: //greater_equal
 10486         __ c_olt_s(reg_op1, reg_op2);
 10487         __ movf(dst, src);
 10488         break;
 10489       case 0x05: //less
 10490         __ c_ult_s(reg_op1, reg_op2);
 10491         __ movt(dst, src);
 10492         break;
 10493       case 0x06: //less_equal
 10494         __ c_ule_s(reg_op1, reg_op2);
 10495         __ movt(dst, src);
 10496         break;
 10497       default:
 10498         Unimplemented();
 10500   %}
 10501   ins_pipe( pipe_slow );
 10502 %}
 10504 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
 10505   match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
 10506   ins_cost(200);
 10507   format %{
 10508              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpF_reg_reg\n"
 10509              "\tCMOV  $dst,$src \t @cmovF_cmpF_reg_reg"
 10510          %}
 10512   ins_encode %{
 10513     FloatRegister reg_op1 = $tmp1$$FloatRegister;
 10514     FloatRegister reg_op2 = $tmp2$$FloatRegister;
 10515     FloatRegister dst = $dst$$FloatRegister;
 10516     FloatRegister src = $src$$FloatRegister;
 10517     int    flag = $cop$$cmpcode;
 10519     switch(flag) {
 10520       case 0x01: //equal
 10521         __ c_eq_s(reg_op1, reg_op2);
 10522         __ movt_s(dst, src);
 10523         break;
 10524       case 0x02: //not_equal
 10525         __ c_eq_s(reg_op1, reg_op2);
 10526         __ movf_s(dst, src);
 10527         break;
 10528       case 0x03: //greater
 10529         __ c_ole_s(reg_op1, reg_op2);
 10530         __ movf_s(dst, src);
 10531         break;
 10532       case 0x04: //greater_equal
 10533         __ c_olt_s(reg_op1, reg_op2);
 10534         __ movf_s(dst, src);
 10535         break;
 10536       case 0x05: //less
 10537         __ c_ult_s(reg_op1, reg_op2);
 10538         __ movt_s(dst, src);
 10539         break;
 10540       case 0x06: //less_equal
 10541         __ c_ule_s(reg_op1, reg_op2);
 10542         __ movt_s(dst, src);
 10543         break;
 10544       default:
 10545         Unimplemented();
 10547   %}
 10548   ins_pipe( pipe_slow );
 10549 %}
 10551 // Manifest a CmpL result in an integer register.  Very painful.
 10552 // This is the test to avoid.
 10553 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
 10554   match(Set dst (CmpL3 src1 src2));
 10555   ins_cost(1000);
 10556   format %{ "cmpL3  $dst, $src1, $src2 @ cmpL3_reg_reg" %}
 10557   ins_encode %{
 10558     Register opr1 = as_Register($src1$$reg);
 10559     Register opr2 = as_Register($src2$$reg);
 10560     Register dst  = as_Register($dst$$reg);
 10562     Label Done;
 10564     __ subu(AT, opr1, opr2);
 10565     __ bltz(AT, Done);
 10566     __ delayed()->daddiu(dst, R0, -1);
 10568     __ move(dst, 1);
 10569     __ movz(dst, R0, AT);
 10571     __ bind(Done);
 10572   %}
 10573   ins_pipe( pipe_slow );
 10574 %}
 10576 //
 10577 // less_rsult     = -1
 10578 // greater_result =  1
 10579 // equal_result   =  0
 10580 // nan_result     = -1
 10581 //
 10582 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
 10583   match(Set dst (CmpF3 src1 src2));
 10584   ins_cost(1000);
 10585   format %{ "cmpF3  $dst, $src1, $src2 @ cmpF3_reg_reg" %}
 10586   ins_encode %{
 10587     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10588     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10589     Register dst = as_Register($dst$$reg);
 10591     Label Done;
 10593     __ c_ult_s(src1, src2);
 10594     __ bc1t(Done);
 10595     __ delayed()->daddiu(dst, R0, -1);
 10597     __ c_eq_s(src1, src2);
 10598     __ move(dst, 1);
 10599     __ movt(dst, R0);
 10601     __ bind(Done);
 10602   %}
 10603   ins_pipe( pipe_slow );
 10604 %}
 10606 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
 10607   match(Set dst (CmpD3 src1 src2));
 10608   ins_cost(1000);
 10609   format %{ "cmpD3  $dst, $src1, $src2 @ cmpD3_reg_reg" %}
 10610   ins_encode %{
 10611     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10612     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10613     Register dst = as_Register($dst$$reg);
 10615     Label Done;
 10617     __ c_ult_d(src1, src2);
 10618     __ bc1t(Done);
 10619     __ delayed()->daddiu(dst, R0, -1);
 10621     __ c_eq_d(src1, src2);
 10622     __ move(dst, 1);
 10623     __ movt(dst, R0);
 10625     __ bind(Done);
 10626   %}
 10627   ins_pipe( pipe_slow );
 10628 %}
 10630 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
 10631   match(Set dummy (ClearArray cnt base));
 10632   format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
 10633   ins_encode %{
 10634     //Assume cnt is the number of bytes in an array to be cleared,
 10635     //and base points to the starting address of the array.
 10636     Register base = $base$$Register;
 10637     Register num  = $cnt$$Register;
 10638     Label Loop, done;
 10640     __ beq(num, R0, done);
 10641     __ delayed()->daddu(AT, base, R0);
 10643     __ move(T9, num);  /* T9 = words */
 10645     __ bind(Loop);
 10646     __ sd(R0, AT, 0);
 10647     __ daddi(T9, T9, -1);
 10648     __ bne(T9, R0, Loop);
 10649     __ delayed()->daddi(AT, AT, wordSize);
 10651     __ bind(done);
 10652   %}
 10653   ins_pipe( pipe_slow );
 10654 %}
 10656 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2,  mA7RegI cnt2, no_Ax_mRegI result) %{
 10657   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
 10658   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
 10660   format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
 10661   ins_encode %{
 10662     // Get the first character position in both strings
 10663     //         [8] char array, [12] offset, [16] count
 10664     Register str1   = $str1$$Register;
 10665     Register str2   = $str2$$Register;
 10666     Register cnt1   = $cnt1$$Register;
 10667     Register cnt2   = $cnt2$$Register;
 10668     Register result = $result$$Register;
 10670     Label L, Loop, haveResult, done;
 10672    // compute the and difference of lengths (in result)
 10673    __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
 10675    // compute the shorter length (in cnt1)
 10676    __ slt(AT, cnt2, cnt1);
 10677    __ movn(cnt1, cnt2, AT);
 10679    // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
 10680    __ bind(Loop);                        // Loop begin
 10681    __ beq(cnt1, R0, done);
 10682    __ delayed()->lhu(AT, str1, 0);;
 10684    // compare current character
 10685    __ lhu(cnt2, str2, 0);
 10686    __ bne(AT, cnt2, haveResult);
 10687    __ delayed()->addi(str1, str1, 2);
 10688    __ addi(str2, str2, 2);
 10689    __ b(Loop);
 10690    __ delayed()->addi(cnt1, cnt1, -1);   // Loop end
 10692    __ bind(haveResult);
 10693    __ subu(result, AT, cnt2);
 10695    __ bind(done);
 10696   %}
 10698   ins_pipe( pipe_slow );
 10699 %}
 10701 // intrinsic optimization
 10702 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
 10703   match(Set result (StrEquals (Binary str1 str2) cnt));
 10704   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
 10706   format %{ "String Equal $str1, $str2, len:$cnt  tmp:$temp -> $result @ string_equals" %}
 10707   ins_encode %{
 10708     // Get the first character position in both strings
 10709     //         [8] char array, [12] offset, [16] count
 10710     Register str1   = $str1$$Register;
 10711     Register str2   = $str2$$Register;
 10712     Register cnt    = $cnt$$Register;
 10713     Register tmp    = $temp$$Register;
 10714     Register result = $result$$Register;
 10716     Label    Loop, done;
 10719    __ beq(str1, str2, done);  // same char[] ?
 10720    __ delayed()->daddiu(result, R0, 1);
 10722    __ bind(Loop);             // Loop begin
 10723    __ beq(cnt, R0, done);
 10724    __ delayed()->daddiu(result, R0, 1); // count == 0
 10726    // compare current character
 10727    __ lhu(AT, str1, 0);;
 10728    __ lhu(tmp, str2, 0);
 10729    __ bne(AT, tmp, done);
 10730    __ delayed()->daddi(result, R0, 0);
 10731    __ addi(str1, str1, 2);
 10732    __ addi(str2, str2, 2);
 10733    __ b(Loop);
 10734    __ delayed()->addi(cnt, cnt, -1);  // Loop end
 10736    __ bind(done);
 10737   %}
 10739   ins_pipe( pipe_slow );
 10740 %}
 10742 //----------Arithmetic Instructions-------------------------------------------
 10743 //----------Addition Instructions---------------------------------------------
 10744 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10745   match(Set dst (AddI src1 src2));
 10747   format %{ "add   $dst, $src1, $src2 #@addI_Reg_Reg" %}
 10748   ins_encode %{
 10749     Register  dst = $dst$$Register;
 10750     Register src1 = $src1$$Register;
 10751     Register src2 = $src2$$Register;
 10752     __ addu32(dst, src1, src2);
 10753   %}
 10754   ins_pipe( ialu_regI_regI );
 10755 %}
 10757 instruct addI_Reg_imm(mRegI dst, mRegI src1,  immI src2) %{
 10758   match(Set dst (AddI src1 src2));
 10760   format %{ "add    $dst, $src1, $src2 #@addI_Reg_imm" %}
 10761   ins_encode %{
 10762     Register  dst = $dst$$Register;
 10763     Register src1 = $src1$$Register;
 10764     int       imm = $src2$$constant;
 10766     if(Assembler::is_simm16(imm)) {
 10767        __ addiu32(dst, src1, imm);
 10768     } else {
 10769        __ move(AT, imm);
 10770        __ addu32(dst, src1, AT);
 10772   %}
 10773   ins_pipe( ialu_regI_regI );
 10774 %}
 10776 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
 10777   match(Set dst (AddP src1 src2));
 10779   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg" %}
 10781   ins_encode %{
 10782     Register  dst = $dst$$Register;
 10783     Register src1 = $src1$$Register;
 10784     Register src2 = $src2$$Register;
 10785     __ daddu(dst, src1, src2);
 10786   %}
 10788   ins_pipe( ialu_regI_regI );
 10789 %}
 10791 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
 10792   match(Set dst (AddP src1 (ConvI2L src2)));
 10794   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
 10796   ins_encode %{
 10797     Register  dst = $dst$$Register;
 10798     Register src1 = $src1$$Register;
 10799     Register src2 = $src2$$Register;
 10800     __ daddu(dst, src1, src2);
 10801   %}
 10803   ins_pipe( ialu_regI_regI );
 10804 %}
 10806 instruct addP_reg_imm(mRegP dst, mRegP src1,  immL src2) %{
 10807   match(Set dst (AddP src1 src2));
 10809   format %{ "daddi   $dst, $src1, $src2 #@addP_reg_imm" %}
 10810   ins_encode %{
 10811     Register src1 = $src1$$Register;
 10812     long      src2 = $src2$$constant;
 10813     Register  dst = $dst$$Register;
 10815     if(Assembler::is_simm16(src2)) {
 10816        __ daddiu(dst, src1, src2);
 10817     } else {
 10818        __ set64(AT, src2);
 10819        __ daddu(dst, src1, AT);
 10821   %}
 10822   ins_pipe( ialu_regI_imm16 );
 10823 %}
 10825 // Add Long Register with Register
 10826 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10827   match(Set dst (AddL src1 src2));
 10828   ins_cost(200);
 10829   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
 10831   ins_encode %{
 10832     Register dst_reg = as_Register($dst$$reg);
 10833     Register src1_reg = as_Register($src1$$reg);
 10834     Register src2_reg = as_Register($src2$$reg);
 10836     __ daddu(dst_reg, src1_reg, src2_reg);
 10837   %}
 10839   ins_pipe( ialu_regL_regL );
 10840 %}
 10842 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
 10843 %{
 10844   match(Set dst (AddL src1 src2));
 10846   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_imm " %}
 10847   ins_encode %{
 10848     Register dst_reg  = as_Register($dst$$reg);
 10849     Register src1_reg = as_Register($src1$$reg);
 10850     int      src2_imm = $src2$$constant;
 10852     __ daddiu(dst_reg, src1_reg, src2_imm);
 10853   %}
 10855   ins_pipe( ialu_regL_regL );
 10856 %}
 10858 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
 10859 %{
 10860   match(Set dst (AddL (ConvI2L src1) src2));
 10862   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_imm " %}
 10863   ins_encode %{
 10864     Register dst_reg  = as_Register($dst$$reg);
 10865     Register src1_reg = as_Register($src1$$reg);
 10866     int      src2_imm = $src2$$constant;
 10868     __ daddiu(dst_reg, src1_reg, src2_imm);
 10869   %}
 10871   ins_pipe( ialu_regL_regL );
 10872 %}
 10874 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
 10875   match(Set dst (AddL (ConvI2L src1) src2));
 10876   ins_cost(200);
 10877   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
 10879   ins_encode %{
 10880     Register dst_reg = as_Register($dst$$reg);
 10881     Register src1_reg = as_Register($src1$$reg);
 10882     Register src2_reg = as_Register($src2$$reg);
 10884     __ daddu(dst_reg, src1_reg, src2_reg);
 10885   %}
 10887   ins_pipe( ialu_regL_regL );
 10888 %}
 10890 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
 10891   match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
 10892   ins_cost(200);
 10893   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
 10895   ins_encode %{
 10896     Register dst_reg = as_Register($dst$$reg);
 10897     Register src1_reg = as_Register($src1$$reg);
 10898     Register src2_reg = as_Register($src2$$reg);
 10900     __ daddu(dst_reg, src1_reg, src2_reg);
 10901   %}
 10903   ins_pipe( ialu_regL_regL );
 10904 %}
 10906 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
 10907   match(Set dst (AddL src1 (ConvI2L src2)));
 10908   ins_cost(200);
 10909   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
 10911   ins_encode %{
 10912     Register dst_reg = as_Register($dst$$reg);
 10913     Register src1_reg = as_Register($src1$$reg);
 10914     Register src2_reg = as_Register($src2$$reg);
 10916     __ daddu(dst_reg, src1_reg, src2_reg);
 10917   %}
 10919   ins_pipe( ialu_regL_regL );
 10920 %}
 10922 //----------Subtraction Instructions-------------------------------------------
 10923 // Integer Subtraction Instructions
 10924 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10925   match(Set dst (SubI src1 src2));
 10926   ins_cost(100);
 10928   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_Reg" %}
 10929   ins_encode %{
 10930     Register  dst = $dst$$Register;
 10931     Register src1 = $src1$$Register;
 10932     Register src2 = $src2$$Register;
 10933     __ subu32(dst, src1, src2);
 10934   %}
 10935   ins_pipe( ialu_regI_regI );
 10936 %}
 10938 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1,  immI16_sub src2) %{
 10939   match(Set dst (SubI src1 src2));
 10940   ins_cost(80);
 10942   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
 10943   ins_encode %{
 10944     Register  dst = $dst$$Register;
 10945     Register src1 = $src1$$Register;
 10946     __ addiu32(dst, src1, -1 * $src2$$constant);
 10947   %}
 10948   ins_pipe( ialu_regI_regI );
 10949 %}
 10951 instruct negI_Reg(mRegI dst, immI0 zero,  mRegI src) %{
 10952   match(Set dst (SubI zero src));
 10953   ins_cost(80);
 10955   format %{ "neg    $dst, $src #@negI_Reg" %}
 10956   ins_encode %{
 10957     Register  dst = $dst$$Register;
 10958     Register  src = $src$$Register;
 10959     __ subu32(dst, R0, src);
 10960   %}
 10961   ins_pipe( ialu_regI_regI );
 10962 %}
 10964 instruct negL_Reg(mRegL dst, immL0 zero,  mRegL src) %{
 10965   match(Set dst (SubL zero src));
 10966   ins_cost(80);
 10968   format %{ "neg    $dst, $src #@negL_Reg" %}
 10969   ins_encode %{
 10970     Register  dst = $dst$$Register;
 10971     Register  src = $src$$Register;
 10972     __ subu(dst, R0, src);
 10973   %}
 10974   ins_pipe( ialu_regI_regI );
 10975 %}
 10977 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1,  immL16_sub src2) %{
 10978   match(Set dst (SubL src1 src2));
 10979   ins_cost(80);
 10981   format %{ "sub    $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
 10982   ins_encode %{
 10983     Register  dst = $dst$$Register;
 10984     Register src1 = $src1$$Register;
 10985     __ daddiu(dst, src1, -1 * $src2$$constant);
 10986   %}
 10987   ins_pipe( ialu_regI_regI );
 10988 %}
 10990 // Subtract Long Register with Register.
 10991 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10992   match(Set dst (SubL src1 src2));
 10993   ins_cost(100);
 10994   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_Reg" %}
 10995   ins_encode %{
 10996     Register dst  = as_Register($dst$$reg);
 10997     Register src1 = as_Register($src1$$reg);
 10998     Register src2 = as_Register($src2$$reg);
 11000     __ subu(dst, src1, src2);
 11001   %}
 11002   ins_pipe( ialu_regL_regL );
 11003 %}
 11005 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11006   match(Set dst (SubL src1 (ConvI2L src2)));
 11007   ins_cost(100);
 11008   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
 11009   ins_encode %{
 11010     Register dst  = as_Register($dst$$reg);
 11011     Register src1 = as_Register($src1$$reg);
 11012     Register src2 = as_Register($src2$$reg);
 11014     __ subu(dst, src1, src2);
 11015   %}
 11016   ins_pipe( ialu_regL_regL );
 11017 %}
 11019 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
 11020   match(Set dst (SubL (ConvI2L src1) src2));
 11021   ins_cost(200);
 11022   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
 11023   ins_encode %{
 11024     Register dst  = as_Register($dst$$reg);
 11025     Register src1 = as_Register($src1$$reg);
 11026     Register src2 = as_Register($src2$$reg);
 11028     __ subu(dst, src1, src2);
 11029   %}
 11030   ins_pipe( ialu_regL_regL );
 11031 %}
 11033 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
 11034   match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
 11035   ins_cost(200);
 11036   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
 11037   ins_encode %{
 11038     Register dst  = as_Register($dst$$reg);
 11039     Register src1 = as_Register($src1$$reg);
 11040     Register src2 = as_Register($src2$$reg);
 11042     __ subu(dst, src1, src2);
 11043   %}
 11044   ins_pipe( ialu_regL_regL );
 11045 %}
 11047 // Integer MOD with Register
 11048 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11049   match(Set dst (ModI src1 src2));
 11050   ins_cost(300);
 11051   format %{ "modi   $dst, $src1, $src2 @ modI_Reg_Reg" %}
 11052   ins_encode %{
 11053     Register  dst = $dst$$Register;
 11054     Register src1 = $src1$$Register;
 11055     Register src2 = $src2$$Register;
 11057     //if (UseLoongsonISA) {
 11058     if (0) {
 11059       // 2016.08.10
 11060       // Experiments show that gsmod is slower that div+mfhi.
 11061       // So I just disable it here.
 11062       __ gsmod(dst, src1, src2);
 11063     } else {
 11064       __ div(src1, src2);
 11065       __ mfhi(dst);
 11067   %}
 11069   //ins_pipe( ialu_mod );
 11070   ins_pipe( ialu_regI_regI );
 11071 %}
 11073 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11074   match(Set dst (ModL src1 src2));
 11075   format %{ "modL  $dst, $src1, $src2 @modL_reg_reg" %}
 11077   ins_encode %{
 11078     Register dst = as_Register($dst$$reg);
 11079     Register op1 = as_Register($src1$$reg);
 11080     Register op2 = as_Register($src2$$reg);
 11082     if (UseLoongsonISA) {
 11083       __ gsdmod(dst, op1, op2);
 11084     } else {
 11085       __ ddiv(op1, op2);
 11086       __ mfhi(dst);
 11088   %}
 11089   ins_pipe( pipe_slow );
 11090 %}
 11092 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11093   match(Set dst (MulI src1 src2));
 11095   ins_cost(300);
 11096   format %{ "mul   $dst, $src1, $src2 @ mulI_Reg_Reg" %}
 11097   ins_encode %{
 11098      Register src1 = $src1$$Register;
 11099      Register src2 = $src2$$Register;
 11100      Register dst  = $dst$$Register;
 11102      __ mul(dst, src1, src2);
 11103   %}
 11104   ins_pipe( ialu_mult );
 11105 %}
 11107 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
 11108   match(Set dst (AddI (MulI src1 src2) src3));
 11110   ins_cost(999);
 11111   format %{ "madd   $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
 11112   ins_encode %{
 11113      Register src1 = $src1$$Register;
 11114      Register src2 = $src2$$Register;
 11115      Register src3 = $src3$$Register;
 11116      Register dst  = $dst$$Register;
 11118      __ mtlo(src3);
 11119      __ madd(src1, src2);
 11120      __ mflo(dst);
 11121   %}
 11122   ins_pipe( ialu_mult );
 11123 %}
 11125 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11126   match(Set dst (DivI src1 src2));
 11128   ins_cost(300);
 11129   format %{ "div   $dst, $src1, $src2 @ divI_Reg_Reg" %}
 11130   ins_encode %{
 11131      Register src1 = $src1$$Register;
 11132      Register src2 = $src2$$Register;
 11133      Register dst  = $dst$$Register;
 11135     // In MIPS, div does not cause exception.
 11136     //   We must trap an exception manually.
 11137     __ teq(R0, src2, 0x7);
 11139     if (UseLoongsonISA) {
 11140       __ gsdiv(dst, src1, src2);
 11141     } else {
 11142       __ div(src1, src2);
 11144       __ nop();
 11145       __ nop();
 11146       __ mflo(dst);
 11148   %}
 11149   ins_pipe( ialu_mod );
 11150 %}
 11152 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
 11153   match(Set dst (DivF src1 src2));
 11155   ins_cost(300);
 11156   format %{ "divF   $dst, $src1, $src2 @ divF_Reg_Reg" %}
 11157   ins_encode %{
 11158      FloatRegister src1 = $src1$$FloatRegister;
 11159      FloatRegister src2 = $src2$$FloatRegister;
 11160      FloatRegister dst  = $dst$$FloatRegister;
 11162     /* Here do we need to trap an exception manually ? */
 11163     __ div_s(dst, src1, src2);
 11164   %}
 11165   ins_pipe( pipe_slow );
 11166 %}
 11168 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
 11169   match(Set dst (DivD src1 src2));
 11171   ins_cost(300);
 11172   format %{ "divD   $dst, $src1, $src2 @ divD_Reg_Reg" %}
 11173   ins_encode %{
 11174      FloatRegister src1 = $src1$$FloatRegister;
 11175      FloatRegister src2 = $src2$$FloatRegister;
 11176      FloatRegister dst  = $dst$$FloatRegister;
 11178     /* Here do we need to trap an exception manually ? */
 11179     __ div_d(dst, src1, src2);
 11180   %}
 11181   ins_pipe( pipe_slow );
 11182 %}
 11184 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11185   match(Set dst (MulL src1 src2));
 11186   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_reg" %}
 11187   ins_encode %{
 11188     Register dst = as_Register($dst$$reg);
 11189     Register op1 = as_Register($src1$$reg);
 11190     Register op2 = as_Register($src2$$reg);
 11192     if (UseLoongsonISA) {
 11193       __ gsdmult(dst, op1, op2);
 11194     } else {
 11195       __ dmult(op1, op2);
 11196       __ mflo(dst);
 11198   %}
 11199   ins_pipe( pipe_slow );
 11200 %}
 11202 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11203   match(Set dst (MulL src1 (ConvI2L src2)));
 11204   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_regI2L" %}
 11205   ins_encode %{
 11206     Register dst = as_Register($dst$$reg);
 11207     Register op1 = as_Register($src1$$reg);
 11208     Register op2 = as_Register($src2$$reg);
 11210     if (UseLoongsonISA) {
 11211       __ gsdmult(dst, op1, op2);
 11212     } else {
 11213       __ dmult(op1, op2);
 11214       __ mflo(dst);
 11216   %}
 11217   ins_pipe( pipe_slow );
 11218 %}
 11220 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 11221   match(Set dst (DivL src1 src2));
 11222   format %{ "divL  $dst, $src1, $src2 @divL_reg_reg" %}
 11224   ins_encode %{
 11225     Register dst = as_Register($dst$$reg);
 11226     Register op1 = as_Register($src1$$reg);
 11227     Register op2 = as_Register($src2$$reg);
 11229     if (UseLoongsonISA) {
 11230       __ gsddiv(dst, op1, op2);
 11231     } else {
 11232       __ ddiv(op1, op2);
 11233       __ mflo(dst);
 11235   %}
 11236   ins_pipe( pipe_slow );
 11237 %}
 11239 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 11240   match(Set dst (AddF src1 src2));
 11241   format %{ "AddF  $dst, $src1, $src2 @addF_reg_reg" %}
 11242   ins_encode %{
 11243     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11244     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11245     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11247     __ add_s(dst, src1, src2);
 11248   %}
 11249   ins_pipe( fpu_regF_regF );
 11250 %}
 11252 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 11253   match(Set dst (SubF src1 src2));
 11254   format %{ "SubF  $dst, $src1, $src2 @subF_reg_reg" %}
 11255   ins_encode %{
 11256     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11257     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11258     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11260     __ sub_s(dst, src1, src2);
 11261   %}
 11262   ins_pipe( fpu_regF_regF );
 11263 %}
 11264 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 11265   match(Set dst (AddD src1 src2));
 11266   format %{ "AddD  $dst, $src1, $src2 @addD_reg_reg" %}
 11267   ins_encode %{
 11268     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11269     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11270     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11272     __ add_d(dst, src1, src2);
 11273   %}
 11274   ins_pipe( fpu_regF_regF );
 11275 %}
 11277 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 11278   match(Set dst (SubD src1 src2));
 11279   format %{ "SubD  $dst, $src1, $src2 @subD_reg_reg" %}
 11280   ins_encode %{
 11281     FloatRegister src1 = as_FloatRegister($src1$$reg);
 11282     FloatRegister src2 = as_FloatRegister($src2$$reg);
 11283     FloatRegister dst  = as_FloatRegister($dst$$reg);
 11285     __ sub_d(dst, src1, src2);
 11286   %}
 11287   ins_pipe( fpu_regF_regF );
 11288 %}
 11290 instruct negF_reg(regF dst, regF src) %{
 11291   match(Set dst (NegF src));
 11292   format %{ "negF  $dst, $src @negF_reg" %}
 11293   ins_encode %{
 11294     FloatRegister src = as_FloatRegister($src$$reg);
 11295     FloatRegister dst = as_FloatRegister($dst$$reg);
 11297     __ neg_s(dst, src);
 11298   %}
 11299   ins_pipe( fpu_regF_regF );
 11300 %}
 11302 instruct negD_reg(regD dst, regD src) %{
 11303   match(Set dst (NegD src));
 11304   format %{ "negD  $dst, $src @negD_reg" %}
 11305   ins_encode %{
 11306     FloatRegister src = as_FloatRegister($src$$reg);
 11307     FloatRegister dst = as_FloatRegister($dst$$reg);
 11309     __ neg_d(dst, src);
 11310   %}
 11311   ins_pipe( fpu_regF_regF );
 11312 %}
 11315 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 11316   match(Set dst (MulF src1 src2));
 11317   format %{ "MULF  $dst, $src1, $src2 @mulF_reg_reg" %}
 11318   ins_encode %{
 11319     FloatRegister src1 = $src1$$FloatRegister;
 11320     FloatRegister src2 = $src2$$FloatRegister;
 11321     FloatRegister dst  = $dst$$FloatRegister;
 11323     __ mul_s(dst, src1, src2);
 11324   %}
 11325   ins_pipe( fpu_regF_regF );
 11326 %}
 11328 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
 11329   match(Set dst (AddF (MulF src1 src2) src3));
 11330   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 11331   ins_cost(44444);
 11332   format %{ "maddF  $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
 11333   ins_encode %{
 11334     FloatRegister src1 = $src1$$FloatRegister;
 11335     FloatRegister src2 = $src2$$FloatRegister;
 11336     FloatRegister src3 = $src3$$FloatRegister;
 11337     FloatRegister dst  = $dst$$FloatRegister;
 11339     __ madd_s(dst, src1, src2, src3);
 11340   %}
 11341   ins_pipe( fpu_regF_regF );
 11342 %}
 11344 // Mul two double precision floating piont number
 11345 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 11346   match(Set dst (MulD src1 src2));
 11347   format %{ "MULD  $dst, $src1, $src2 @mulD_reg_reg" %}
 11348   ins_encode %{
 11349     FloatRegister src1 = $src1$$FloatRegister;
 11350     FloatRegister src2 = $src2$$FloatRegister;
 11351     FloatRegister dst  = $dst$$FloatRegister;
 11353     __ mul_d(dst, src1, src2);
 11354   %}
 11355   ins_pipe( fpu_regF_regF );
 11356 %}
 11358 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
 11359   match(Set dst (AddD (MulD src1 src2) src3));
 11360   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 11361   ins_cost(44444);
 11362   format %{ "maddD  $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
 11363   ins_encode %{
 11364     FloatRegister src1 = $src1$$FloatRegister;
 11365     FloatRegister src2 = $src2$$FloatRegister;
 11366     FloatRegister src3 = $src3$$FloatRegister;
 11367     FloatRegister dst  = $dst$$FloatRegister;
 11369     __ madd_d(dst, src1, src2, src3);
 11370   %}
 11371   ins_pipe( fpu_regF_regF );
 11372 %}
 11374 instruct absF_reg(regF dst, regF src) %{
 11375   match(Set dst (AbsF src));
 11376   ins_cost(100);
 11377   format %{ "absF  $dst, $src @absF_reg" %}
 11378   ins_encode %{
 11379     FloatRegister src = as_FloatRegister($src$$reg);
 11380     FloatRegister dst = as_FloatRegister($dst$$reg);
 11382     __ abs_s(dst, src);
 11383   %}
 11384   ins_pipe( fpu_regF_regF );
 11385 %}
 11388 // intrinsics for math_native.
 11389 // AbsD  SqrtD  CosD  SinD  TanD  LogD  Log10D
 11391 instruct absD_reg(regD dst, regD src) %{
 11392   match(Set dst (AbsD src));
 11393   ins_cost(100);
 11394   format %{ "absD  $dst, $src @absD_reg" %}
 11395   ins_encode %{
 11396     FloatRegister src = as_FloatRegister($src$$reg);
 11397     FloatRegister dst = as_FloatRegister($dst$$reg);
 11399     __ abs_d(dst, src);
 11400   %}
 11401   ins_pipe( fpu_regF_regF );
 11402 %}
 11404 instruct sqrtD_reg(regD dst, regD src) %{
 11405   match(Set dst (SqrtD src));
 11406   ins_cost(100);
 11407   format %{ "SqrtD  $dst, $src @sqrtD_reg" %}
 11408   ins_encode %{
 11409     FloatRegister src = as_FloatRegister($src$$reg);
 11410     FloatRegister dst = as_FloatRegister($dst$$reg);
 11412     __ sqrt_d(dst, src);
 11413   %}
 11414   ins_pipe( fpu_regF_regF );
 11415 %}
 11417 instruct sqrtF_reg(regF dst, regF src) %{
 11418   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 11419   ins_cost(100);
 11420   format %{ "SqrtF  $dst, $src @sqrtF_reg" %}
 11421   ins_encode %{
 11422     FloatRegister src = as_FloatRegister($src$$reg);
 11423     FloatRegister dst = as_FloatRegister($dst$$reg);
 11425     __ sqrt_s(dst, src);
 11426   %}
 11427   ins_pipe( fpu_regF_regF );
 11428 %}
 11429 //----------------------------------Logical Instructions----------------------
 11430 //__________________________________Integer Logical Instructions-------------
 11432 //And Instuctions
 11433 // And Register with Immediate
 11434 instruct andI_Reg_immI(mRegI dst, mRegI src1,  immI src2) %{
 11435   match(Set dst (AndI src1 src2));
 11437   format %{ "and  $dst, $src1, $src2 #@andI_Reg_immI" %}
 11438   ins_encode %{
 11439     Register dst = $dst$$Register;
 11440     Register src = $src1$$Register;
 11441     int      val = $src2$$constant;
 11443     __ move(AT, val);
 11444     __ andr(dst, src, AT);
 11445   %}
 11446   ins_pipe( ialu_regI_regI );
 11447 %}
 11449 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 11450   match(Set dst (AndI src1 src2));
 11451   ins_cost(60);
 11453   format %{ "and  $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
 11454   ins_encode %{
 11455     Register dst = $dst$$Register;
 11456     Register src = $src1$$Register;
 11457     int      val = $src2$$constant;
 11459     __ andi(dst, src, val);
 11460   %}
 11461   ins_pipe( ialu_regI_regI );
 11462 %}
 11464 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1,  immI_nonneg_mask mask) %{
 11465   match(Set dst (AndI src1 mask));
 11466   ins_cost(60);
 11468   format %{ "and  $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
 11469   ins_encode %{
 11470     Register dst = $dst$$Register;
 11471     Register src = $src1$$Register;
 11472     int     size = Assembler::is_int_mask($mask$$constant);
 11474     __ ext(dst, src, 0, size);
 11475   %}
 11476   ins_pipe( ialu_regI_regI );
 11477 %}
 11479 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1,  immL_nonneg_mask mask) %{
 11480   match(Set dst (AndL src1 mask));
 11481   ins_cost(60);
 11483   format %{ "and  $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
 11484   ins_encode %{
 11485     Register dst = $dst$$Register;
 11486     Register src = $src1$$Register;
 11487     int     size = Assembler::is_jlong_mask($mask$$constant);
 11489     __ dext(dst, src, 0, size);
 11490   %}
 11491   ins_pipe( ialu_regI_regI );
 11492 %}
 11494 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 11495   match(Set dst (XorI src1 src2));
 11496   ins_cost(60);
 11498   format %{ "xori  $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
 11499   ins_encode %{
 11500     Register dst = $dst$$Register;
 11501     Register src = $src1$$Register;
 11502     int      val = $src2$$constant;
 11504        __ xori(dst, src, val);
 11505   %}
 11506   ins_pipe( ialu_regI_regI );
 11507 %}
 11509 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1,  immI_M1 M1) %{
 11510   match(Set dst (XorI src1 M1));
 11511   predicate(UseLoongsonISA && Use3A2000);
 11512   ins_cost(60);
 11514   format %{ "xor  $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
 11515   ins_encode %{
 11516     Register dst = $dst$$Register;
 11517     Register src = $src1$$Register;
 11519     __ gsorn(dst, R0, src);
 11520   %}
 11521   ins_pipe( ialu_regI_regI );
 11522 %}
 11524 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1,  immI_M1 M1) %{
 11525   match(Set dst (XorI (ConvL2I src1) M1));
 11526   predicate(UseLoongsonISA && Use3A2000);
 11527   ins_cost(60);
 11529   format %{ "xor  $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
 11530   ins_encode %{
 11531     Register dst = $dst$$Register;
 11532     Register src = $src1$$Register;
 11534     __ gsorn(dst, R0, src);
 11535   %}
 11536   ins_pipe( ialu_regI_regI );
 11537 %}
 11539 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 11540   match(Set dst (XorL src1 src2));
 11541   ins_cost(60);
 11543   format %{ "xori  $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
 11544   ins_encode %{
 11545     Register dst = $dst$$Register;
 11546     Register src = $src1$$Register;
 11547     int      val = $src2$$constant;
 11549        __ xori(dst, src, val);
 11550   %}
 11551   ins_pipe( ialu_regI_regI );
 11552 %}
 11554 /*
 11555 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1,  immL_M1 M1) %{
 11556   match(Set dst (XorL src1 M1));
 11557   predicate(UseLoongsonISA);
 11558   ins_cost(60);
 11560   format %{ "xor  $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
 11561   ins_encode %{
 11562     Register dst = $dst$$Register;
 11563     Register src = $src1$$Register;
 11565     __ gsorn(dst, R0, src);
 11566   %}
 11567   ins_pipe( ialu_regI_regI );
 11568 %}
 11569 */
 11571 instruct lbu_and_lmask(mRegI dst, memory mem,  immI_255 mask) %{
 11572   match(Set dst (AndI mask (LoadB mem)));
 11573   ins_cost(60);
 11575   format %{ "lhu  $dst, $mem #@lbu_and_lmask" %}
 11576   ins_encode(load_UB_enc(dst, mem));
 11577   ins_pipe( ialu_loadI );
 11578 %}
 11580 instruct lbu_and_rmask(mRegI dst, memory mem,  immI_255 mask) %{
 11581   match(Set dst (AndI (LoadB mem) mask));
 11582   ins_cost(60);
 11584   format %{ "lhu  $dst, $mem #@lbu_and_rmask" %}
 11585   ins_encode(load_UB_enc(dst, mem));
 11586   ins_pipe( ialu_loadI );
 11587 %}
 11589 instruct andI_Reg_Reg(mRegI dst, mRegI src1,  mRegI src2) %{
 11590   match(Set dst (AndI src1 src2));
 11592   format %{ "and    $dst, $src1, $src2 #@andI_Reg_Reg" %}
 11593   ins_encode %{
 11594     Register dst = $dst$$Register;
 11595     Register src1 = $src1$$Register;
 11596     Register src2 = $src2$$Register;
 11597     __ andr(dst, src1, src2);
 11598   %}
 11599   ins_pipe( ialu_regI_regI );
 11600 %}
 11602 instruct andnI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11603   match(Set dst (AndI src1 (XorI src2 M1)));
 11604   predicate(UseLoongsonISA && Use3A2000);
 11606   format %{ "andn   $dst, $src1, $src2 #@andnI_Reg_nReg" %}
 11607   ins_encode %{
 11608     Register dst = $dst$$Register;
 11609     Register src1 = $src1$$Register;
 11610     Register src2 = $src2$$Register;
 11612     __ gsandn(dst, src1, src2);
 11613   %}
 11614   ins_pipe( ialu_regI_regI );
 11615 %}
 11617 instruct ornI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11618   match(Set dst (OrI src1 (XorI src2 M1)));
 11619   predicate(UseLoongsonISA && Use3A2000);
 11621   format %{ "orn    $dst, $src1, $src2 #@ornI_Reg_nReg" %}
 11622   ins_encode %{
 11623     Register dst = $dst$$Register;
 11624     Register src1 = $src1$$Register;
 11625     Register src2 = $src2$$Register;
 11627     __ gsorn(dst, src1, src2);
 11628   %}
 11629   ins_pipe( ialu_regI_regI );
 11630 %}
 11632 instruct andnI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11633   match(Set dst (AndI (XorI src1 M1) src2));
 11634   predicate(UseLoongsonISA && Use3A2000);
 11636   format %{ "andn   $dst, $src2, $src1 #@andnI_nReg_Reg" %}
 11637   ins_encode %{
 11638     Register dst = $dst$$Register;
 11639     Register src1 = $src1$$Register;
 11640     Register src2 = $src2$$Register;
 11642     __ gsandn(dst, src2, src1);
 11643   %}
 11644   ins_pipe( ialu_regI_regI );
 11645 %}
 11647 instruct ornI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 11648   match(Set dst (OrI (XorI src1 M1) src2));
 11649   predicate(UseLoongsonISA && Use3A2000);
 11651   format %{ "orn    $dst, $src2, $src1 #@ornI_nReg_Reg" %}
 11652   ins_encode %{
 11653     Register dst = $dst$$Register;
 11654     Register src1 = $src1$$Register;
 11655     Register src2 = $src2$$Register;
 11657     __ gsorn(dst, src2, src1);
 11658   %}
 11659   ins_pipe( ialu_regI_regI );
 11660 %}
 11662 // And Long Register with Register
 11663 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11664   match(Set dst (AndL src1 src2));
 11665   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
 11666   ins_encode %{
 11667     Register dst_reg = as_Register($dst$$reg);
 11668     Register src1_reg = as_Register($src1$$reg);
 11669     Register src2_reg = as_Register($src2$$reg);
 11671     __ andr(dst_reg, src1_reg, src2_reg);
 11672   %}
 11673   ins_pipe( ialu_regL_regL );
 11674 %}
 11676 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
 11677   match(Set dst (AndL src1 (ConvI2L src2)));
 11678   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
 11679   ins_encode %{
 11680     Register dst_reg = as_Register($dst$$reg);
 11681     Register src1_reg = as_Register($src1$$reg);
 11682     Register src2_reg = as_Register($src2$$reg);
 11684     __ andr(dst_reg, src1_reg, src2_reg);
 11685   %}
 11686   ins_pipe( ialu_regL_regL );
 11687 %}
 11689 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 11690   match(Set dst (AndL src1 src2));
 11691   ins_cost(60);
 11693   format %{ "and  $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
 11694   ins_encode %{
 11695     Register dst = $dst$$Register;
 11696     Register src = $src1$$Register;
 11697     long     val = $src2$$constant;
 11699        __ andi(dst, src, val);
 11700   %}
 11701   ins_pipe( ialu_regI_regI );
 11702 %}
 11704 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1,  immL_0_65535 src2) %{
 11705   match(Set dst (ConvL2I (AndL src1 src2)));
 11706   ins_cost(60);
 11708   format %{ "and  $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
 11709   ins_encode %{
 11710     Register dst = $dst$$Register;
 11711     Register src = $src1$$Register;
 11712     long     val = $src2$$constant;
 11714        __ andi(dst, src, val);
 11715   %}
 11716   ins_pipe( ialu_regI_regI );
 11717 %}
 11719 /*
 11720 instruct andnL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11721   match(Set dst (AndL src1 (XorL src2 M1)));
 11722   predicate(UseLoongsonISA);
 11724   format %{ "andn   $dst, $src1, $src2 #@andnL_Reg_nReg" %}
 11725   ins_encode %{
 11726     Register dst = $dst$$Register;
 11727     Register src1 = $src1$$Register;
 11728     Register src2 = $src2$$Register;
 11730     __ gsandn(dst, src1, src2);
 11731   %}
 11732   ins_pipe( ialu_regI_regI );
 11733 %}
 11734 */
 11736 /*
 11737 instruct ornL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11738   match(Set dst (OrL src1 (XorL src2 M1)));
 11739   predicate(UseLoongsonISA);
 11741   format %{ "orn    $dst, $src1, $src2 #@ornL_Reg_nReg" %}
 11742   ins_encode %{
 11743     Register dst = $dst$$Register;
 11744     Register src1 = $src1$$Register;
 11745     Register src2 = $src2$$Register;
 11747     __ gsorn(dst, src1, src2);
 11748   %}
 11749   ins_pipe( ialu_regI_regI );
 11750 %}
 11751 */
 11753 /*
 11754 instruct andnL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11755   match(Set dst (AndL (XorL src1 M1) src2));
 11756   predicate(UseLoongsonISA);
 11758   format %{ "andn   $dst, $src2, $src1 #@andnL_nReg_Reg" %}
 11759   ins_encode %{
 11760     Register dst = $dst$$Register;
 11761     Register src1 = $src1$$Register;
 11762     Register src2 = $src2$$Register;
 11764     __ gsandn(dst, src2, src1);
 11765   %}
 11766   ins_pipe( ialu_regI_regI );
 11767 %}
 11768 */
 11770 /*
 11771 instruct ornL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 11772   match(Set dst (OrL (XorL src1 M1) src2));
 11773   predicate(UseLoongsonISA);
 11775   format %{ "orn    $dst, $src2, $src1 #@ornL_nReg_Reg" %}
 11776   ins_encode %{
 11777     Register dst = $dst$$Register;
 11778     Register src1 = $src1$$Register;
 11779     Register src2 = $src2$$Register;
 11781     __ gsorn(dst, src2, src1);
 11782   %}
 11783   ins_pipe( ialu_regI_regI );
 11784 %}
 11785 */
 11787 instruct andL_Reg_immL_M8(mRegL dst,  immL_M8 M8) %{
 11788   match(Set dst (AndL dst M8));
 11789   ins_cost(60);
 11791   format %{ "and  $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
 11792   ins_encode %{
 11793     Register dst = $dst$$Register;
 11795     __ dins(dst, R0, 0, 3);
 11796   %}
 11797   ins_pipe( ialu_regI_regI );
 11798 %}
 11800 instruct andL_Reg_immL_M5(mRegL dst,  immL_M5 M5) %{
 11801   match(Set dst (AndL dst M5));
 11802   ins_cost(60);
 11804   format %{ "and  $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
 11805   ins_encode %{
 11806     Register dst = $dst$$Register;
 11808     __ dins(dst, R0, 2, 1);
 11809   %}
 11810   ins_pipe( ialu_regI_regI );
 11811 %}
 11813 instruct andL_Reg_immL_M7(mRegL dst,  immL_M7 M7) %{
 11814   match(Set dst (AndL dst M7));
 11815   ins_cost(60);
 11817   format %{ "and  $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
 11818   ins_encode %{
 11819     Register dst = $dst$$Register;
 11821     __ dins(dst, R0, 1, 2);
 11822   %}
 11823   ins_pipe( ialu_regI_regI );
 11824 %}
 11826 instruct andL_Reg_immL_M4(mRegL dst,  immL_M4 M4) %{
 11827   match(Set dst (AndL dst M4));
 11828   ins_cost(60);
 11830   format %{ "and  $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
 11831   ins_encode %{
 11832     Register dst = $dst$$Register;
 11834     __ dins(dst, R0, 0, 2);
 11835   %}
 11836   ins_pipe( ialu_regI_regI );
 11837 %}
 11839 instruct andL_Reg_immL_M121(mRegL dst,  immL_M121 M121) %{
 11840   match(Set dst (AndL dst M121));
 11841   ins_cost(60);
 11843   format %{ "and  $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
 11844   ins_encode %{
 11845     Register dst = $dst$$Register;
 11847     __ dins(dst, R0, 3, 4);
 11848   %}
 11849   ins_pipe( ialu_regI_regI );
 11850 %}
 11852 // Or Long Register with Register
 11853 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11854   match(Set dst (OrL src1 src2));
 11855   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
 11856   ins_encode %{
 11857     Register dst_reg  = $dst$$Register;
 11858     Register src1_reg = $src1$$Register;
 11859     Register src2_reg = $src2$$Register;
 11861     __ orr(dst_reg, src1_reg, src2_reg);
 11862   %}
 11863   ins_pipe( ialu_regL_regL );
 11864 %}
 11866 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
 11867   match(Set dst (OrL (CastP2X src1) src2));
 11868   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
 11869   ins_encode %{
 11870     Register dst_reg  = $dst$$Register;
 11871     Register src1_reg = $src1$$Register;
 11872     Register src2_reg = $src2$$Register;
 11874     __ orr(dst_reg, src1_reg, src2_reg);
 11875   %}
 11876   ins_pipe( ialu_regL_regL );
 11877 %}
 11879 // Xor Long Register with Register
 11880 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 11881   match(Set dst (XorL src1 src2));
 11882   format %{ "XOR    $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
 11883   ins_encode %{
 11884     Register dst_reg = as_Register($dst$$reg);
 11885     Register src1_reg = as_Register($src1$$reg);
 11886     Register src2_reg = as_Register($src2$$reg);
 11888     __ xorr(dst_reg, src1_reg, src2_reg);
 11889   %}
 11890   ins_pipe( ialu_regL_regL );
 11891 %}
 11893 // Shift Left by 8-bit immediate
 11894 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 11895   match(Set dst (LShiftI src shift));
 11897   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm" %}
 11898   ins_encode %{
 11899     Register src = $src$$Register;
 11900     Register dst = $dst$$Register;
 11901     int    shamt = $shift$$constant;
 11903     __ sll(dst, src, shamt);
 11904   %}
 11905   ins_pipe( ialu_regI_regI );
 11906 %}
 11908 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
 11909   match(Set dst (LShiftI (ConvL2I src) shift));
 11911   format %{ "SHL    $dst, $src, $shift #@salL2I_Reg_imm" %}
 11912   ins_encode %{
 11913     Register src = $src$$Register;
 11914     Register dst = $dst$$Register;
 11915     int    shamt = $shift$$constant;
 11917     __ sll(dst, src, shamt);
 11918   %}
 11919   ins_pipe( ialu_regI_regI );
 11920 %}
 11922 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
 11923   match(Set dst (AndI (LShiftI src shift) mask));
 11925   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
 11926   ins_encode %{
 11927     Register src = $src$$Register;
 11928     Register dst = $dst$$Register;
 11930     __ sll(dst, src, 16);
 11931   %}
 11932   ins_pipe( ialu_regI_regI );
 11933 %}
 11935 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
 11936 %{
 11937   match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
 11939   format %{ "andi  $dst, $src, 7\t# @land7_2_s" %}
 11940   ins_encode %{
 11941     Register src = $src$$Register;
 11942     Register dst = $dst$$Register;
 11944     __ andi(dst, src, 7);
 11945   %}
 11946   ins_pipe(ialu_regI_regI);
 11947 %}
 11949 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
 11950 %{
 11951   match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
 11953   format %{ "ori  $dst, $src1, $src2\t# @ori2s" %}
 11954   ins_encode %{
 11955     Register src = $src1$$Register;
 11956     int      val = $src2$$constant;
 11957     Register dst = $dst$$Register;
 11959     __ ori(dst, src, val);
 11960   %}
 11961   ins_pipe(ialu_regI_regI);
 11962 %}
 11964 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
 11965 // This idiom is used by the compiler the i2s bytecode.
 11966 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
 11967 %{
 11968   match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
 11970   format %{ "i2s  $dst, $src\t# @i2s" %}
 11971   ins_encode %{
 11972     Register src = $src$$Register;
 11973     Register dst = $dst$$Register;
 11975     __ seh(dst, src);
 11976   %}
 11977   ins_pipe(ialu_regI_regI);
 11978 %}
 11980 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 11981 // This idiom is used by the compiler for the i2b bytecode.
 11982 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
 11983 %{
 11984   match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
 11986   format %{ "i2b  $dst, $src\t# @i2b" %}
 11987   ins_encode %{
 11988     Register src = $src$$Register;
 11989     Register dst = $dst$$Register;
 11991     __ seb(dst, src);
 11992   %}
 11993   ins_pipe(ialu_regI_regI);
 11994 %}
 11997 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
 11998   match(Set dst (LShiftI (ConvL2I src) shift));
 12000   format %{ "SHL    $dst, $src, $shift #@salI_RegL2I_imm" %}
 12001   ins_encode %{
 12002     Register src = $src$$Register;
 12003     Register dst = $dst$$Register;
 12004     int    shamt = $shift$$constant;
 12006     __ sll(dst, src, shamt);
 12007   %}
 12008   ins_pipe( ialu_regI_regI );
 12009 %}
 12011 // Shift Left by 8-bit immediate
 12012 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12013   match(Set dst (LShiftI src shift));
 12015   format %{ "SHL    $dst, $src, $shift #@salI_Reg_Reg" %}
 12016   ins_encode %{
 12017     Register src = $src$$Register;
 12018     Register dst = $dst$$Register;
 12019     Register shamt = $shift$$Register;
 12020     __ sllv(dst, src, shamt);
 12021   %}
 12022   ins_pipe( ialu_regI_regI );
 12023 %}
 12026 // Shift Left Long
 12027 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 12028   //predicate(UseNewLongLShift);
 12029   match(Set dst (LShiftL src shift));
 12030   ins_cost(100);
 12031   format %{ "salL    $dst, $src, $shift @ salL_Reg_imm" %}
 12032   ins_encode %{
 12033     Register src_reg = as_Register($src$$reg);
 12034     Register dst_reg = as_Register($dst$$reg);
 12035     int      shamt = $shift$$constant;
 12037     if (__ is_simm(shamt, 5))
 12038         __ dsll(dst_reg, src_reg, shamt);
 12039     else {
 12040       int sa = Assembler::low(shamt, 6);
 12041       if (sa < 32) {
 12042         __ dsll(dst_reg, src_reg, sa);
 12043       } else {
 12044         __ dsll32(dst_reg, src_reg, sa - 32);
 12047   %}
 12048   ins_pipe( ialu_regL_regL );
 12049 %}
 12051 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
 12052   //predicate(UseNewLongLShift);
 12053   match(Set dst (LShiftL (ConvI2L src) shift));
 12054   ins_cost(100);
 12055   format %{ "salL    $dst, $src, $shift @ salL_RegI2L_imm" %}
 12056   ins_encode %{
 12057     Register src_reg = as_Register($src$$reg);
 12058     Register dst_reg = as_Register($dst$$reg);
 12059     int      shamt = $shift$$constant;
 12061     if (__ is_simm(shamt, 5))
 12062         __ dsll(dst_reg, src_reg, shamt);
 12063     else {
 12064       int sa = Assembler::low(shamt, 6);
 12065       if (sa < 32) {
 12066         __ dsll(dst_reg, src_reg, sa);
 12067       } else {
 12068         __ dsll32(dst_reg, src_reg, sa - 32);
 12071   %}
 12072   ins_pipe( ialu_regL_regL );
 12073 %}
 12075 // Shift Left Long
 12076 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12077   //predicate(UseNewLongLShift);
 12078   match(Set dst (LShiftL src shift));
 12079   ins_cost(100);
 12080   format %{ "salL    $dst, $src, $shift @ salL_Reg_Reg" %}
 12081   ins_encode %{
 12082     Register src_reg = as_Register($src$$reg);
 12083     Register dst_reg = as_Register($dst$$reg);
 12085     __ dsllv(dst_reg, src_reg, $shift$$Register);
 12086   %}
 12087   ins_pipe( ialu_regL_regL );
 12088 %}
 12090 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
 12091   match(Set dst (LShiftL (ConvI2L src) shift));
 12092   ins_cost(100);
 12093   format %{ "salL    $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
 12094   ins_encode %{
 12095     Register src_reg = as_Register($src$$reg);
 12096     Register dst_reg = as_Register($dst$$reg);
 12097     int      shamt = $shift$$constant;
 12099     if (__ is_simm(shamt, 5)) {
 12100       __ dsll(dst_reg, src_reg, shamt);
 12101     } else {
 12102       int sa = Assembler::low(shamt, 6);
 12103       if (sa < 32) {
 12104         __ dsll(dst_reg, src_reg, sa);
 12105       } else {
 12106         __ dsll32(dst_reg, src_reg, sa - 32);
 12109     %}
 12110   ins_pipe( ialu_regL_regL );
 12111 %}
 12113 // Shift Right Long
 12114 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 12115   match(Set dst (RShiftL src shift));
 12116   ins_cost(100);
 12117   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_imm" %}
 12118   ins_encode %{
 12119     Register src_reg = as_Register($src$$reg);
 12120     Register dst_reg = as_Register($dst$$reg);
 12121     int      shamt = ($shift$$constant & 0x3f);
 12122     if (__  is_simm(shamt, 5))
 12123       __ dsra(dst_reg, src_reg, shamt);
 12124     else {
 12125       int sa = Assembler::low(shamt, 6);
 12126       if (sa < 32) {
 12127         __ dsra(dst_reg, src_reg, sa);
 12128       } else {
 12129         __ dsra32(dst_reg, src_reg, sa - 32);
 12132   %}
 12133   ins_pipe( ialu_regL_regL );
 12134 %}
 12136 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
 12137   match(Set dst (ConvL2I (RShiftL src shift)));
 12138   ins_cost(100);
 12139   format %{ "sarL    $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
 12140   ins_encode %{
 12141     Register src_reg = as_Register($src$$reg);
 12142     Register dst_reg = as_Register($dst$$reg);
 12143     int      shamt   = $shift$$constant;
 12145     __ dsra32(dst_reg, src_reg, shamt - 32);
 12146   %}
 12147   ins_pipe( ialu_regL_regL );
 12148 %}
 12150 // Shift Right Long arithmetically
 12151 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12152   //predicate(UseNewLongLShift);
 12153   match(Set dst (RShiftL src shift));
 12154   ins_cost(100);
 12155   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_Reg" %}
 12156   ins_encode %{
 12157     Register src_reg = as_Register($src$$reg);
 12158     Register dst_reg = as_Register($dst$$reg);
 12160     __ dsrav(dst_reg, src_reg, $shift$$Register);
 12161   %}
 12162   ins_pipe( ialu_regL_regL );
 12163 %}
 12165 // Shift Right Long logically
 12166 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 12167   match(Set dst (URShiftL src shift));
 12168   ins_cost(100);
 12169   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_Reg" %}
 12170   ins_encode %{
 12171     Register src_reg = as_Register($src$$reg);
 12172     Register dst_reg = as_Register($dst$$reg);
 12174     __ dsrlv(dst_reg, src_reg, $shift$$Register);
 12175   %}
 12176   ins_pipe( ialu_regL_regL );
 12177 %}
 12179 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
 12180   match(Set dst (URShiftL src shift));
 12181   ins_cost(80);
 12182   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
 12183   ins_encode %{
 12184     Register src_reg = as_Register($src$$reg);
 12185     Register dst_reg = as_Register($dst$$reg);
 12186     int        shamt = $shift$$constant;
 12188     __ dsrl(dst_reg, src_reg, shamt);
 12189   %}
 12190   ins_pipe( ialu_regL_regL );
 12191 %}
 12193 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
 12194   match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
 12195   ins_cost(80);
 12196   format %{ "dext    $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
 12197   ins_encode %{
 12198     Register src_reg = as_Register($src$$reg);
 12199     Register dst_reg = as_Register($dst$$reg);
 12200     int        shamt = $shift$$constant;
 12202     __ dext(dst_reg, src_reg, shamt, 31);
 12203   %}
 12204   ins_pipe( ialu_regL_regL );
 12205 %}
 12207 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
 12208   match(Set dst (URShiftL (CastP2X src) shift));
 12209   ins_cost(80);
 12210   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
 12211   ins_encode %{
 12212     Register src_reg = as_Register($src$$reg);
 12213     Register dst_reg = as_Register($dst$$reg);
 12214     int        shamt = $shift$$constant;
 12216     __ dsrl(dst_reg, src_reg, shamt);
 12217   %}
 12218   ins_pipe( ialu_regL_regL );
 12219 %}
 12221 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
 12222   match(Set dst (URShiftL src shift));
 12223   ins_cost(80);
 12224   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
 12225   ins_encode %{
 12226     Register src_reg = as_Register($src$$reg);
 12227     Register dst_reg = as_Register($dst$$reg);
 12228     int        shamt = $shift$$constant;
 12230     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12231   %}
 12232   ins_pipe( ialu_regL_regL );
 12233 %}
 12235 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
 12236   match(Set dst (ConvL2I (URShiftL src shift)));
 12237   predicate(n->in(1)->in(2)->get_int() > 32);
 12238   ins_cost(80);
 12239   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
 12240   ins_encode %{
 12241     Register src_reg = as_Register($src$$reg);
 12242     Register dst_reg = as_Register($dst$$reg);
 12243     int        shamt = $shift$$constant;
 12245     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12246   %}
 12247   ins_pipe( ialu_regL_regL );
 12248 %}
 12250 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
 12251   match(Set dst (URShiftL (CastP2X src) shift));
 12252   ins_cost(80);
 12253   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
 12254   ins_encode %{
 12255     Register src_reg = as_Register($src$$reg);
 12256     Register dst_reg = as_Register($dst$$reg);
 12257     int        shamt = $shift$$constant;
 12259     __ dsrl32(dst_reg, src_reg, shamt - 32);
 12260   %}
 12261   ins_pipe( ialu_regL_regL );
 12262 %}
 12264 // Xor Instructions
 12265 // Xor Register with Register
 12266 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 12267   match(Set dst (XorI src1 src2));
 12269   format %{ "XOR    $dst, $src1, $src2 #@xorI_Reg_Reg" %}
 12271   ins_encode %{
 12272     Register  dst = $dst$$Register;
 12273     Register src1 = $src1$$Register;
 12274     Register src2 = $src2$$Register;
 12275     __ xorr(dst, src1, src2);
 12276     __ sll(dst, dst, 0); /* long -> int */
 12277   %}
 12279   ins_pipe( ialu_regI_regI );
 12280 %}
 12282 // Or Instructions
 12283 // Or Register with Register
 12284 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 12285   match(Set dst (OrI src1 src2));
 12287   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_Reg" %}
 12288   ins_encode %{
 12289     Register  dst = $dst$$Register;
 12290     Register src1 = $src1$$Register;
 12291     Register src2 = $src2$$Register;
 12292     __ orr(dst, src1, src2);
 12293   %}
 12295   ins_pipe( ialu_regI_regI );
 12296 %}
 12298 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
 12299   match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
 12300   predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
 12302   format %{ "rotr     $dst, $src, 1 ...\n\t"
 12303             "srl      $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
 12304   ins_encode %{
 12305     Register   dst = $dst$$Register;
 12306     Register   src = $src$$Register;
 12307     int     rshift = $rshift$$constant;
 12309     __ rotr(dst, src, 1);
 12310     if (rshift - 1) {
 12311       __ srl(dst, dst, rshift - 1);
 12313   %}
 12315   ins_pipe( ialu_regI_regI );
 12316 %}
 12318 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
 12319   match(Set dst (OrI src1 (CastP2X src2)));
 12321   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_castP2X" %}
 12322   ins_encode %{
 12323     Register  dst = $dst$$Register;
 12324     Register src1 = $src1$$Register;
 12325     Register src2 = $src2$$Register;
 12326     __ orr(dst, src1, src2);
 12327   %}
 12329   ins_pipe( ialu_regI_regI );
 12330 %}
 12332 // Logical Shift Right by 8-bit immediate
 12333 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 12334   match(Set dst (URShiftI src shift));
 12335   //effect(KILL cr);
 12337   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_imm" %}
 12338   ins_encode %{
 12339     Register src = $src$$Register;
 12340     Register dst = $dst$$Register;
 12341     int    shift = $shift$$constant;
 12343     __ srl(dst, src, shift);
 12344   %}
 12345   ins_pipe( ialu_regI_regI );
 12346 %}
 12348 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
 12349   match(Set dst (AndI (URShiftI src shift) mask));
 12351   format %{ "ext    $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
 12352   ins_encode %{
 12353     Register src = $src$$Register;
 12354     Register dst = $dst$$Register;
 12355     int      pos = $shift$$constant;
 12356     int     size = Assembler::is_int_mask($mask$$constant);
 12358     __ ext(dst, src, pos, size);
 12359   %}
 12360   ins_pipe( ialu_regI_regI );
 12361 %}
 12363 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
 12364 %{
 12365   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 12366   match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
 12368   ins_cost(100);
 12369   format %{ "rotr    $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
 12370   ins_encode %{
 12371     Register dst = $dst$$Register;
 12372     int      sa  = $rshift$$constant;
 12374     __ rotr(dst, dst, sa);
 12375   %}
 12376   ins_pipe( ialu_regI_regI );
 12377 %}
 12379 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
 12380 %{
 12381   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12382   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 12384   ins_cost(100);
 12385   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
 12386   ins_encode %{
 12387     Register dst = $dst$$Register;
 12388     int      sa  = $rshift$$constant;
 12390     __ drotr(dst, dst, sa);
 12391   %}
 12392   ins_pipe( ialu_regI_regI );
 12393 %}
 12395 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
 12396 %{
 12397   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12398   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 12400   ins_cost(100);
 12401   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
 12402   ins_encode %{
 12403     Register dst = $dst$$Register;
 12404     int      sa  = $rshift$$constant;
 12406     __ drotr32(dst, dst, sa - 32);
 12407   %}
 12408   ins_pipe( ialu_regI_regI );
 12409 %}
 12411 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
 12412 %{
 12413   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 12414   match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
 12416   ins_cost(100);
 12417   format %{ "rotr    $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
 12418   ins_encode %{
 12419     Register dst = $dst$$Register;
 12420     int      sa  = $rshift$$constant;
 12422     __ rotr(dst, dst, sa);
 12423   %}
 12424   ins_pipe( ialu_regI_regI );
 12425 %}
 12427 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
 12428 %{
 12429   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12430   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 12432   ins_cost(100);
 12433   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
 12434   ins_encode %{
 12435     Register dst = $dst$$Register;
 12436     int      sa  = $rshift$$constant;
 12438     __ drotr(dst, dst, sa);
 12439   %}
 12440   ins_pipe( ialu_regI_regI );
 12441 %}
 12443 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
 12444 %{
 12445   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 12446   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 12448   ins_cost(100);
 12449   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
 12450   ins_encode %{
 12451     Register dst = $dst$$Register;
 12452     int      sa  = $rshift$$constant;
 12454     __ drotr32(dst, dst, sa - 32);
 12455   %}
 12456   ins_pipe( ialu_regI_regI );
 12457 %}
 12459 // Logical Shift Right
 12460 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12461   match(Set dst (URShiftI src shift));
 12463   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_Reg" %}
 12464   ins_encode %{
 12465     Register src = $src$$Register;
 12466     Register dst = $dst$$Register;
 12467     Register shift = $shift$$Register;
 12468     __ srlv(dst, src, shift);
 12469   %}
 12470   ins_pipe( ialu_regI_regI );
 12471 %}
 12474 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 12475   match(Set dst (RShiftI src shift));
 12476  // effect(KILL cr);
 12478   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_imm" %}
 12479   ins_encode %{
 12480     Register src = $src$$Register;
 12481     Register dst = $dst$$Register;
 12482     int    shift = $shift$$constant;
 12483     __ sra(dst, src, shift);
 12484   %}
 12485   ins_pipe( ialu_regI_regI );
 12486 %}
 12488 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 12489   match(Set dst (RShiftI src shift));
 12490  // effect(KILL cr);
 12492   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_Reg" %}
 12493   ins_encode %{
 12494     Register src = $src$$Register;
 12495     Register dst = $dst$$Register;
 12496     Register shift = $shift$$Register;
 12497     __ srav(dst, src, shift);
 12498   %}
 12499   ins_pipe( ialu_regI_regI );
 12500 %}
 12502 //----------Convert Int to Boolean---------------------------------------------
 12504 instruct convI2B(mRegI dst, mRegI src) %{
 12505   match(Set dst (Conv2B src));
 12507   ins_cost(100);
 12508   format %{ "convI2B    $dst, $src @ convI2B"  %}
 12509   ins_encode %{
 12510     Register dst = as_Register($dst$$reg);
 12511     Register src = as_Register($src$$reg);
 12513     if (dst != src) {
 12514       __ daddiu(dst, R0, 1);
 12515       __ movz(dst, R0, src);
 12516     } else {
 12517       __ move(AT, src);
 12518       __ daddiu(dst, R0, 1);
 12519       __ movz(dst, R0, AT);
 12521   %}
 12523   ins_pipe( ialu_regL_regL );
 12524 %}
 12526 instruct convI2L_reg( mRegL dst, mRegI src) %{
 12527   match(Set dst (ConvI2L src));
 12529   ins_cost(100);
 12530   format %{ "SLL    $dst, $src @ convI2L_reg\t"  %}
 12531   ins_encode %{
 12532     Register dst = as_Register($dst$$reg);
 12533     Register src = as_Register($src$$reg);
 12535     if(dst != src) __ sll(dst, src, 0);
 12536   %}
 12537   ins_pipe( ialu_regL_regL );
 12538 %}
 12541 instruct convL2I_reg( mRegI dst, mRegL src ) %{
 12542   match(Set dst (ConvL2I src));
 12544   format %{ "MOV    $dst, $src @ convL2I_reg" %}
 12545   ins_encode %{
 12546     Register dst = as_Register($dst$$reg);
 12547     Register src = as_Register($src$$reg);
 12549     __ sll(dst, src, 0);
 12550   %}
 12552   ins_pipe( ialu_regI_regI );
 12553 %}
 12555 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
 12556   match(Set dst (ConvI2L (ConvL2I src)));
 12558   format %{ "sll    $dst, $src, 0 @ convL2I2L_reg" %}
 12559   ins_encode %{
 12560     Register dst = as_Register($dst$$reg);
 12561     Register src = as_Register($src$$reg);
 12563     __ sll(dst, src, 0);
 12564   %}
 12566   ins_pipe( ialu_regI_regI );
 12567 %}
 12569 instruct convL2D_reg( regD dst, mRegL src ) %{
 12570   match(Set dst (ConvL2D src));
 12571   format %{ "convL2D    $dst, $src @ convL2D_reg" %}
 12572   ins_encode %{
 12573     Register src = as_Register($src$$reg);
 12574     FloatRegister dst = as_FloatRegister($dst$$reg);
 12576     __ dmtc1(src, dst);
 12577     __ cvt_d_l(dst, dst);
 12578   %}
 12580   ins_pipe( pipe_slow );
 12581 %}
 12584 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
 12585   match(Set dst (ConvD2L src));
 12586   ins_cost(150);
 12587   format %{ "convD2L    $dst, $src @ convD2L_reg_fast" %}
 12588   ins_encode %{
 12589     Register dst = as_Register($dst$$reg);
 12590     FloatRegister src = as_FloatRegister($src$$reg);
 12592     Label Done;
 12594     __ trunc_l_d(F30, src);
 12595     // max_long:    0x7fffffffffffffff
 12596     // __ set64(AT, 0x7fffffffffffffff);
 12597     __ daddiu(AT, R0, -1);
 12598     __ dsrl(AT, AT, 1);
 12599     __ dmfc1(dst, F30);
 12601     __ bne(dst, AT, Done);
 12602     __ delayed()->mtc1(R0, F30);
 12604     __ cvt_d_w(F30, F30);
 12605     __ c_ult_d(src, F30);
 12606     __ bc1f(Done);
 12607     __ delayed()->daddiu(T9, R0, -1);
 12609     __ c_un_d(src, src);    //NaN?
 12610     __ subu(dst, T9, AT);
 12611     __ movt(dst, R0);
 12613     __ bind(Done);
 12614   %}
 12616   ins_pipe( pipe_slow );
 12617 %}
 12620 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
 12621   match(Set dst (ConvD2L src));
 12622   ins_cost(250);
 12623   format %{ "convD2L    $dst, $src @ convD2L_reg_slow" %}
 12624   ins_encode %{
 12625     Register dst = as_Register($dst$$reg);
 12626     FloatRegister src = as_FloatRegister($src$$reg);
 12628     Label L;
 12630     __ c_un_d(src, src);    //NaN?
 12631     __ bc1t(L);
 12632     __ delayed();
 12633     __ move(dst, R0);
 12635     __ trunc_l_d(F30, src);
 12636     __ cfc1(AT, 31);
 12637     __ li(T9, 0x10000);
 12638     __ andr(AT, AT, T9);
 12639     __ beq(AT, R0, L);
 12640     __ delayed()->dmfc1(dst, F30);
 12642     __ mov_d(F12, src);
 12643     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
 12644     __ move(dst, V0);
 12645     __ bind(L);
 12646   %}
 12648   ins_pipe( pipe_slow );
 12649 %}
 12652 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
 12653   match(Set dst (ConvF2I src));
 12654   ins_cost(150);
 12655   format %{ "convf2i    $dst, $src @ convF2I_reg_fast" %}
 12656   ins_encode %{
 12657     Register      dreg = $dst$$Register;
 12658     FloatRegister fval = $src$$FloatRegister;
 12659     Label L;
 12661     __ trunc_w_s(F30, fval);
 12662     __ move(AT, 0x7fffffff);
 12663     __ mfc1(dreg, F30);
 12664     __ c_un_s(fval, fval);    //NaN?
 12665     __ movt(dreg, R0);
 12667     __ bne(AT, dreg, L);
 12668     __ delayed()->lui(T9, 0x8000);
 12670     __ mfc1(AT, fval);
 12671     __ andr(AT, AT, T9);
 12673     __ movn(dreg, T9, AT);
 12675     __ bind(L);
 12677   %}
 12679   ins_pipe( pipe_slow );
 12680 %}
 12684 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
 12685   match(Set dst (ConvF2I src));
 12686   ins_cost(250);
 12687   format %{ "convf2i    $dst, $src @ convF2I_reg_slow" %}
 12688   ins_encode %{
 12689     Register      dreg = $dst$$Register;
 12690     FloatRegister fval = $src$$FloatRegister;
 12691     Label L;
 12693     __ c_un_s(fval, fval);    //NaN?
 12694     __ bc1t(L);
 12695     __ delayed();
 12696     __ move(dreg, R0);
 12698     __ trunc_w_s(F30, fval);
 12700     /* Call SharedRuntime:f2i() to do valid convention */
 12701     __ cfc1(AT, 31);
 12702     __ li(T9, 0x10000);
 12703     __ andr(AT, AT, T9);
 12704     __ beq(AT, R0, L);
 12705     __ delayed()->mfc1(dreg, F30);
 12707     __ mov_s(F12, fval);
 12709     //This bug was found when running ezDS's control-panel.
 12710     //    J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
 12711     //
 12712     // An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
 12713     // V0 is corrupted during call_VM_leaf(), and should be preserved.
 12714     //
 12715     __ push(fval);
 12716     if(dreg != V0) {
 12717       __ push(V0);
 12719     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
 12720     if(dreg != V0) {
 12721       __ move(dreg, V0);
 12722       __ pop(V0);
 12724     __ pop(fval);
 12725     __ bind(L);
 12726   %}
 12728   ins_pipe( pipe_slow );
 12729 %}
 12732 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
 12733   match(Set dst (ConvF2L src));
 12734   ins_cost(150);
 12735   format %{ "convf2l    $dst, $src @ convF2L_reg_fast" %}
 12736   ins_encode %{
 12737     Register      dreg = $dst$$Register;
 12738     FloatRegister fval = $src$$FloatRegister;
 12739     Label L;
 12741     __ trunc_l_s(F30, fval);
 12742     __ daddiu(AT, R0, -1);
 12743     __ dsrl(AT, AT, 1);
 12744     __ dmfc1(dreg, F30);
 12745     __ c_un_s(fval, fval);    //NaN?
 12746     __ movt(dreg, R0);
 12748     __ bne(AT, dreg, L);
 12749     __ delayed()->lui(T9, 0x8000);
 12751     __ mfc1(AT, fval);
 12752     __ andr(AT, AT, T9);
 12754     __ dsll32(T9, T9, 0);
 12755     __ movn(dreg, T9, AT);
 12757     __ bind(L);
 12758   %}
 12760   ins_pipe( pipe_slow );
 12761 %}
 12764 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
 12765   match(Set dst (ConvF2L src));
 12766   ins_cost(250);
 12767   format %{ "convf2l    $dst, $src @ convF2L_reg_slow" %}
 12768   ins_encode %{
 12769     Register dst = as_Register($dst$$reg);
 12770     FloatRegister fval = $src$$FloatRegister;
 12771     Label L;
 12773     __ c_un_s(fval, fval);    //NaN?
 12774     __ bc1t(L);
 12775     __ delayed();
 12776     __ move(dst, R0);
 12778     __ trunc_l_s(F30, fval);
 12779     __ cfc1(AT, 31);
 12780     __ li(T9, 0x10000);
 12781     __ andr(AT, AT, T9);
 12782     __ beq(AT, R0, L);
 12783     __ delayed()->dmfc1(dst, F30);
 12785     __ mov_s(F12, fval);
 12786     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
 12787     __ move(dst, V0);
 12788     __ bind(L);
 12789   %}
 12791   ins_pipe( pipe_slow );
 12792 %}
 12794 instruct convL2F_reg( regF dst, mRegL src ) %{
 12795   match(Set dst (ConvL2F src));
 12796   format %{ "convl2f    $dst, $src @ convL2F_reg" %}
 12797   ins_encode %{
 12798     FloatRegister dst = $dst$$FloatRegister;
 12799     Register src = as_Register($src$$reg);
 12800     Label L;
 12802     __ dmtc1(src, dst);
 12803     __ cvt_s_l(dst, dst);
 12804   %}
 12806   ins_pipe( pipe_slow );
 12807 %}
 12809 instruct convI2F_reg( regF dst, mRegI src ) %{
 12810   match(Set dst (ConvI2F src));
 12811   format %{ "convi2f    $dst, $src @ convI2F_reg" %}
 12812   ins_encode %{
 12813     Register      src = $src$$Register;
 12814     FloatRegister dst = $dst$$FloatRegister;
 12816     __ mtc1(src, dst);
 12817     __ cvt_s_w(dst, dst);
 12818   %}
 12820   ins_pipe( fpu_regF_regF );
 12821 %}
 12823 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
 12824   match(Set dst (CmpLTMask p zero));
 12825   ins_cost(100);
 12827   format %{ "sra    $dst, $p, 31 @ cmpLTMask_immI0" %}
 12828     ins_encode %{
 12829        Register src = $p$$Register;
 12830        Register dst = $dst$$Register;
 12832        __ sra(dst, src, 31);
 12833     %}
 12834     ins_pipe( pipe_slow );
 12835 %}
 12838 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
 12839   match(Set dst (CmpLTMask p q));
 12840   ins_cost(400);
 12842   format %{ "cmpLTMask    $dst, $p, $q @ cmpLTMask" %}
 12843   ins_encode %{
 12844     Register p   = $p$$Register;
 12845     Register q   = $q$$Register;
 12846     Register dst = $dst$$Register;
 12848     __ slt(dst, p, q);
 12849     __ subu(dst, R0, dst);
 12850     %}
 12851   ins_pipe( pipe_slow );
 12852 %}
 12854 instruct convP2B(mRegI dst, mRegP src) %{
 12855   match(Set dst (Conv2B src));
 12857   ins_cost(100);
 12858   format %{ "convP2B    $dst, $src @ convP2B"  %}
 12859   ins_encode %{
 12860     Register dst = as_Register($dst$$reg);
 12861     Register src = as_Register($src$$reg);
 12863     if (dst != src) {
 12864       __ daddiu(dst, R0, 1);
 12865       __ movz(dst, R0, src);
 12866     } else {
 12867       __ move(AT, src);
 12868       __ daddiu(dst, R0, 1);
 12869       __ movz(dst, R0, AT);
 12871   %}
 12873   ins_pipe( ialu_regL_regL );
 12874 %}
 12877 instruct convI2D_reg_reg(regD dst, mRegI src) %{
 12878   match(Set dst (ConvI2D src));
 12879   format %{ "conI2D $dst, $src @convI2D_reg" %}
 12880   ins_encode %{
 12881     Register      src = $src$$Register;
 12882     FloatRegister dst = $dst$$FloatRegister;
 12883     __ mtc1(src, dst);
 12884     __ cvt_d_w(dst, dst);
 12885     %}
 12886   ins_pipe( fpu_regF_regF );
 12887 %}
 12889 instruct convF2D_reg_reg(regD dst, regF src) %{
 12890   match(Set dst (ConvF2D src));
 12891   format %{ "convF2D  $dst, $src\t# @convF2D_reg_reg" %}
 12892   ins_encode %{
 12893     FloatRegister dst = $dst$$FloatRegister;
 12894     FloatRegister src = $src$$FloatRegister;
 12896     __ cvt_d_s(dst, src);
 12897   %}
 12898   ins_pipe( fpu_regF_regF );
 12899 %}
 12901 instruct convD2F_reg_reg(regF dst, regD src) %{
 12902   match(Set dst (ConvD2F src));
 12903   format %{ "convD2F  $dst, $src\t# @convD2F_reg_reg" %}
 12904   ins_encode %{
 12905     FloatRegister dst = $dst$$FloatRegister;
 12906     FloatRegister src = $src$$FloatRegister;
 12908     __ cvt_s_d(dst, src);
 12909   %}
 12910   ins_pipe( fpu_regF_regF );
 12911 %}
 12914 // Convert a double to an int.  If the double is a NAN, stuff a zero in instead.
 12915 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
 12916   match(Set dst (ConvD2I src));
 12918   ins_cost(150);
 12919   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
 12921   ins_encode %{
 12922     FloatRegister src = $src$$FloatRegister;
 12923     Register      dst = $dst$$Register;
 12925     Label Done;
 12927     __ trunc_w_d(F30, src);
 12928     // max_int: 2147483647
 12929     __ move(AT, 0x7fffffff);
 12930     __ mfc1(dst, F30);
 12932     __ bne(dst, AT, Done);
 12933     __ delayed()->mtc1(R0, F30);
 12935     __ cvt_d_w(F30, F30);
 12936     __ c_ult_d(src, F30);
 12937     __ bc1f(Done);
 12938     __ delayed()->addiu(T9, R0, -1);
 12940     __ c_un_d(src, src);    //NaN?
 12941     __ subu32(dst, T9, AT);
 12942     __ movt(dst, R0);
 12944     __ bind(Done);
 12945   %}
 12946   ins_pipe( pipe_slow );
 12947 %}
 12950 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
 12951   match(Set dst (ConvD2I src));
 12953   ins_cost(250);
 12954   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
 12956   ins_encode %{
 12957     FloatRegister src = $src$$FloatRegister;
 12958     Register      dst = $dst$$Register;
 12959     Label L;
 12961     __ trunc_w_d(F30, src);
 12962     __ cfc1(AT, 31);
 12963     __ li(T9, 0x10000);
 12964     __ andr(AT, AT, T9);
 12965     __ beq(AT, R0, L);
 12966     __ delayed()->mfc1(dst, F30);
 12968     __ mov_d(F12, src);
 12969     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
 12970     __ move(dst, V0);
 12971     __ bind(L);
 12973   %}
 12974   ins_pipe( pipe_slow );
 12975 %}
 12977 // Convert oop pointer into compressed form
 12978 instruct encodeHeapOop(mRegN dst, mRegP src) %{
 12979   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 12980   match(Set dst (EncodeP src));
 12981   format %{ "encode_heap_oop $dst,$src" %}
 12982   ins_encode %{
 12983     Register src = $src$$Register;
 12984     Register dst = $dst$$Register;
 12986     __ encode_heap_oop(dst, src);
 12987   %}
 12988   ins_pipe( ialu_regL_regL );
 12989 %}
 12991 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
 12992   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
 12993   match(Set dst (EncodeP src));
 12994   format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
 12995   ins_encode %{
 12996     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
 12997   %}
 12998   ins_pipe( ialu_regL_regL );
 12999 %}
 13001 instruct decodeHeapOop(mRegP dst, mRegN src) %{
 13002   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
 13003             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
 13004   match(Set dst (DecodeN src));
 13005   format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
 13006   ins_encode %{
 13007     Register s = $src$$Register;
 13008     Register d = $dst$$Register;
 13010     __ decode_heap_oop(d, s);
 13011   %}
 13012   ins_pipe( ialu_regL_regL );
 13013 %}
 13015 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
 13016   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
 13017             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
 13018   match(Set dst (DecodeN src));
 13019   format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
 13020   ins_encode %{
 13021     Register s = $src$$Register;
 13022     Register d = $dst$$Register;
 13023     if (s != d) {
 13024       __ decode_heap_oop_not_null(d, s);
 13025     } else {
 13026       __ decode_heap_oop_not_null(d);
 13028   %}
 13029   ins_pipe( ialu_regL_regL );
 13030 %}
 13032 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
 13033   match(Set dst (EncodePKlass src));
 13034   format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
 13035   ins_encode %{
 13036     __ encode_klass_not_null($dst$$Register, $src$$Register);
 13037   %}
 13038   ins_pipe( ialu_regL_regL );
 13039 %}
 13041 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
 13042   match(Set dst (DecodeNKlass src));
 13043   format %{ "decode_heap_klass_not_null $dst,$src" %}
 13044   ins_encode %{
 13045     Register s = $src$$Register;
 13046     Register d = $dst$$Register;
 13047     if (s != d) {
 13048       __ decode_klass_not_null(d, s);
 13049     } else {
 13050       __ decode_klass_not_null(d);
 13052   %}
 13053   ins_pipe( ialu_regL_regL );
 13054 %}
 13056 //FIXME
 13057 instruct tlsLoadP(mRegP dst) %{
 13058   match(Set dst (ThreadLocal));
 13060   ins_cost(0);
 13061   format %{ " get_thread in $dst #@tlsLoadP" %}
 13062   ins_encode %{
 13063     Register dst = $dst$$Register;
 13064 #ifdef OPT_THREAD
 13065     __ move(dst, TREG);
 13066 #else
 13067     __ get_thread(dst);
 13068 #endif
 13069   %}
 13071   ins_pipe( ialu_loadI );
 13072 %}
 13075 instruct checkCastPP( mRegP dst ) %{
 13076   match(Set dst (CheckCastPP dst));
 13078   format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
 13079   ins_encode( /*empty encoding*/ );
 13080   ins_pipe( empty );
 13081 %}
 13083 instruct castPP(mRegP dst)
 13084 %{
 13085   match(Set dst (CastPP dst));
 13087   size(0);
 13088   format %{ "# castPP of $dst" %}
 13089   ins_encode(/* empty encoding */);
 13090   ins_pipe(empty);
 13091 %}
 13093 instruct castII( mRegI dst ) %{
 13094   match(Set dst (CastII dst));
 13095   format %{ "#castII of $dst  empty encoding" %}
 13096   ins_encode( /*empty encoding*/ );
 13097   ins_cost(0);
 13098   ins_pipe( empty );
 13099 %}
 13101 // Return Instruction
 13102 // Remove the return address & jump to it.
 13103 instruct Ret() %{
 13104   match(Return);
 13105   format %{ "RET #@Ret" %}
 13107   ins_encode %{
 13108    __ jr(RA);
 13109    __ delayed()->nop();
 13110   %}
 13112   ins_pipe( pipe_jump );
 13113 %}
 13115 /*
 13116 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
 13117 instruct jumpXtnd(mRegL switch_val) %{
 13118   match(Jump switch_val);
 13120   ins_cost(350);
 13122   format %{  "load   T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
 13123              "jr     T9\n\t"
 13124              "nop" %}
 13125   ins_encode %{
 13126     Register table_base = $constanttablebase;
 13127     int      con_offset = $constantoffset;
 13128     Register switch_reg = $switch_val$$Register;
 13130     if (UseLoongsonISA) {
 13131        if (Assembler::is_simm(con_offset, 8)) {
 13132          __ gsldx(T9, table_base, switch_reg, con_offset);
 13133        } else if (Assembler::is_simm16(con_offset)) {
 13134          __ daddu(T9, table_base, switch_reg);
 13135          __ ld(T9, T9, con_offset);
 13136        } else {
 13137          __ move(T9, con_offset);
 13138          __ daddu(AT, table_base, switch_reg);
 13139          __ gsldx(T9, AT, T9, 0);
 13141     } else {
 13142        if (Assembler::is_simm16(con_offset)) {
 13143          __ daddu(T9, table_base, switch_reg);
 13144          __ ld(T9, T9, con_offset);
 13145        } else {
 13146          __ move(T9, con_offset);
 13147          __ daddu(AT, table_base, switch_reg);
 13148          __ daddu(AT, T9, AT);
 13149          __ ld(T9, AT, 0);
 13153     __ jr(T9);
 13154     __ delayed()->nop();
 13156   %}
 13157   ins_pipe(pipe_jump);
 13158 %}
 13159 */
 13162 // Tail Jump; remove the return address; jump to target.
 13163 // TailCall above leaves the return address around.
 13164 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 13165 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 13166 // "restore" before this instruction (in Epilogue), we need to materialize it
 13167 // in %i0.
 13168 //FIXME
 13169 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
 13170   match( TailJump jump_target ex_oop );
 13171   ins_cost(200);
 13172   format %{ "Jmp     $jump_target  ; ex_oop = $ex_oop #@tailjmpInd" %}
 13173   ins_encode %{
 13174     Register target = $jump_target$$Register;
 13176     // V0, V1 are indicated in:
 13177     //     [stubGenerator_mips.cpp] generate_forward_exception()
 13178     //     [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
 13179     //
 13180     Register oop  = $ex_oop$$Register;
 13181     Register exception_oop = V0;
 13182     Register exception_pc = V1;
 13184     __ move(exception_pc, RA);
 13185     __ move(exception_oop, oop);
 13187     __ jr(target);
 13188     __ delayed()->nop();
 13189   %}
 13190   ins_pipe( pipe_jump );
 13191 %}
 13193 // ============================================================================
 13194 // Procedure Call/Return Instructions
 13195 // Call Java Static Instruction
 13196 // Note: If this code changes, the corresponding ret_addr_offset() and
 13197 //       compute_padding() functions will have to be adjusted.
 13198 instruct CallStaticJavaDirect(method meth) %{
 13199   match(CallStaticJava);
 13200   effect(USE meth);
 13202   ins_cost(300);
 13203   format %{ "CALL,static #@CallStaticJavaDirect " %}
 13204   ins_encode( Java_Static_Call( meth ) );
 13205   ins_pipe( pipe_slow );
 13206   ins_pc_relative(1);
 13207 %}
 13209 // Call Java Dynamic Instruction
 13210 // Note: If this code changes, the corresponding ret_addr_offset() and
 13211 //       compute_padding() functions will have to be adjusted.
 13212 instruct CallDynamicJavaDirect(method meth) %{
 13213   match(CallDynamicJava);
 13214   effect(USE meth);
 13216   ins_cost(300);
 13217   format %{"MOV IC_Klass, #Universe::non_oop_word()\n\t"
 13218            "CallDynamic @ CallDynamicJavaDirect" %}
 13219   ins_encode( Java_Dynamic_Call( meth ) );
 13220   ins_pipe( pipe_slow );
 13221   ins_pc_relative(1);
 13222 %}
 13224 instruct CallLeafNoFPDirect(method meth) %{
 13225   match(CallLeafNoFP);
 13226   effect(USE meth);
 13228   ins_cost(300);
 13229   format %{ "CALL_LEAF_NOFP,runtime " %}
 13230   ins_encode(Java_To_Runtime(meth));
 13231   ins_pipe( pipe_slow );
 13232   ins_pc_relative(1);
 13233   ins_alignment(16);
 13234 %}
 13236 // Prefetch instructions.
 13238 instruct prefetchrNTA( memory mem ) %{
 13239   match(PrefetchRead mem);
 13240   ins_cost(125);
 13242   format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
 13243   ins_encode %{
 13244     int  base = $mem$$base;
 13245     int  index = $mem$$index;
 13246     int  scale = $mem$$scale;
 13247     int  disp = $mem$$disp;
 13249     if( index != 0 ) {
 13250       if (scale == 0) {
 13251         __ daddu(AT, as_Register(base), as_Register(index));
 13252       } else {
 13253         __ dsll(AT, as_Register(index), scale);
 13254         __ daddu(AT, as_Register(base), AT);
 13256     } else {
 13257       __ move(AT, as_Register(base));
 13259     if( Assembler::is_simm16(disp) ) {
 13260       __ daddiu(AT, as_Register(base), disp);
 13261       __ daddiu(AT, AT, disp);
 13262     } else {
 13263       __ move(T9, disp);
 13264       __ daddu(AT, as_Register(base), T9);
 13266     __ pref(0, AT, 0); //hint: 0:load
 13267   %}
 13268   ins_pipe(pipe_slow);
 13269 %}
 13271 instruct prefetchwNTA( memory mem ) %{
 13272   match(PrefetchWrite mem);
 13273   ins_cost(125);
 13274   format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
 13275   ins_encode %{
 13276     int  base = $mem$$base;
 13277     int  index = $mem$$index;
 13278     int  scale = $mem$$scale;
 13279     int  disp = $mem$$disp;
 13281     if( index != 0 ) {
 13282       if (scale == 0) {
 13283         __ daddu(AT, as_Register(base), as_Register(index));
 13284       } else {
 13285         __ dsll(AT, as_Register(index), scale);
 13286         __ daddu(AT, as_Register(base), AT);
 13288     } else {
 13289       __ move(AT, as_Register(base));
 13291     if( Assembler::is_simm16(disp) ) {
 13292       __ daddiu(AT, as_Register(base), disp);
 13293       __ daddiu(AT, AT, disp);
 13294     } else {
 13295       __ move(T9, disp);
 13296       __ daddu(AT, as_Register(base), T9);
 13298      __ pref(1, AT, 0); //hint: 1:store
 13299   %}
 13300   ins_pipe(pipe_slow);
 13301 %}
 13303 // Prefetch instructions for allocation.
 13305 instruct prefetchAllocNTA( memory mem ) %{
 13306   match(PrefetchAllocation mem);
 13307   ins_cost(125);
 13308   format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
 13309   ins_encode %{
 13310     int  base = $mem$$base;
 13311     int  index = $mem$$index;
 13312     int  scale = $mem$$scale;
 13313     int  disp = $mem$$disp;
 13315     Register dst = R0;
 13317     if( index != 0 ) {
 13318       if( Assembler::is_simm16(disp) ) {
 13319         if( UseLoongsonISA ) {
 13320           if (scale == 0) {
 13321             __ gslbx(dst, as_Register(base), as_Register(index), disp);
 13322           } else {
 13323             __ dsll(AT, as_Register(index), scale);
 13324             __ gslbx(dst, as_Register(base), AT, disp);
 13326         } else {
 13327           if (scale == 0) {
 13328             __ addu(AT, as_Register(base), as_Register(index));
 13329           } else {
 13330             __ dsll(AT, as_Register(index), scale);
 13331             __ addu(AT, as_Register(base), AT);
 13333           __ lb(dst, AT, disp);
 13335       } else {
 13336         if (scale == 0) {
 13337           __ addu(AT, as_Register(base), as_Register(index));
 13338         } else {
 13339           __ dsll(AT, as_Register(index), scale);
 13340           __ addu(AT, as_Register(base), AT);
 13342         __ move(T9, disp);
 13343         if( UseLoongsonISA ) {
 13344           __ gslbx(dst, AT, T9, 0);
 13345         } else {
 13346           __ addu(AT, AT, T9);
 13347           __ lb(dst, AT, 0);
 13350     } else {
 13351       if( Assembler::is_simm16(disp) ) {
 13352         __ lb(dst, as_Register(base), disp);
 13353       } else {
 13354         __ move(T9, disp);
 13355         if( UseLoongsonISA ) {
 13356           __ gslbx(dst, as_Register(base), T9, 0);
 13357         } else {
 13358           __ addu(AT, as_Register(base), T9);
 13359           __ lb(dst, AT, 0);
 13363   %}
 13364   ins_pipe(pipe_slow);
 13365 %}
 13368 // Call runtime without safepoint
 13369 instruct CallLeafDirect(method meth) %{
 13370   match(CallLeaf);
 13371   effect(USE meth);
 13373   ins_cost(300);
 13374   format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
 13375   ins_encode(Java_To_Runtime(meth));
 13376   ins_pipe( pipe_slow );
 13377   ins_pc_relative(1);
 13378   ins_alignment(16);
 13379 %}
 13381 // Load Char (16bit unsigned)
 13382 instruct loadUS(mRegI dst, memory mem) %{
 13383   match(Set dst (LoadUS mem));
 13385   ins_cost(125);
 13386   format %{ "loadUS  $dst,$mem @ loadC" %}
 13387   ins_encode(load_C_enc(dst, mem));
 13388   ins_pipe( ialu_loadI );
 13389 %}
 13391 instruct loadUS_convI2L(mRegL dst, memory mem) %{
 13392   match(Set dst (ConvI2L (LoadUS mem)));
 13394   ins_cost(125);
 13395   format %{ "loadUS  $dst,$mem @ loadUS_convI2L" %}
 13396   ins_encode(load_C_enc(dst, mem));
 13397   ins_pipe( ialu_loadI );
 13398 %}
 13400 // Store Char (16bit unsigned)
 13401 instruct storeC(memory mem, mRegI src) %{
 13402   match(Set mem (StoreC mem src));
 13404   ins_cost(125);
 13405   format %{ "storeC  $src, $mem @ storeC" %}
 13406   ins_encode(store_C_reg_enc(mem, src));
 13407   ins_pipe( ialu_loadI );
 13408 %}
 13410 instruct storeC0(memory mem, immI0 zero) %{
 13411   match(Set mem (StoreC mem zero));
 13413   ins_cost(125);
 13414   format %{ "storeC  $zero, $mem @ storeC0" %}
 13415   ins_encode(store_C0_enc(mem));
 13416   ins_pipe( ialu_loadI );
 13417 %}
 13420 instruct loadConF0(regF dst, immF0 zero) %{
 13421   match(Set dst zero);
 13422   ins_cost(100);
 13424   format %{ "mov  $dst, zero @ loadConF0\n"%}
 13425   ins_encode %{
 13426     FloatRegister dst = $dst$$FloatRegister;
 13428     __ mtc1(R0, dst);
 13429   %}
 13430   ins_pipe( fpu_loadF );
 13431 %}
 13434 instruct loadConF(regF dst, immF src) %{
 13435   match(Set dst src);
 13436   ins_cost(125);
 13438   format %{ "lwc1  $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
 13439   ins_encode %{
 13440     int con_offset = $constantoffset($src);
 13442     if (Assembler::is_simm16(con_offset)) {
 13443       __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
 13444     } else {
 13445       __ set64(AT, con_offset);
 13446       if (UseLoongsonISA) {
 13447         __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 13448       } else {
 13449         __ daddu(AT, $constanttablebase, AT);
 13450         __ lwc1($dst$$FloatRegister, AT, 0);
 13453   %}
 13454   ins_pipe( fpu_loadF );
 13455 %}
 13458 instruct loadConD0(regD dst, immD0 zero) %{
 13459   match(Set dst zero);
 13460   ins_cost(100);
 13462   format %{ "mov  $dst, zero @ loadConD0"%}
 13463   ins_encode %{
 13464     FloatRegister dst = as_FloatRegister($dst$$reg);
 13466     __ dmtc1(R0, dst);
 13467   %}
 13468   ins_pipe( fpu_loadF );
 13469 %}
 13471 instruct loadConD(regD dst, immD src) %{
 13472   match(Set dst src);
 13473   ins_cost(125);
 13475   format %{ "ldc1  $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
 13476   ins_encode %{
 13477     int con_offset = $constantoffset($src);
 13479     if (Assembler::is_simm16(con_offset)) {
 13480       __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
 13481     } else {
 13482       __ set64(AT, con_offset);
 13483       if (UseLoongsonISA) {
 13484         __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 13485       } else {
 13486         __ daddu(AT, $constanttablebase, AT);
 13487         __ ldc1($dst$$FloatRegister, AT, 0);
 13490   %}
 13491   ins_pipe( fpu_loadF );
 13492 %}
 13494 // Store register Float value (it is faster than store from FPU register)
 13495 instruct storeF_reg( memory mem, regF src) %{
 13496   match(Set mem (StoreF mem src));
 13498   ins_cost(50);
 13499   format %{ "store   $mem, $src\t# store float @ storeF_reg" %}
 13500   ins_encode(store_F_reg_enc(mem, src));
 13501   ins_pipe( fpu_storeF );
 13502 %}
 13504 instruct storeF_imm0( memory mem, immF0 zero) %{
 13505   match(Set mem (StoreF mem zero));
 13507   ins_cost(40);
 13508   format %{ "store   $mem, zero\t# store float @ storeF_imm0" %}
 13509   ins_encode %{
 13510     int      base = $mem$$base;
 13511     int     index = $mem$$index;
 13512     int     scale = $mem$$scale;
 13513     int      disp = $mem$$disp;
 13515     if( index != 0 ) {
 13516       if ( UseLoongsonISA ) {
 13517         if ( Assembler::is_simm(disp, 8) ) {
 13518           if ( scale == 0 ) {
 13519             __ gsswx(R0, as_Register(base), as_Register(index), disp);
 13520           } else {
 13521             __ dsll(T9, as_Register(index), scale);
 13522             __ gsswx(R0, as_Register(base), T9, disp);
 13524         } else if ( Assembler::is_simm16(disp) ) {
 13525           if ( scale == 0 ) {
 13526             __ daddu(AT, as_Register(base), as_Register(index));
 13527           } else {
 13528             __ dsll(T9, as_Register(index), scale);
 13529             __ daddu(AT, as_Register(base), T9);
 13531           __ sw(R0, AT, disp);
 13532         } else {
 13533           if ( scale == 0 ) {
 13534             __ move(T9, disp);
 13535             __ daddu(AT, as_Register(index), T9);
 13536             __ gsswx(R0, as_Register(base), AT, 0);
 13537           } else {
 13538             __ dsll(T9, as_Register(index), scale);
 13539             __ move(AT, disp);
 13540             __ daddu(AT, AT, T9);
 13541             __ gsswx(R0, as_Register(base), AT, 0);
 13544       } else { //not use loongson isa
 13545         if(scale != 0) {
 13546           __ dsll(T9, as_Register(index), scale);
 13547           __ daddu(AT, as_Register(base), T9);
 13548         } else {
 13549           __ daddu(AT, as_Register(base), as_Register(index));
 13551         if( Assembler::is_simm16(disp) ) {
 13552           __ sw(R0, AT, disp);
 13553         } else {
 13554           __ move(T9, disp);
 13555           __ daddu(AT, AT, T9);
 13556           __ sw(R0, AT, 0);
 13559     } else { //index is 0
 13560       if ( UseLoongsonISA ) {
 13561         if ( Assembler::is_simm16(disp) ) {
 13562           __ sw(R0, as_Register(base), disp);
 13563         } else {
 13564           __ move(T9, disp);
 13565           __ gsswx(R0, as_Register(base), T9, 0);
 13567       } else {
 13568         if( Assembler::is_simm16(disp) ) {
 13569           __ sw(R0, as_Register(base), disp);
 13570         } else {
 13571           __ move(T9, disp);
 13572           __ daddu(AT, as_Register(base), T9);
 13573           __ sw(R0, AT, 0);
 13577   %}
 13578   ins_pipe( ialu_storeI );
 13579 %}
 13581 // Load Double
 13582 instruct loadD(regD dst, memory mem) %{
 13583   match(Set dst (LoadD mem));
 13585   ins_cost(150);
 13586   format %{ "loadD   $dst, $mem #@loadD" %}
 13587   ins_encode(load_D_enc(dst, mem));
 13588   ins_pipe( ialu_loadI );
 13589 %}
 13591 // Load Double - UNaligned
 13592 instruct loadD_unaligned(regD dst, memory mem ) %{
 13593   match(Set dst (LoadD_unaligned mem));
 13594   ins_cost(250);
 13595   // FIXME: Need more effective ldl/ldr
 13596   format %{ "loadD_unaligned   $dst, $mem #@loadD_unaligned" %}
 13597   ins_encode(load_D_enc(dst, mem));
 13598   ins_pipe( ialu_loadI );
 13599 %}
 13601 instruct storeD_reg( memory mem, regD src) %{
 13602   match(Set mem (StoreD mem src));
 13604   ins_cost(50);
 13605   format %{ "store   $mem, $src\t# store float @ storeD_reg" %}
 13606   ins_encode(store_D_reg_enc(mem, src));
 13607   ins_pipe( fpu_storeF );
 13608 %}
 13610 instruct storeD_imm0( memory mem, immD0 zero) %{
 13611   match(Set mem (StoreD mem zero));
 13613   ins_cost(40);
 13614   format %{ "store   $mem, zero\t# store float @ storeD_imm0" %}
 13615   ins_encode %{
 13616     int      base = $mem$$base;
 13617     int     index = $mem$$index;
 13618     int     scale = $mem$$scale;
 13619     int      disp = $mem$$disp;
 13621     __ mtc1(R0, F30);
 13622     __ cvt_d_w(F30, F30);
 13624     if( index != 0 ) {
 13625     if ( UseLoongsonISA ) {
 13626       if ( Assembler::is_simm(disp, 8) ) {
 13627         if (scale == 0) {
 13628           __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
 13629         } else {
 13630           __ dsll(T9, as_Register(index), scale);
 13631           __ gssdxc1(F30, as_Register(base), T9, disp);
 13633       } else if ( Assembler::is_simm16(disp) ) {
 13634         if (scale == 0) {
 13635           __ daddu(AT, as_Register(base), as_Register(index));
 13636           __ sdc1(F30, AT, disp);
 13637         } else {
 13638           __ dsll(T9, as_Register(index), scale);
 13639           __ daddu(AT, as_Register(base), T9);
 13640           __ sdc1(F30, AT, disp);
 13642       } else {
 13643         if (scale == 0) {
 13644           __ move(T9, disp);
 13645           __ daddu(AT, as_Register(index), T9);
 13646           __ gssdxc1(F30, as_Register(base), AT, 0);
 13647         } else {
 13648           __ move(T9, disp);
 13649           __ dsll(AT, as_Register(index), scale);
 13650           __ daddu(AT, AT, T9);
 13651           __ gssdxc1(F30, as_Register(base), AT, 0);
 13654     } else { // not use loongson isa
 13655         if(scale != 0) {
 13656            __ dsll(T9, as_Register(index), scale);
 13657            __ daddu(AT, as_Register(base), T9);
 13658         } else {
 13659            __ daddu(AT, as_Register(base), as_Register(index));
 13661        if( Assembler::is_simm16(disp) ) {
 13662           __ sdc1(F30, AT, disp);
 13663        } else {
 13664           __ move(T9, disp);
 13665           __ daddu(AT, AT, T9);
 13666           __ sdc1(F30, AT, 0);
 13669     } else {// index is 0
 13670     if ( UseLoongsonISA ) {
 13671       if ( Assembler::is_simm16(disp) ) {
 13672         __ sdc1(F30, as_Register(base), disp);
 13673       } else {
 13674         __ move(T9, disp);
 13675         __ gssdxc1(F30, as_Register(base), T9, 0);
 13677     } else {
 13678        if( Assembler::is_simm16(disp) ) {
 13679           __ sdc1(F30, as_Register(base), disp);
 13680        } else {
 13681           __ move(T9, disp);
 13682           __ daddu(AT, as_Register(base), T9);
 13683           __ sdc1(F30, AT, 0);
 13687   %}
 13688   ins_pipe( ialu_storeI );
 13689 %}
 13691 instruct loadSSI(mRegI dst, stackSlotI src)
 13692 %{
 13693   match(Set dst src);
 13695   ins_cost(125);
 13696   format %{ "lw    $dst, $src\t# int stk @ loadSSI" %}
 13697   ins_encode %{
 13698     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
 13699     __ lw($dst$$Register, SP, $src$$disp);
 13700   %}
 13701   ins_pipe(ialu_loadI);
 13702 %}
 13704 instruct storeSSI(stackSlotI dst, mRegI src)
 13705 %{
 13706   match(Set dst src);
 13708   ins_cost(100);
 13709   format %{ "sw    $dst, $src\t# int stk @ storeSSI" %}
 13710   ins_encode %{
 13711     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
 13712     __ sw($src$$Register, SP, $dst$$disp);
 13713   %}
 13714   ins_pipe(ialu_storeI);
 13715 %}
 13717 instruct loadSSL(mRegL dst, stackSlotL src)
 13718 %{
 13719   match(Set dst src);
 13721   ins_cost(125);
 13722   format %{ "ld    $dst, $src\t# long stk @ loadSSL" %}
 13723   ins_encode %{
 13724     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
 13725     __ ld($dst$$Register, SP, $src$$disp);
 13726   %}
 13727   ins_pipe(ialu_loadI);
 13728 %}
 13730 instruct storeSSL(stackSlotL dst, mRegL src)
 13731 %{
 13732   match(Set dst src);
 13734   ins_cost(100);
 13735   format %{ "sd    $dst, $src\t# long stk @ storeSSL" %}
 13736   ins_encode %{
 13737     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
 13738     __ sd($src$$Register, SP, $dst$$disp);
 13739   %}
 13740   ins_pipe(ialu_storeI);
 13741 %}
 13743 instruct loadSSP(mRegP dst, stackSlotP src)
 13744 %{
 13745   match(Set dst src);
 13747   ins_cost(125);
 13748   format %{ "ld    $dst, $src\t# ptr stk @ loadSSP" %}
 13749   ins_encode %{
 13750     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
 13751     __ ld($dst$$Register, SP, $src$$disp);
 13752   %}
 13753   ins_pipe(ialu_loadI);
 13754 %}
 13756 instruct storeSSP(stackSlotP dst, mRegP src)
 13757 %{
 13758   match(Set dst src);
 13760   ins_cost(100);
 13761   format %{ "sd    $dst, $src\t# ptr stk @ storeSSP" %}
 13762   ins_encode %{
 13763     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
 13764     __ sd($src$$Register, SP, $dst$$disp);
 13765   %}
 13766   ins_pipe(ialu_storeI);
 13767 %}
 13769 instruct loadSSF(regF dst, stackSlotF src)
 13770 %{
 13771   match(Set dst src);
 13773   ins_cost(125);
 13774   format %{ "lwc1   $dst, $src\t# float stk @ loadSSF" %}
 13775   ins_encode %{
 13776     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
 13777     __ lwc1($dst$$FloatRegister, SP, $src$$disp);
 13778   %}
 13779   ins_pipe(ialu_loadI);
 13780 %}
 13782 instruct storeSSF(stackSlotF dst, regF src)
 13783 %{
 13784   match(Set dst src);
 13786   ins_cost(100);
 13787   format %{ "swc1    $dst, $src\t# float stk @ storeSSF" %}
 13788   ins_encode %{
 13789     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
 13790     __ swc1($src$$FloatRegister, SP, $dst$$disp);
 13791   %}
 13792   ins_pipe(fpu_storeF);
 13793 %}
 13795 // Use the same format since predicate() can not be used here.
 13796 instruct loadSSD(regD dst, stackSlotD src)
 13797 %{
 13798   match(Set dst src);
 13800   ins_cost(125);
 13801   format %{ "ldc1   $dst, $src\t# double stk @ loadSSD" %}
 13802   ins_encode %{
 13803     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
 13804     __ ldc1($dst$$FloatRegister, SP, $src$$disp);
 13805   %}
 13806   ins_pipe(ialu_loadI);
 13807 %}
 13809 instruct storeSSD(stackSlotD dst, regD src)
 13810 %{
 13811   match(Set dst src);
 13813   ins_cost(100);
 13814   format %{ "sdc1    $dst, $src\t# double stk @ storeSSD" %}
 13815   ins_encode %{
 13816     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
 13817     __ sdc1($src$$FloatRegister, SP, $dst$$disp);
 13818   %}
 13819   ins_pipe(fpu_storeF);
 13820 %}
 13822 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
 13823   match( Set cr (FastLock object box) );
 13824   effect( TEMP tmp, TEMP scr, USE_KILL box );
 13825   ins_cost(300);
 13826   format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
 13827   ins_encode %{
 13828     __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
 13829   %}
 13831   ins_pipe( pipe_slow );
 13832   ins_pc_relative(1);
 13833 %}
 13835 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
 13836   match( Set cr (FastUnlock object box) );
 13837   effect( TEMP tmp, USE_KILL box );
 13838   ins_cost(300);
 13839   format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
 13840   ins_encode %{
 13841     __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
 13842   %}
 13844   ins_pipe( pipe_slow );
 13845   ins_pc_relative(1);
 13846 %}
 13848 // Store CMS card-mark Immediate
 13849 instruct storeImmCM(memory mem, immI8 src) %{
 13850   match(Set mem (StoreCM mem src));
 13852   ins_cost(150);
 13853   format %{ "MOV8   $mem,$src\t! CMS card-mark imm0" %}
 13854 //  opcode(0xC6);
 13855   ins_encode(store_B_immI_enc_sync(mem, src));
 13856   ins_pipe( ialu_storeI );
 13857 %}
 13859 // Die now
 13860 instruct ShouldNotReachHere( )
 13861 %{
 13862   match(Halt);
 13863   ins_cost(300);
 13865   // Use the following format syntax
 13866   format %{ "ILLTRAP   ;#@ShouldNotReachHere" %}
 13867   ins_encode %{
 13868     // Here we should emit illtrap !
 13870     __ stop("in ShoudNotReachHere");
 13872   %}
 13873   ins_pipe( pipe_jump );
 13874 %}
 13876 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
 13877 %{
 13878   predicate(Universe::narrow_oop_shift() == 0);
 13879   match(Set dst mem);
 13881   ins_cost(110);
 13882   format %{ "leaq    $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
 13883   ins_encode %{
 13884     Register  dst  = $dst$$Register;
 13885     Register  base = as_Register($mem$$base);
 13886     int       disp = $mem$$disp;
 13888     __ daddiu(dst, base, disp);
 13889   %}
 13890   ins_pipe( ialu_regI_imm16 );
 13891 %}
 13893 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
 13894 %{
 13895   match(Set dst mem);
 13897   ins_cost(110);
 13898   format %{ "leaq    $dst, $mem\t# @ PosIdxScaleOff8" %}
 13899   ins_encode %{
 13900     Register  dst   = $dst$$Register;
 13901     Register  base  = as_Register($mem$$base);
 13902     Register  index = as_Register($mem$$index);
 13903     int       scale = $mem$$scale;
 13904     int       disp  = $mem$$disp;
 13906     if (scale == 0) {
 13907       __ daddu(AT, base, index);
 13908       __ daddiu(dst, AT, disp);
 13909     } else {
 13910       __ dsll(AT, index, scale);
 13911       __ daddu(AT, base, AT);
 13912       __ daddiu(dst, AT, disp);
 13914  %}
 13916   ins_pipe( ialu_regI_imm16 );
 13917 %}
 13919 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
 13920 %{
 13921   match(Set dst mem);
 13923   ins_cost(110);
 13924   format %{ "leaq    $dst, $mem\t# @ leaPIdxScale" %}
 13925   ins_encode %{
 13926     Register  dst   = $dst$$Register;
 13927     Register  base  = as_Register($mem$$base);
 13928     Register  index = as_Register($mem$$index);
 13929     int       scale = $mem$$scale;
 13931     if (scale == 0) {
 13932        __ daddu(dst, base, index);
 13933     } else {
 13934        __ dsll(AT, index, scale);
 13935        __ daddu(dst, base, AT);
 13937  %}
 13939   ins_pipe( ialu_regI_imm16 );
 13940 %}
 13943 // ============================================================================
 13944 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 13945 // array for an instance of the superklass.  Set a hidden internal cache on a
 13946 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 13947 // NZ for a miss or zero for a hit.  The encoding ALSO sets flags.
 13948 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
 13949   match(Set result (PartialSubtypeCheck sub super));
 13950   effect(KILL tmp);
 13951   ins_cost(1100);  // slightly larger than the next version
 13952   format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
 13954   ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
 13955   ins_pipe( pipe_slow );
 13956 %}
 13959 // Conditional-store of an int value.
 13960 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
 13961 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
 13962   match(Set cr (StoreIConditional mem (Binary oldval newval)));
 13963 //  effect(KILL oldval);
 13964   format %{ "CMPXCHG  $newval, $mem, $oldval \t# @storeIConditional" %}
 13966   ins_encode %{
 13967     Register oldval = $oldval$$Register;
 13968     Register newval = $newval$$Register;
 13969     Address  addr(as_Register($mem$$base), $mem$$disp);
 13970     Label    again, failure;
 13972     int     index = $mem$$index;
 13973     int     scale = $mem$$scale;
 13974     int      disp = $mem$$disp;
 13976     guarantee(Assembler::is_simm16(disp), "");
 13978     if( index != 0 ) {
 13979       __ stop("in storeIConditional: index != 0");
 13980     } else {
 13981       __ bind(again);
 13982       if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
 13983       __ ll(AT, addr);
 13984       __ bne(AT, oldval, failure);
 13985       __ delayed()->addu(AT, R0, R0);
 13987       __ addu(AT, newval, R0);
 13988       __ sc(AT, addr);
 13989       __ beq(AT, R0, again);
 13990       __ delayed()->addiu(AT, R0, 0xFF);
 13991       __ bind(failure);
 13992       __ sync();
 13994 %}
 13996   ins_pipe( long_memory_op );
 13997 %}
 13999 // Conditional-store of a long value.
 14000 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
 14001 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
 14002 %{
 14003   match(Set cr (StoreLConditional mem (Binary oldval newval)));
 14004   effect(KILL oldval);
 14006   format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
 14007   ins_encode%{
 14008     Register oldval = $oldval$$Register;
 14009     Register newval = $newval$$Register;
 14010     Address addr((Register)$mem$$base, $mem$$disp);
 14012     int     index = $mem$$index;
 14013     int     scale = $mem$$scale;
 14014     int      disp = $mem$$disp;
 14016     guarantee(Assembler::is_simm16(disp), "");
 14018     if( index != 0 ) {
 14019       __ stop("in storeIConditional: index != 0");
 14020     } else {
 14021       __ cmpxchg(newval, addr, oldval);
 14023   %}
 14024   ins_pipe( long_memory_op );
 14025 %}
 14028 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
 14029   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
 14030   effect(KILL oldval);
 14031 //  match(CompareAndSwapI mem_ptr (Binary oldval newval));
 14032   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
 14033             "MOV    $res, 1 @ compareAndSwapI\n\t"
 14034             "BNE    AT, R0 @ compareAndSwapI\n\t"
 14035             "MOV    $res, 0 @ compareAndSwapI\n"
 14036           "L:" %}
 14037   ins_encode %{
 14038     Register newval = $newval$$Register;
 14039     Register oldval = $oldval$$Register;
 14040     Register res    = $res$$Register;
 14041     Address  addr($mem_ptr$$Register, 0);
 14042     Label L;
 14044     __ cmpxchg32(newval, addr, oldval);
 14045     __ move(res, AT);
 14046   %}
 14047   ins_pipe( long_memory_op );
 14048 %}
 14050 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
 14051   predicate(VM_Version::supports_cx8());
 14052   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
 14053   effect(KILL oldval);
 14054   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
 14055             "MOV    $res, 1 @ compareAndSwapI\n\t"
 14056             "BNE    AT, R0 @ compareAndSwapI\n\t"
 14057             "MOV    $res, 0 @ compareAndSwapI\n"
 14058           "L:" %}
 14059   ins_encode %{
 14060     Register newval = $newval$$Register;
 14061     Register oldval = $oldval$$Register;
 14062     Register res    = $res$$Register;
 14063     Address  addr($mem_ptr$$Register, 0);
 14064     Label L;
 14066     __ cmpxchg(newval, addr, oldval);
 14067     __ move(res, AT);
 14068   %}
 14069   ins_pipe( long_memory_op );
 14070 %}
 14072 //FIXME:
 14073 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
 14074   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
 14075   effect(KILL oldval);
 14076   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
 14077             "MOV    $res, AT @ compareAndSwapP\n\t"
 14078           "L:" %}
 14079   ins_encode %{
 14080     Register newval = $newval$$Register;
 14081     Register oldval = $oldval$$Register;
 14082     Register res    = $res$$Register;
 14083     Address  addr($mem_ptr$$Register, 0);
 14084     Label L;
 14086     __ cmpxchg(newval, addr, oldval);
 14087     __ move(res, AT);
 14088   %}
 14089   ins_pipe( long_memory_op );
 14090 %}
 14092 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
 14093   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
 14094   effect(KILL oldval);
 14095   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
 14096             "MOV    $res, AT @ compareAndSwapN\n\t"
 14097           "L:" %}
 14098   ins_encode %{
 14099     Register newval = $newval$$Register;
 14100     Register oldval = $oldval$$Register;
 14101     Register res    = $res$$Register;
 14102     Address  addr($mem_ptr$$Register, 0);
 14103     Label L;
 14105     // cmpxchg32 is implemented with ll/sc, which will do sign extension.
 14106     //      Thus, we should extend oldval's sign for correct comparision.
 14107     //
 14108     __ sll(oldval, oldval, 0);
 14110     __ cmpxchg32(newval, addr, oldval);
 14111     __ move(res, AT);
 14112   %}
 14113   ins_pipe( long_memory_op );
 14114 %}
 14116 //----------Max and Min--------------------------------------------------------
 14117 // Min Instructions
 14118 ////
 14119 //   *** Min and Max using the conditional move are slower than the
 14120 //   *** branch version on a Pentium III.
 14121 // // Conditional move for min
 14122 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 14123 //  effect( USE_DEF op2, USE op1, USE cr );
 14124 //  format %{ "CMOVlt $op2,$op1\t! min" %}
 14125 //  opcode(0x4C,0x0F);
 14126 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 14127 //  ins_pipe( pipe_cmov_reg );
 14128 //%}
 14129 //
 14130 //// Min Register with Register (P6 version)
 14131 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
 14132 //  predicate(VM_Version::supports_cmov() );
 14133 //  match(Set op2 (MinI op1 op2));
 14134 //  ins_cost(200);
 14135 //  expand %{
 14136 //    eFlagsReg cr;
 14137 //    compI_eReg(cr,op1,op2);
 14138 //    cmovI_reg_lt(op2,op1,cr);
 14139 //  %}
 14140 //%}
 14142 // Min Register with Register (generic version)
 14143 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
 14144   match(Set dst (MinI dst src));
 14145   //effect(KILL flags);
 14146   ins_cost(80);
 14148   format %{ "MIN    $dst, $src @minI_Reg_Reg" %}
 14149   ins_encode %{
 14150     Register dst   = $dst$$Register;
 14151     Register src   = $src$$Register;
 14153     __ slt(AT, src, dst);
 14154     __ movn(dst, src, AT);
 14156   %}
 14158   ins_pipe( pipe_slow );
 14159 %}
 14161 // Max Register with Register
 14162 //   *** Min and Max using the conditional move are slower than the
 14163 //   *** branch version on a Pentium III.
 14164 // // Conditional move for max
 14165 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 14166 //  effect( USE_DEF op2, USE op1, USE cr );
 14167 //  format %{ "CMOVgt $op2,$op1\t! max" %}
 14168 //  opcode(0x4F,0x0F);
 14169 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 14170 //  ins_pipe( pipe_cmov_reg );
 14171 //%}
 14172 //
 14173 // // Max Register with Register (P6 version)
 14174 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
 14175 //  predicate(VM_Version::supports_cmov() );
 14176 //  match(Set op2 (MaxI op1 op2));
 14177 //  ins_cost(200);
 14178 //  expand %{
 14179 //    eFlagsReg cr;
 14180 //    compI_eReg(cr,op1,op2);
 14181 //    cmovI_reg_gt(op2,op1,cr);
 14182 //  %}
 14183 //%}
 14185 // Max Register with Register (generic version)
 14186 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
 14187   match(Set dst (MaxI dst src));
 14188   ins_cost(80);
 14190   format %{ "MAX    $dst, $src @maxI_Reg_Reg" %}
 14192   ins_encode %{
 14193     Register dst   = $dst$$Register;
 14194     Register src   = $src$$Register;
 14196     __ slt(AT, dst, src);
 14197     __ movn(dst, src, AT);
 14199   %}
 14201   ins_pipe( pipe_slow );
 14202 %}
 14204 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
 14205   match(Set dst (MaxI dst zero));
 14206   ins_cost(50);
 14208   format %{ "MAX    $dst, 0 @maxI_Reg_zero" %}
 14210   ins_encode %{
 14211     Register dst   = $dst$$Register;
 14213     __ slt(AT, dst, R0);
 14214     __ movn(dst, R0, AT);
 14216   %}
 14218   ins_pipe( pipe_slow );
 14219 %}
 14221 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
 14222 %{
 14223   match(Set dst (AndL src mask));
 14225   format %{ "movl    $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
 14226   ins_encode %{
 14227     Register dst = $dst$$Register;
 14228     Register src = $src$$Register;
 14230     __ dext(dst, src, 0, 32);
 14231   %}
 14232   ins_pipe(ialu_regI_regI);
 14233 %}
 14235 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
 14236 %{
 14237   match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
 14239   format %{ "combine_i2l    $dst, $src2(H), $src1(L) @ combine_i2l" %}
 14240   ins_encode %{
 14241     Register dst  = $dst$$Register;
 14242     Register src1 = $src1$$Register;
 14243     Register src2 = $src2$$Register;
 14245     if (src1 == dst) {
 14246        __ dinsu(dst, src2, 32, 32);
 14247     } else if (src2 == dst) {
 14248        __ dsll32(dst, dst, 0);
 14249        __ dins(dst, src1, 0, 32);
 14250     } else {
 14251        __ dext(dst, src1, 0, 32);
 14252        __ dinsu(dst, src2, 32, 32);
 14254   %}
 14255   ins_pipe(ialu_regI_regI);
 14256 %}
 14258 // Zero-extend convert int to long
 14259 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
 14260 %{
 14261   match(Set dst (AndL (ConvI2L src) mask));
 14263   format %{ "movl    $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
 14264   ins_encode %{
 14265     Register dst = $dst$$Register;
 14266     Register src = $src$$Register;
 14268     __ dext(dst, src, 0, 32);
 14269   %}
 14270   ins_pipe(ialu_regI_regI);
 14271 %}
 14273 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
 14274 %{
 14275   match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
 14277   format %{ "movl    $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
 14278   ins_encode %{
 14279     Register dst = $dst$$Register;
 14280     Register src = $src$$Register;
 14282     __ dext(dst, src, 0, 32);
 14283   %}
 14284   ins_pipe(ialu_regI_regI);
 14285 %}
 14287 // Match loading integer and casting it to unsigned int in long register.
 14288 // LoadI + ConvI2L + AndL 0xffffffff.
 14289 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
 14290   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 14292   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
 14293   ins_encode (load_N_enc(dst, mem));
 14294   ins_pipe(ialu_loadI);
 14295 %}
 14297 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
 14298   match(Set dst (AndL mask (ConvI2L (LoadI mem))));
 14300   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
 14301   ins_encode (load_N_enc(dst, mem));
 14302   ins_pipe(ialu_loadI);
 14303 %}
 14306 // ============================================================================
 14307 // Safepoint Instruction
 14308 instruct safePoint_poll_reg(mRegP poll) %{
 14309   match(SafePoint poll);
 14310   predicate(false);
 14311   effect(USE poll);
 14313   ins_cost(125);
 14314   format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
 14316   ins_encode %{
 14317     Register poll_reg = $poll$$Register;
 14319     __ block_comment("Safepoint:");
 14320     __ relocate(relocInfo::poll_type);
 14321     __ lw(AT, poll_reg, 0);
 14322   %}
 14324   ins_pipe( ialu_storeI );
 14325 %}
 14327 instruct safePoint_poll() %{
 14328   match(SafePoint);
 14330   ins_cost(105);
 14331   format %{ "poll for GC @ safePoint_poll" %}
 14333   ins_encode %{
 14334     __ block_comment("Safepoint:");
 14335     __ set64(T9, (long)os::get_polling_page());
 14336     __ relocate(relocInfo::poll_type);
 14337     __ lw(AT, T9, 0);
 14338   %}
 14340   ins_pipe( ialu_storeI );
 14341 %}
 14343 //----------Arithmetic Conversion Instructions---------------------------------
 14345 instruct roundFloat_nop(regF dst)
 14346 %{
 14347   match(Set dst (RoundFloat dst));
 14349   ins_cost(0);
 14350   ins_encode();
 14351   ins_pipe(empty);
 14352 %}
 14354 instruct roundDouble_nop(regD dst)
 14355 %{
 14356   match(Set dst (RoundDouble dst));
 14358   ins_cost(0);
 14359   ins_encode();
 14360   ins_pipe(empty);
 14361 %}
 14363 //---------- Zeros Count Instructions ------------------------------------------
 14364 // CountLeadingZerosINode CountTrailingZerosINode
 14365 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
 14366   predicate(UseCountLeadingZerosInstructionMIPS64);
 14367   match(Set dst (CountLeadingZerosI src));
 14369   format %{ "clz  $dst, $src\t# count leading zeros (int)" %}
 14370   ins_encode %{
 14371     __ clz($dst$$Register, $src$$Register);
 14372   %}
 14373   ins_pipe( ialu_regL_regL );
 14374 %}
 14376 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
 14377   predicate(UseCountLeadingZerosInstructionMIPS64);
 14378   match(Set dst (CountLeadingZerosL src));
 14380   format %{ "dclz  $dst, $src\t# count leading zeros (long)" %}
 14381   ins_encode %{
 14382     __ dclz($dst$$Register, $src$$Register);
 14383   %}
 14384   ins_pipe( ialu_regL_regL );
 14385 %}
 14387 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
 14388   predicate(UseCountTrailingZerosInstructionMIPS64);
 14389   match(Set dst (CountTrailingZerosI src));
 14391   format %{ "ctz    $dst, $src\t# count trailing zeros (int)" %}
 14392   ins_encode %{
 14393     // ctz and dctz is gs instructions.
 14394     __ ctz($dst$$Register, $src$$Register);
 14395   %}
 14396   ins_pipe( ialu_regL_regL );
 14397 %}
 14399 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
 14400   predicate(UseCountTrailingZerosInstructionMIPS64);
 14401   match(Set dst (CountTrailingZerosL src));
 14403   format %{ "dcto    $dst, $src\t# count trailing zeros (long)" %}
 14404   ins_encode %{
 14405     __ dctz($dst$$Register, $src$$Register);
 14406   %}
 14407   ins_pipe( ialu_regL_regL );
 14408 %}
 14410 // ====================VECTOR INSTRUCTIONS=====================================
 14412 // Load vectors (8 bytes long)
 14413 instruct loadV8(vecD dst, memory mem) %{
 14414   predicate(n->as_LoadVector()->memory_size() == 8);
 14415   match(Set dst (LoadVector mem));
 14416   ins_cost(125);
 14417   format %{ "load    $dst, $mem\t! load vector (8 bytes)" %}
 14418   ins_encode(load_D_enc(dst, mem));
 14419   ins_pipe( fpu_loadF );
 14420 %}
 14422 // Store vectors (8 bytes long)
 14423 instruct storeV8(memory mem, vecD src) %{
 14424   predicate(n->as_StoreVector()->memory_size() == 8);
 14425   match(Set mem (StoreVector mem src));
 14426   ins_cost(145);
 14427   format %{ "store    $mem, $src\t! store vector (8 bytes)" %}
 14428   ins_encode(store_D_reg_enc(mem, src));
 14429   ins_pipe( fpu_storeF );
 14430 %}
 14432 instruct Repl8B_DSP(vecD dst, mRegI src) %{
 14433   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 14434   match(Set dst (ReplicateB src));
 14435   ins_cost(100);
 14436   format %{ "replv_ob    AT, $src\n\t"
 14437             "dmtc1 AT, $dst\t! replicate8B" %}
 14438   ins_encode %{
 14439     __ replv_ob(AT, $src$$Register);
 14440     __ dmtc1(AT, $dst$$FloatRegister);
 14441   %}
 14442   ins_pipe( pipe_mtc1 );
 14443 %}
 14445 instruct Repl8B(vecD dst, mRegI src) %{
 14446   predicate(n->as_Vector()->length() == 8);
 14447   match(Set dst (ReplicateB src));
 14448   ins_cost(140);
 14449   format %{ "move       AT,  $src\n\t"
 14450             "dins  AT, AT,  8,  8\n\t"
 14451             "dins  AT, AT, 16, 16\n\t"
 14452             "dinsu AT, AT, 32, 32\n\t"
 14453             "dmtc1 AT, $dst\t! replicate8B" %}
 14454   ins_encode %{
 14455     __ move(AT, $src$$Register);
 14456     __ dins(AT, AT, 8, 8);
 14457     __ dins(AT, AT, 16, 16);
 14458     __ dinsu(AT, AT, 32, 32);
 14459     __ dmtc1(AT, $dst$$FloatRegister);
 14460   %}
 14461   ins_pipe( pipe_mtc1 );
 14462 %}
 14464 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
 14465   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 14466   match(Set dst (ReplicateB con));
 14467   ins_cost(110);
 14468   format %{ "repl_ob    AT, [$con]\n\t"
 14469             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 14470   ins_encode %{
 14471     int      val = $con$$constant;
 14472     __ repl_ob(AT, val);
 14473     __ dmtc1(AT, $dst$$FloatRegister);
 14474   %}
 14475   ins_pipe( pipe_mtc1 );
 14476 %}
 14478 instruct Repl8B_imm(vecD dst, immI con) %{
 14479   predicate(n->as_Vector()->length() == 8);
 14480   match(Set dst (ReplicateB con));
 14481   ins_cost(150);
 14482   format %{ "move      AT, [$con]\n\t"
 14483             "dins  AT, AT,  8,  8\n\t"
 14484             "dins  AT, AT, 16, 16\n\t"
 14485             "dinsu AT, AT, 32, 32\n\t"
 14486             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 14487   ins_encode %{
 14488     __ move(AT, $con$$constant);
 14489     __ dins(AT, AT, 8, 8);
 14490     __ dins(AT, AT, 16, 16);
 14491     __ dinsu(AT, AT, 32, 32);
 14492     __ dmtc1(AT, $dst$$FloatRegister);
 14493   %}
 14494   ins_pipe( pipe_mtc1 );
 14495 %}
 14497 instruct Repl8B_zero(vecD dst, immI0 zero) %{
 14498   predicate(n->as_Vector()->length() == 8);
 14499   match(Set dst (ReplicateB zero));
 14500   ins_cost(90);
 14501   format %{ "dmtc1    R0, $dst\t! replicate8B zero" %}
 14502   ins_encode %{
 14503     __ dmtc1(R0, $dst$$FloatRegister);
 14504   %}
 14505   ins_pipe( pipe_mtc1 );
 14506 %}
 14508 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
 14509   predicate(n->as_Vector()->length() == 8);
 14510   match(Set dst (ReplicateB M1));
 14511   ins_cost(80);
 14512   format %{ "dmtc1    -1, $dst\t! replicate8B -1" %}
 14513   ins_encode %{
 14514     __ nor(AT, R0, R0);
 14515     __ dmtc1(AT, $dst$$FloatRegister);
 14516   %}
 14517   ins_pipe( pipe_mtc1 );
 14518 %}
 14520 instruct Repl4S_DSP(vecD dst, mRegI src) %{
 14521   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 14522   match(Set dst (ReplicateS src));
 14523   ins_cost(100);
 14524   format %{ "replv_qh    AT, $src\n\t"
 14525             "dmtc1 AT, $dst\t! replicate4S" %}
 14526   ins_encode %{
 14527     __ replv_qh(AT, $src$$Register);
 14528     __ dmtc1(AT, $dst$$FloatRegister);
 14529   %}
 14530   ins_pipe( pipe_mtc1 );
 14531 %}
 14533 instruct Repl4S(vecD dst, mRegI src) %{
 14534   predicate(n->as_Vector()->length() == 4);
 14535   match(Set dst (ReplicateS src));
 14536   ins_cost(120);
 14537   format %{ "move    AT,     $src  \n\t"
 14538             "dins    AT, AT, 16, 16\n\t"
 14539             "dinsu   AT, AT, 32, 32\n\t"
 14540             "dmtc1 AT, $dst\t! replicate4S" %}
 14541   ins_encode %{
 14542     __ move(AT, $src$$Register);
 14543     __ dins(AT, AT, 16, 16);
 14544     __ dinsu(AT, AT, 32, 32);
 14545     __ dmtc1(AT, $dst$$FloatRegister);
 14546   %}
 14547   ins_pipe( pipe_mtc1 );
 14548 %}
 14550 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
 14551   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 14552   match(Set dst (ReplicateS con));
 14553   ins_cost(100);
 14554   format %{ "repl_qh    AT, [$con]\n\t"
 14555             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 14556   ins_encode %{
 14557     int      val = $con$$constant;
 14558     if ( Assembler::is_simm(val, 10)) {
 14559       //repl_qh supports 10 bits immediate
 14560       __ repl_qh(AT, val);
 14561     } else {
 14562       __ li32(AT, val);
 14563       __ replv_qh(AT, AT);
 14565     __ dmtc1(AT, $dst$$FloatRegister);
 14566   %}
 14567   ins_pipe( pipe_mtc1 );
 14568 %}
 14570 instruct Repl4S_imm(vecD dst, immI con) %{
 14571   predicate(n->as_Vector()->length() == 4);
 14572   match(Set dst (ReplicateS con));
 14573   ins_cost(110);
 14574   format %{ "move    AT,   [$con]\n\t"
 14575             "dins  AT, AT, 16, 16\n\t"
 14576             "dinsu AT, AT, 32, 32\n\t"
 14577             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 14578   ins_encode %{
 14579     __ move(AT, $con$$constant);
 14580     __ dins(AT, AT, 16, 16);
 14581     __ dinsu(AT, AT, 32, 32);
 14582     __ dmtc1(AT, $dst$$FloatRegister);
 14583   %}
 14584   ins_pipe( pipe_mtc1 );
 14585 %}
 14587 instruct Repl4S_zero(vecD dst, immI0 zero) %{
 14588   predicate(n->as_Vector()->length() == 4);
 14589   match(Set dst (ReplicateS zero));
 14590   format %{ "dmtc1    R0, $dst\t! replicate4S zero" %}
 14591   ins_encode %{
 14592     __ dmtc1(R0, $dst$$FloatRegister);
 14593   %}
 14594   ins_pipe( pipe_mtc1 );
 14595 %}
 14597 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
 14598   predicate(n->as_Vector()->length() == 4);
 14599   match(Set dst (ReplicateS M1));
 14600   format %{ "dmtc1    -1, $dst\t! replicate4S -1" %}
 14601   ins_encode %{
 14602     __ nor(AT, R0, R0);
 14603     __ dmtc1(AT, $dst$$FloatRegister);
 14604   %}
 14605   ins_pipe( pipe_mtc1 );
 14606 %}
 14608 // Replicate integer (4 byte) scalar to be vector
 14609 instruct Repl2I(vecD dst, mRegI src) %{
 14610   predicate(n->as_Vector()->length() == 2);
 14611   match(Set dst (ReplicateI src));
 14612   format %{ "dins    AT, $src, 0, 32\n\t"
 14613             "dinsu   AT, $src, 32, 32\n\t"
 14614             "dmtc1   AT, $dst\t! replicate2I" %}
 14615   ins_encode %{
 14616     __ dins(AT, $src$$Register, 0, 32);
 14617     __ dinsu(AT, $src$$Register, 32, 32);
 14618     __ dmtc1(AT, $dst$$FloatRegister);
 14619   %}
 14620   ins_pipe( pipe_mtc1 );
 14621 %}
 14623 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
 14624 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
 14625   predicate(n->as_Vector()->length() == 2);
 14626   match(Set dst (ReplicateI con));
 14627   effect(KILL tmp);
 14628   format %{ "li32    AT, [$con], 32\n\t"
 14629             "dinsu   AT,         AT\n\t"
 14630             "dmtc1   AT, $dst\t! replicate2I($con)" %}
 14631   ins_encode %{
 14632     int      val = $con$$constant;
 14633     __ li32(AT, val);
 14634     __ dinsu(AT, AT, 32, 32);
 14635     __ dmtc1(AT, $dst$$FloatRegister);
 14636   %}
 14637   ins_pipe( pipe_mtc1 );
 14638 %}
 14640 // Replicate integer (4 byte) scalar zero to be vector
 14641 instruct Repl2I_zero(vecD dst, immI0 zero) %{
 14642   predicate(n->as_Vector()->length() == 2);
 14643   match(Set dst (ReplicateI zero));
 14644   format %{ "dmtc1    R0, $dst\t! replicate2I zero" %}
 14645   ins_encode %{
 14646     __ dmtc1(R0, $dst$$FloatRegister);
 14647   %}
 14648   ins_pipe( pipe_mtc1 );
 14649 %}
 14651 // Replicate integer (4 byte) scalar -1 to be vector
 14652 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
 14653   predicate(n->as_Vector()->length() == 2);
 14654   match(Set dst (ReplicateI M1));
 14655   format %{ "dmtc1    -1, $dst\t! replicate2I -1, use AT" %}
 14656   ins_encode %{
 14657     __ nor(AT, R0, R0);
 14658     __ dmtc1(AT, $dst$$FloatRegister);
 14659   %}
 14660   ins_pipe( pipe_mtc1 );
 14661 %}
 14663 // Replicate float (4 byte) scalar to be vector
 14664 instruct Repl2F(vecD dst, regF src) %{
 14665   predicate(n->as_Vector()->length() == 2);
 14666   match(Set dst (ReplicateF src));
 14667   format %{ "cvt.ps  $dst, $src, $src\t! replicate2F" %}
 14668   ins_encode %{
 14669     __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
 14670   %}
 14671   ins_pipe( pipe_slow );
 14672 %}
 14674 // Replicate float (4 byte) scalar zero to be vector
 14675 instruct Repl2F_zero(vecD dst, immF0 zero) %{
 14676   predicate(n->as_Vector()->length() == 2);
 14677   match(Set dst (ReplicateF zero));
 14678   format %{ "dmtc1   R0, $dst\t! replicate2F zero" %}
 14679   ins_encode %{
 14680     __ dmtc1(R0, $dst$$FloatRegister);
 14681   %}
 14682   ins_pipe( pipe_mtc1 );
 14683 %}
 14686 // ====================VECTOR ARITHMETIC=======================================
 14688 // --------------------------------- ADD --------------------------------------
 14690 // Floats vector add
 14691 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
 14692 instruct vadd2F(vecD dst, vecD src) %{
 14693   predicate(n->as_Vector()->length() == 2);
 14694   match(Set dst (AddVF dst src));
 14695   format %{ "add.ps   $dst,$src\t! add packed2F" %}
 14696   ins_encode %{
 14697     __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14698   %}
 14699   ins_pipe( pipe_slow );
 14700 %}
 14702 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
 14703   predicate(n->as_Vector()->length() == 2);
 14704   match(Set dst (AddVF src1 src2));
 14705   format %{ "add.ps   $dst,$src1,$src2\t! add packed2F" %}
 14706   ins_encode %{
 14707     __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14708   %}
 14709   ins_pipe( fpu_regF_regF );
 14710 %}
 14712 // --------------------------------- SUB --------------------------------------
 14714 // Floats vector sub
 14715 instruct vsub2F(vecD dst, vecD src) %{
 14716   predicate(n->as_Vector()->length() == 2);
 14717   match(Set dst (SubVF dst src));
 14718   format %{ "sub.ps   $dst,$src\t! sub packed2F" %}
 14719   ins_encode %{
 14720     __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14721   %}
 14722   ins_pipe( fpu_regF_regF );
 14723 %}
 14725 // --------------------------------- MUL --------------------------------------
 14727 // Floats vector mul
 14728 instruct vmul2F(vecD dst, vecD src) %{
 14729   predicate(n->as_Vector()->length() == 2);
 14730   match(Set dst (MulVF dst src));
 14731   format %{ "mul.ps   $dst, $src\t! mul packed2F" %}
 14732   ins_encode %{
 14733     __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 14734   %}
 14735   ins_pipe( fpu_regF_regF );
 14736 %}
 14738 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
 14739   predicate(n->as_Vector()->length() == 2);
 14740   match(Set dst (MulVF src1 src2));
 14741   format %{ "mul.ps   $dst, $src1, $src2\t! mul packed2F" %}
 14742   ins_encode %{
 14743     __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14744   %}
 14745   ins_pipe( fpu_regF_regF );
 14746 %}
 14748 // --------------------------------- DIV --------------------------------------
 14749 // MIPS do not have div.ps
 14751 // --------------------------------- MADD --------------------------------------
 14752 // Floats vector madd
 14753 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
 14754 //  predicate(n->as_Vector()->length() == 2);
 14755 //  match(Set dst (AddVF (MulVF src1 src2) src3));
 14756 //  ins_cost(50);
 14757 //  format %{ "madd.ps   $dst, $src3, $src1, $src2\t! madd packed2F" %}
 14758 //  ins_encode %{
 14759 //    __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 14760 //  %}
 14761 //  ins_pipe( fpu_regF_regF );
 14762 //%}
 14765 //----------PEEPHOLE RULES-----------------------------------------------------
 14766 // These must follow all instruction definitions as they use the names
 14767 // defined in the instructions definitions.
 14768 //
 14769 // peepmatch ( root_instr_name [preceeding_instruction]* );
 14770 //
 14771 // peepconstraint %{
 14772 // (instruction_number.operand_name relational_op instruction_number.operand_name
 14773 //  [, ...] );
 14774 // // instruction numbers are zero-based using left to right order in peepmatch
 14775 //
 14776 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
 14777 // // provide an instruction_number.operand_name for each operand that appears
 14778 // // in the replacement instruction's match rule
 14779 //
 14780 // ---------VM FLAGS---------------------------------------------------------
 14781 //
 14782 // All peephole optimizations can be turned off using -XX:-OptoPeephole
 14783 //
 14784 // Each peephole rule is given an identifying number starting with zero and
 14785 // increasing by one in the order seen by the parser.  An individual peephole
 14786 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
 14787 // on the command-line.
 14788 //
 14789 // ---------CURRENT LIMITATIONS----------------------------------------------
 14790 //
 14791 // Only match adjacent instructions in same basic block
 14792 // Only equality constraints
 14793 // Only constraints between operands, not (0.dest_reg == EAX_enc)
 14794 // Only one replacement instruction
 14795 //
 14796 // ---------EXAMPLE----------------------------------------------------------
 14797 //
 14798 // // pertinent parts of existing instructions in architecture description
 14799 // instruct movI(eRegI dst, eRegI src) %{
 14800 //   match(Set dst (CopyI src));
 14801 // %}
 14802 //
 14803 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
 14804 //   match(Set dst (AddI dst src));
 14805 //   effect(KILL cr);
 14806 // %}
 14807 //
 14808 // // Change (inc mov) to lea
 14809 // peephole %{
 14810 //   // increment preceeded by register-register move
 14811 //   peepmatch ( incI_eReg movI );
 14812 //   // require that the destination register of the increment
 14813 //   // match the destination register of the move
 14814 //   peepconstraint ( 0.dst == 1.dst );
 14815 //   // construct a replacement instruction that sets
 14816 //   // the destination to ( move's source register + one )
 14817 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14818 // %}
 14819 //
 14820 // Implementation no longer uses movX instructions since
 14821 // machine-independent system no longer uses CopyX nodes.
 14822 //
 14823 // peephole %{
 14824 //   peepmatch ( incI_eReg movI );
 14825 //   peepconstraint ( 0.dst == 1.dst );
 14826 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14827 // %}
 14828 //
 14829 // peephole %{
 14830 //   peepmatch ( decI_eReg movI );
 14831 //   peepconstraint ( 0.dst == 1.dst );
 14832 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14833 // %}
 14834 //
 14835 // peephole %{
 14836 //   peepmatch ( addI_eReg_imm movI );
 14837 //   peepconstraint ( 0.dst == 1.dst );
 14838 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 14839 // %}
 14840 //
 14841 // peephole %{
 14842 //   peepmatch ( addP_eReg_imm movP );
 14843 //   peepconstraint ( 0.dst == 1.dst );
 14844 //   peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
 14845 // %}
 14847 // // Change load of spilled value to only a spill
 14848 // instruct storeI(memory mem, eRegI src) %{
 14849 //   match(Set mem (StoreI mem src));
 14850 // %}
 14851 //
 14852 // instruct loadI(eRegI dst, memory mem) %{
 14853 //   match(Set dst (LoadI mem));
 14854 // %}
 14855 //
 14856 //peephole %{
 14857 //  peepmatch ( loadI storeI );
 14858 //  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
 14859 //  peepreplace ( storeI( 1.mem 1.mem 1.src ) );
 14860 //%}
 14862 //----------SMARTSPILL RULES---------------------------------------------------
 14863 // These must follow all instruction definitions as they use the names
 14864 // defined in the instructions definitions.

mercurial