src/cpu/mips/vm/mips_64.ad

Wed, 07 Feb 2018 15:44:45 +0800

author
fujie
date
Wed, 07 Feb 2018 15:44:45 +0800
changeset 8022
a9cf1a1da2b9
parent 8020
ed0d6e1dbcb2
child 8023
8aa7175e677c
permissions
-rw-r--r--

Follows 5e952d5ef68a, the cost of sync is high.

     1 //
     2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     3 // Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
     4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5 //
     6 // This code is free software; you can redistribute it and/or modify it
     7 // under the terms of the GNU General Public License version 2 only, as
     8 // published by the Free Software Foundation.
     9 //
    10 // This code is distributed in the hope that it will be useful, but WITHOUT
    11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13 // version 2 for more details (a copy is included in the LICENSE file that
    14 // accompanied this code).
    15 //
    16 // You should have received a copy of the GNU General Public License version
    17 // 2 along with this work; if not, write to the Free Software Foundation,
    18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19 //
    20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21 // or visit www.oracle.com if you need additional information or have any
    22 // questions.
    23 //
    24 //
    26 // GodSon3 Architecture Description File
    28 //----------REGISTER DEFINITION BLOCK------------------------------------------
    29 // This information is used by the matcher and the register allocator to
    30 // describe individual registers and classes of registers within the target
    31 // archtecture.
    33 // format:
    34 // reg_def name (call convention, c-call convention, ideal type, encoding);
    35 //     call convention :
    36 //      NS  = No-Save
    37 //      SOC = Save-On-Call
    38 //      SOE = Save-On-Entry
    39 //      AS  = Always-Save
    40 //    ideal type :
    41 //      see opto/opcodes.hpp for more info
    42 // reg_class name (reg, ...);
    43 // alloc_class name (reg, ...);
    44 register %{
    46 // General Registers
    47 // Integer Registers
    48   reg_def R0      ( NS,  NS,   Op_RegI,  0, VMRegImpl::Bad());
    49   reg_def AT    ( NS,  NS,   Op_RegI,  1, AT->as_VMReg());
    50   reg_def AT_H    ( NS,  NS,  Op_RegI,  1, AT->as_VMReg()->next());
    51   reg_def V0    (SOC, SOC,  Op_RegI,  2, V0->as_VMReg());
    52   reg_def V0_H  (SOC, SOC,  Op_RegI,  2, V0->as_VMReg()->next());
    53   reg_def V1    (SOC, SOC,  Op_RegI,  3, V1->as_VMReg());
    54   reg_def V1_H  (SOC, SOC,  Op_RegI,  3, V1->as_VMReg()->next());
    55   reg_def A0    (SOC, SOC,  Op_RegI,  4, A0->as_VMReg());
    56   reg_def A0_H  (SOC, SOC,  Op_RegI,  4, A0->as_VMReg()->next());
    57   reg_def A1    (SOC, SOC,  Op_RegI,  5, A1->as_VMReg());
    58   reg_def A1_H  (SOC, SOC,  Op_RegI,  5, A1->as_VMReg()->next());
    59   reg_def A2    (SOC, SOC,  Op_RegI,  6, A2->as_VMReg());
    60   reg_def A2_H  (SOC, SOC,  Op_RegI,  6, A2->as_VMReg()->next());
    61   reg_def A3    (SOC, SOC,  Op_RegI,  7, A3->as_VMReg());
    62   reg_def A3_H  (SOC, SOC,  Op_RegI,  7, A3->as_VMReg()->next());
    63   reg_def A4    (SOC, SOC,  Op_RegI,  8, A4->as_VMReg());
    64   reg_def A4_H  (SOC, SOC,  Op_RegI,  8, A4->as_VMReg()->next());
    65   reg_def A5    (SOC, SOC,  Op_RegI,  9, A5->as_VMReg());
    66   reg_def A5_H  (SOC, SOC,  Op_RegI,  9, A5->as_VMReg()->next());
    67   reg_def A6    (SOC, SOC,  Op_RegI,  10, A6->as_VMReg());
    68   reg_def A6_H  (SOC, SOC,  Op_RegI,  10, A6->as_VMReg()->next());
    69   reg_def A7    (SOC, SOC,  Op_RegI,  11, A7->as_VMReg());
    70   reg_def A7_H  (SOC, SOC,  Op_RegI,  11, A7->as_VMReg()->next());
    71   reg_def T0    (SOC, SOC,  Op_RegI,  12, T0->as_VMReg());
    72   reg_def T0_H  (SOC, SOC,  Op_RegI,  12, T0->as_VMReg()->next());
    73   reg_def T1    (SOC, SOC,  Op_RegI,  13, T1->as_VMReg());
    74   reg_def T1_H  (SOC, SOC,  Op_RegI,  13, T1->as_VMReg()->next());
    75   reg_def T2    (SOC, SOC,  Op_RegI,  14, T2->as_VMReg());
    76   reg_def T2_H  (SOC, SOC,  Op_RegI,  14, T2->as_VMReg()->next());
    77   reg_def T3    (SOC, SOC,  Op_RegI,  15, T3->as_VMReg());
    78   reg_def T3_H  (SOC, SOC,  Op_RegI,  15, T3->as_VMReg()->next());
    79   reg_def S0    (SOC, SOE,  Op_RegI,  16, S0->as_VMReg());
    80   reg_def S0_H  (SOC, SOE,  Op_RegI,  16, S0->as_VMReg()->next());
    81   reg_def S1    (SOC, SOE,  Op_RegI,  17, S1->as_VMReg());
    82   reg_def S1_H  (SOC, SOE,  Op_RegI,  17, S1->as_VMReg()->next());
    83   reg_def S2    (SOC, SOE,  Op_RegI,  18, S2->as_VMReg());
    84   reg_def S2_H  (SOC, SOE,  Op_RegI,  18, S2->as_VMReg()->next());
    85   reg_def S3    (SOC, SOE,  Op_RegI,  19, S3->as_VMReg());
    86   reg_def S3_H  (SOC, SOE,  Op_RegI,  19, S3->as_VMReg()->next());
    87   reg_def S4    (SOC, SOE,  Op_RegI,  20, S4->as_VMReg());
    88   reg_def S4_H  (SOC, SOE,  Op_RegI,  20, S4->as_VMReg()->next());
    89   reg_def S5    (SOC, SOE,  Op_RegI,  21, S5->as_VMReg());
    90   reg_def S5_H  (SOC, SOE,  Op_RegI,  21, S5->as_VMReg()->next());
    91   reg_def S6    (SOC, SOE,  Op_RegI,  22, S6->as_VMReg());
    92   reg_def S6_H  (SOC, SOE,  Op_RegI,  22, S6->as_VMReg()->next());
    93   reg_def S7    (SOC, SOE,  Op_RegI,  23, S7->as_VMReg());
    94   reg_def S7_H  (SOC, SOE,  Op_RegI,  23, S7->as_VMReg()->next());
    95   reg_def T8    (SOC, SOC,  Op_RegI,  24, T8->as_VMReg());
    96   reg_def T8_H  (SOC, SOC,  Op_RegI,  24, T8->as_VMReg()->next());
    97   reg_def T9    (SOC, SOC,  Op_RegI,  25, T9->as_VMReg());
    98   reg_def T9_H  (SOC, SOC,  Op_RegI,  25, T9->as_VMReg()->next());
   100 // Special Registers
   101   reg_def K0    ( NS,  NS,  Op_RegI, 26, K0->as_VMReg());
   102   reg_def K1    ( NS,  NS,  Op_RegI, 27, K1->as_VMReg());
   103   reg_def GP    ( NS,  NS,  Op_RegI, 28, GP->as_VMReg());
   104   reg_def GP_H  ( NS,  NS,  Op_RegI, 28, GP->as_VMReg()->next());
   105   reg_def SP    ( NS,  NS,  Op_RegI, 29, SP->as_VMReg());
   106   reg_def SP_H  ( NS,  NS,  Op_RegI, 29, SP->as_VMReg()->next());
   107   reg_def FP    ( NS,  NS,  Op_RegI, 30, FP->as_VMReg());
   108   reg_def FP_H  ( NS,  NS,  Op_RegI, 30, FP->as_VMReg()->next());
   109   reg_def RA    ( NS,  NS,  Op_RegI, 31, RA->as_VMReg());
   110   reg_def RA_H  ( NS,  NS,  Op_RegI, 31, RA->as_VMReg()->next());
   112 // Floating registers.
   113 reg_def F0          ( SOC, SOC, Op_RegF, 0, F0->as_VMReg());
   114 reg_def F0_H        ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()->next());
   115 reg_def F1          ( SOC, SOC, Op_RegF, 1, F1->as_VMReg());
   116 reg_def F1_H        ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()->next());
   117 reg_def F2          ( SOC, SOC, Op_RegF, 2, F2->as_VMReg());
   118 reg_def F2_H        ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()->next());
   119 reg_def F3          ( SOC, SOC, Op_RegF, 3, F3->as_VMReg());
   120 reg_def F3_H        ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()->next());
   121 reg_def F4          ( SOC, SOC, Op_RegF, 4, F4->as_VMReg());
   122 reg_def F4_H        ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()->next());
   123 reg_def F5          ( SOC, SOC, Op_RegF, 5, F5->as_VMReg());
   124 reg_def F5_H        ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()->next());
   125 reg_def F6          ( SOC, SOC, Op_RegF, 6, F6->as_VMReg());
   126 reg_def F6_H        ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()->next());
   127 reg_def F7          ( SOC, SOC, Op_RegF, 7, F7->as_VMReg());
   128 reg_def F7_H        ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()->next());
   129 reg_def F8          ( SOC, SOC, Op_RegF, 8, F8->as_VMReg());
   130 reg_def F8_H        ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()->next());
   131 reg_def F9          ( SOC, SOC, Op_RegF, 9, F9->as_VMReg());
   132 reg_def F9_H        ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()->next());
   133 reg_def F10         ( SOC, SOC, Op_RegF, 10, F10->as_VMReg());
   134 reg_def F10_H       ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()->next());
   135 reg_def F11         ( SOC, SOC, Op_RegF, 11, F11->as_VMReg());
   136 reg_def F11_H       ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()->next());
   137 reg_def F12         ( SOC, SOC, Op_RegF, 12, F12->as_VMReg());
   138 reg_def F12_H       ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()->next());
   139 reg_def F13         ( SOC, SOC, Op_RegF, 13, F13->as_VMReg());
   140 reg_def F13_H       ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()->next());
   141 reg_def F14         ( SOC, SOC, Op_RegF, 14, F14->as_VMReg());
   142 reg_def F14_H       ( SOC, SOC, Op_RegF, 14, F14->as_VMReg()->next());
   143 reg_def F15         ( SOC, SOC, Op_RegF, 15, F15->as_VMReg());
   144 reg_def F15_H       ( SOC, SOC, Op_RegF, 15, F15->as_VMReg()->next());
   145 reg_def F16         ( SOC, SOC, Op_RegF, 16, F16->as_VMReg());
   146 reg_def F16_H       ( SOC, SOC, Op_RegF, 16, F16->as_VMReg()->next());
   147 reg_def F17         ( SOC, SOC, Op_RegF, 17, F17->as_VMReg());
   148 reg_def F17_H       ( SOC, SOC, Op_RegF, 17, F17->as_VMReg()->next());
   149 reg_def F18         ( SOC, SOC, Op_RegF, 18, F18->as_VMReg());
   150 reg_def F18_H       ( SOC, SOC, Op_RegF, 18, F18->as_VMReg()->next());
   151 reg_def F19         ( SOC, SOC, Op_RegF, 19, F19->as_VMReg());
   152 reg_def F19_H       ( SOC, SOC, Op_RegF, 19, F19->as_VMReg()->next());
   153 reg_def F20         ( SOC, SOC, Op_RegF, 20, F20->as_VMReg());
   154 reg_def F20_H       ( SOC, SOC, Op_RegF, 20, F20->as_VMReg()->next());
   155 reg_def F21         ( SOC, SOC, Op_RegF, 21, F21->as_VMReg());
   156 reg_def F21_H       ( SOC, SOC, Op_RegF, 21, F21->as_VMReg()->next());
   157 reg_def F22         ( SOC, SOC, Op_RegF, 22, F22->as_VMReg());
   158 reg_def F22_H       ( SOC, SOC, Op_RegF, 22, F22->as_VMReg()->next());
   159 reg_def F23         ( SOC, SOC, Op_RegF, 23, F23->as_VMReg());
   160 reg_def F23_H       ( SOC, SOC, Op_RegF, 23, F23->as_VMReg()->next());
   161 reg_def F24         ( SOC, SOC, Op_RegF, 24, F24->as_VMReg());
   162 reg_def F24_H       ( SOC, SOC, Op_RegF, 24, F24->as_VMReg()->next());
   163 reg_def F25         ( SOC, SOC, Op_RegF, 25, F25->as_VMReg());
   164 reg_def F25_H       ( SOC, SOC, Op_RegF, 25, F25->as_VMReg()->next());
   165 reg_def F26         ( SOC, SOC, Op_RegF, 26, F26->as_VMReg());
   166 reg_def F26_H       ( SOC, SOC, Op_RegF, 26, F26->as_VMReg()->next());
   167 reg_def F27         ( SOC, SOC, Op_RegF, 27, F27->as_VMReg());
   168 reg_def F27_H       ( SOC, SOC, Op_RegF, 27, F27->as_VMReg()->next());
   169 reg_def F28         ( SOC, SOC, Op_RegF, 28, F28->as_VMReg());
   170 reg_def F28_H       ( SOC, SOC, Op_RegF, 28, F28->as_VMReg()->next());
   171 reg_def F29         ( SOC, SOC, Op_RegF, 29, F29->as_VMReg());
   172 reg_def F29_H       ( SOC, SOC, Op_RegF, 29, F29->as_VMReg()->next());
   173 reg_def F30         ( SOC, SOC, Op_RegF, 30, F30->as_VMReg());
   174 reg_def F30_H       ( SOC, SOC, Op_RegF, 30, F30->as_VMReg()->next());
   175 reg_def F31         ( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
   176 reg_def F31_H       ( SOC, SOC, Op_RegF, 31, F31->as_VMReg()->next());
   179 // ----------------------------
   180 // Special Registers
   181 // Condition Codes Flag Registers
   182 reg_def MIPS_FLAG (SOC, SOC,  Op_RegFlags, 1, as_Register(1)->as_VMReg());
   183 //S6 is used for get_thread(S6)
   184 //S5 is uesd for heapbase of compressed oop
   185 alloc_class chunk0(
   186                      S7, S7_H,
   187                      S0, S0_H,
   188                      S1, S1_H,
   189                      S2, S2_H,
   190                      S4, S4_H,
   191                      S5, S5_H,
   192                      S6, S6_H,
   193                      S3, S3_H,
   194                      T2, T2_H,
   195                      T3, T3_H,
   196                      T8, T8_H,
   197                      T9, T9_H,
   198                      T1, T1_H, // inline_cache_reg
   199                      V1, V1_H,
   200                      A7, A7_H,
   201                      A6, A6_H,
   202                      A5, A5_H,
   203                      A4, A4_H,
   204                      V0, V0_H,
   205                      A3, A3_H,
   206                      A2, A2_H,
   207                      A1, A1_H,
   208                      A0, A0_H,
   209                      T0, T0_H,
   210                      GP, GP_H
   211                      RA, RA_H,
   212                      SP, SP_H, // stack_pointer
   213                      FP, FP_H  // frame_pointer
   214                  );
   216 alloc_class chunk1(  F0, F0_H,
   217                      F1, F1_H,
   218                      F2, F2_H,
   219                      F3, F3_H,
   220                      F4, F4_H,
   221                      F5, F5_H,
   222                      F6, F6_H,
   223                      F7, F7_H,
   224                      F8, F8_H,
   225                      F9, F9_H,
   226                      F10, F10_H,
   227                      F11, F11_H,
   228                      F20, F20_H,
   229                      F21, F21_H,
   230                      F22, F22_H,
   231                      F23, F23_H,
   232                      F24, F24_H,
   233                      F25, F25_H,
   234                      F26, F26_H,
   235                      F27, F27_H,
   236                      F28, F28_H,
   237                      F19, F19_H,
   238                      F18, F18_H,
   239                      F17, F17_H,
   240                      F16, F16_H,
   241                      F15, F15_H,
   242                      F14, F14_H,
   243                      F13, F13_H,
   244                      F12, F12_H,
   245                      F29, F29_H,
   246                      F30, F30_H,
   247                      F31, F31_H);
   249 alloc_class chunk2(MIPS_FLAG);
   251 reg_class s_reg( S0, S1, S2, S3, S4, S5, S6, S7 );
   252 reg_class s0_reg( S0 );
   253 reg_class s1_reg( S1 );
   254 reg_class s2_reg( S2 );
   255 reg_class s3_reg( S3 );
   256 reg_class s4_reg( S4 );
   257 reg_class s5_reg( S5 );
   258 reg_class s6_reg( S6 );
   259 reg_class s7_reg( S7 );
   261 reg_class t_reg( T0, T1, T2, T3, T8, T9 );
   262 reg_class t0_reg( T0 );
   263 reg_class t1_reg( T1 );
   264 reg_class t2_reg( T2 );
   265 reg_class t3_reg( T3 );
   266 reg_class t8_reg( T8 );
   267 reg_class t9_reg( T9 );
   269 reg_class a_reg( A0, A1, A2, A3, A4, A5, A6, A7 );
   270 reg_class a0_reg( A0 );
   271 reg_class a1_reg( A1 );
   272 reg_class a2_reg( A2 );
   273 reg_class a3_reg( A3 );
   274 reg_class a4_reg( A4 );
   275 reg_class a5_reg( A5 );
   276 reg_class a6_reg( A6 );
   277 reg_class a7_reg( A7 );
   279 reg_class v0_reg( V0 );
   280 reg_class v1_reg( V1 );
   282 reg_class sp_reg( SP, SP_H );
   283 reg_class fp_reg( FP, FP_H );
   285 reg_class mips_flags(MIPS_FLAG);
   287 reg_class v0_long_reg( V0, V0_H );
   288 reg_class v1_long_reg( V1, V1_H );
   289 reg_class a0_long_reg( A0, A0_H );
   290 reg_class a1_long_reg( A1, A1_H );
   291 reg_class a2_long_reg( A2, A2_H );
   292 reg_class a3_long_reg( A3, A3_H );
   293 reg_class a4_long_reg( A4, A4_H );
   294 reg_class a5_long_reg( A5, A5_H );
   295 reg_class a6_long_reg( A6, A6_H );
   296 reg_class a7_long_reg( A7, A7_H );
   297 reg_class t0_long_reg( T0, T0_H );
   298 reg_class t1_long_reg( T1, T1_H );
   299 reg_class t2_long_reg( T2, T2_H );
   300 reg_class t3_long_reg( T3, T3_H );
   301 reg_class t8_long_reg( T8, T8_H );
   302 reg_class t9_long_reg( T9, T9_H );
   303 reg_class s0_long_reg( S0, S0_H );
   304 reg_class s1_long_reg( S1, S1_H );
   305 reg_class s2_long_reg( S2, S2_H );
   306 reg_class s3_long_reg( S3, S3_H );
   307 reg_class s4_long_reg( S4, S4_H );
   308 reg_class s5_long_reg( S5, S5_H );
   309 reg_class s6_long_reg( S6, S6_H );
   310 reg_class s7_long_reg( S7, S7_H );
   312 reg_class int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, A7, A6, A5, A4, V0, A3, A2, A1, A0, T0 );
   314 reg_class no_Ax_int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, V0, T0 );
   316 reg_class p_reg(
   317                  S7, S7_H,
   318                  S0, S0_H,
   319                  S1, S1_H,
   320                  S2, S2_H,
   321                  S4, S4_H,
   322                  S3, S3_H,
   323                  T8, T8_H,
   324                  T2, T2_H,
   325                  T3, T3_H,
   326                  T1, T1_H,
   327                  A7, A7_H,
   328                  A6, A6_H,
   329                  A5, A5_H,
   330                  A4, A4_H,
   331                  A3, A3_H,
   332                  A2, A2_H,
   333                  A1, A1_H,
   334                  A0, A0_H,
   335                  T0, T0_H
   336                );
   338 reg_class no_T8_p_reg(
   339                  S7, S7_H,
   340                  S0, S0_H,
   341                  S1, S1_H,
   342                  S2, S2_H,
   343                  S4, S4_H,
   344                  S3, S3_H,
   345                  T2, T2_H,
   346                  T3, T3_H,
   347                  T1, T1_H,
   348                  A7, A7_H,
   349                  A6, A6_H,
   350                  A5, A5_H,
   351                  A4, A4_H,
   352                  A3, A3_H,
   353                  A2, A2_H,
   354                  A1, A1_H,
   355                  A0, A0_H,
   356                  T0, T0_H
   357                );
   359 reg_class long_reg(
   360                     S7, S7_H,
   361                     S0, S0_H,
   362                     S1, S1_H,
   363                     S2, S2_H,
   364                     S4, S4_H,
   365                     S3, S3_H,
   366                     T8, T8_H,
   367                     T2, T2_H,
   368                     T3, T3_H,
   369                     T1, T1_H,
   370                     A7, A7_H,
   371                     A6, A6_H,
   372                     A5, A5_H,
   373                     A4, A4_H,
   374                     A3, A3_H,
   375                     A2, A2_H,
   376                     A1, A1_H,
   377                     A0, A0_H,
   378                     T0, T0_H
   379                   );
   382 // Floating point registers.
   383 // 2012/8/23 Fu: F30/F31 are used as temporary registers in D2I
   384 // 2016/12/1 aoqi: F31 are not used as temporary registers in D2I
   385 reg_class flt_reg( F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17 F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F31);
   386 reg_class dbl_reg( F0, F0_H,
   387                    F1, F1_H,
   388                    F2, F2_H,
   389                    F3, F3_H,
   390                    F4, F4_H,
   391                    F5, F5_H,
   392                    F6, F6_H,
   393                    F7, F7_H,
   394                    F8, F8_H,
   395                    F9, F9_H,
   396                    F10, F10_H,
   397                    F11, F11_H,
   398                    F12, F12_H,
   399                    F13, F13_H,
   400                    F14, F14_H,
   401                    F15, F15_H,
   402                    F16, F16_H,
   403                    F17, F17_H,
   404                    F18, F18_H,
   405                    F19, F19_H,
   406                    F20, F20_H,
   407                    F21, F21_H,
   408                    F22, F22_H,
   409                    F23, F23_H,
   410                    F24, F24_H,
   411                    F25, F25_H,
   412                    F26, F26_H,
   413                    F27, F27_H,
   414                    F28, F28_H,
   415                    F29, F29_H,
   416                    F31, F31_H);
   418 reg_class flt_arg0( F12 );
   419 reg_class dbl_arg0( F12, F12_H );
   420 reg_class dbl_arg1( F14, F14_H );
   422 %}
   424 //----------DEFINITION BLOCK---------------------------------------------------
   425 // Define name --> value mappings to inform the ADLC of an integer valued name
   426 // Current support includes integer values in the range [0, 0x7FFFFFFF]
   427 // Format:
   428 //        int_def  <name>         ( <int_value>, <expression>);
   429 // Generated Code in ad_<arch>.hpp
   430 //        #define  <name>   (<expression>)
   431 //        // value == <int_value>
   432 // Generated code in ad_<arch>.cpp adlc_verification()
   433 //        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
   434 //
   435 definitions %{
   436   int_def DEFAULT_COST      (    100,     100);
   437   int_def HUGE_COST         (1000000, 1000000);
   439   // Memory refs are twice as expensive as run-of-the-mill.
   440   int_def MEMORY_REF_COST   (    200, DEFAULT_COST * 2);
   442   // Branches are even more expensive.
   443   int_def BRANCH_COST       (    300, DEFAULT_COST * 3);
   444   // we use jr instruction to construct call, so more expensive
   445   // by yjl 2/28/2006
   446   int_def CALL_COST         (    500, DEFAULT_COST * 5);
   447 /*
   448         int_def EQUAL             (   1, 1  );
   449         int_def NOT_EQUAL         (   2, 2  );
   450         int_def GREATER           (   3, 3  );
   451         int_def GREATER_EQUAL     (   4, 4  );
   452         int_def LESS              (   5, 5  );
   453         int_def LESS_EQUAL        (   6, 6  );
   454 */
   455 %}
   459 //----------SOURCE BLOCK-------------------------------------------------------
   460 // This is a block of C++ code which provides values, functions, and
   461 // definitions necessary in the rest of the architecture description
   463 source_hpp %{
   464 // Header information of the source block.
   465 // Method declarations/definitions which are used outside
   466 // the ad-scope can conveniently be defined here.
   467 //
   468 // To keep related declarations/definitions/uses close together,
   469 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
   471 class CallStubImpl {
   473   //--------------------------------------------------------------
   474   //---<  Used for optimization in Compile::shorten_branches  >---
   475   //--------------------------------------------------------------
   477  public:
   478   // Size of call trampoline stub.
   479   static uint size_call_trampoline() {
   480     return 0; // no call trampolines on this platform
   481   }
   483   // number of relocations needed by a call trampoline stub
   484   static uint reloc_call_trampoline() {
   485     return 0; // no call trampolines on this platform
   486   }
   487 };
   489 class HandlerImpl {
   491  public:
   493   static int emit_exception_handler(CodeBuffer &cbuf);
   494   static int emit_deopt_handler(CodeBuffer& cbuf);
   496   static uint size_exception_handler() {
   497     // NativeCall instruction size is the same as NativeJump.
   498     // exception handler starts out as jump and can be patched to
   499     // a call be deoptimization.  (4932387)
   500     // Note that this value is also credited (in output.cpp) to
   501     // the size of the code section.
   502     int size = NativeCall::instruction_size;
   503     return round_to(size, 16);
   504   }
   506 #ifdef _LP64
   507   static uint size_deopt_handler() {
   508     int size = NativeCall::instruction_size;
   509     return round_to(size, 16);
   510   }
   511 #else
   512   static uint size_deopt_handler() {
   513     // NativeCall instruction size is the same as NativeJump.
   514     // exception handler starts out as jump and can be patched to
   515     // a call be deoptimization.  (4932387)
   516     // Note that this value is also credited (in output.cpp) to
   517     // the size of the code section.
   518     return 5 + NativeJump::instruction_size; // pushl(); jmp;
   519   }
   520 #endif
   521 };
   523 %} // end source_hpp
   525 source %{
   527 #define   NO_INDEX    0
   528 #define   RELOC_IMM64    Assembler::imm_operand
   529 #define   RELOC_DISP32   Assembler::disp32_operand
   532 #define __ _masm.
   535 // Emit exception handler code.
   536 // Stuff framesize into a register and call a VM stub routine.
   537 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
   538   // Note that the code buffer's insts_mark is always relative to insts.
   539   // That's why we must use the macroassembler to generate a handler.
   540   MacroAssembler _masm(&cbuf);
   541   address base =
   542   __ start_a_stub(size_exception_handler());
   543   if (base == NULL)  return 0;  // CodeBuffer::expand failed
   544   int offset = __ offset();
   546   __ block_comment("; emit_exception_handler");
   548   cbuf.set_insts_mark();
   549   __ relocate(relocInfo::runtime_call_type);
   550   __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
   551   __ align(16);
   552   assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
   553   __ end_a_stub();
   554   return offset;
   555 }
   557 // Emit deopt handler code.
   558 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
   559   // Note that the code buffer's insts_mark is always relative to insts.
   560   // That's why we must use the macroassembler to generate a handler.
   561   MacroAssembler _masm(&cbuf);
   562   address base =
   563   __ start_a_stub(size_deopt_handler());
   565   // FIXME
   566   if (base == NULL)  return 0;  // CodeBuffer::expand failed
   567   int offset = __ offset();
   569   __ block_comment("; emit_deopt_handler");
   571   cbuf.set_insts_mark();
   572   __ relocate(relocInfo::runtime_call_type);
   573   __ patchable_call(SharedRuntime::deopt_blob()->unpack());
   574   __ align(16);
   575   assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
   576   __ end_a_stub();
   577   return offset;
   578 }
   581 const bool Matcher::match_rule_supported(int opcode) {
   582   if (!has_match_rule(opcode))
   583     return false;
   585   switch (opcode) {
   586     //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
   587     case Op_CountLeadingZerosI:
   588     case Op_CountLeadingZerosL:
   589       if (!UseCountLeadingZerosInstruction)
   590         return false;
   591       break;
   592     case Op_CountTrailingZerosI:
   593     case Op_CountTrailingZerosL:
   594       if (!UseCountTrailingZerosInstruction)
   595         return false;
   596       break;
   597   }
   599   return true;  // Per default match rules are supported.
   600 }
   602 //FIXME
   603 // emit call stub, compiled java to interpreter
   604 void emit_java_to_interp(CodeBuffer &cbuf ) {
   605   // Stub is fixed up when the corresponding call is converted from calling
   606   // compiled code to calling interpreted code.
   607   // mov rbx,0
   608   // jmp -1
   610   address mark = cbuf.insts_mark();  // get mark within main instrs section
   612   // Note that the code buffer's insts_mark is always relative to insts.
   613   // That's why we must use the macroassembler to generate a stub.
   614   MacroAssembler _masm(&cbuf);
   616   address base =
   617   __ start_a_stub(Compile::MAX_stubs_size);
   618   if (base == NULL)  return;  // CodeBuffer::expand failed
   619   // static stub relocation stores the instruction address of the call
   621   __ relocate(static_stub_Relocation::spec(mark), 0);
   623   // static stub relocation also tags the methodOop in the code-stream.
   624   __ patchable_set48(S3, (long)0);
   625   // This is recognized as unresolved by relocs/nativeInst/ic code
   627   __ relocate(relocInfo::runtime_call_type);
   629   cbuf.set_insts_mark();
   630   address call_pc = (address)-1;
   631   __ patchable_jump(call_pc);
   632   __ align(16);
   633   __ end_a_stub();
   634   // Update current stubs pointer and restore code_end.
   635 }
   637 // size of call stub, compiled java to interpretor
   638 uint size_java_to_interp() {
   639   int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
   640   return round_to(size, 16);
   641 }
   643 // relocation entries for call stub, compiled java to interpreter
   644 uint reloc_java_to_interp() {
   645   return 16;  //  in emit_java_to_interp +  in Java_Static_Call
   646 }
   648 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
   649   if( Assembler::is_simm16(offset) )
   650     return true;
   651   else {
   652      assert(false, "Not implemented yet !" );
   653      Unimplemented();
   654   }
   655 }
   658 // No additional cost for CMOVL.
   659 const int Matcher::long_cmove_cost() { return 0; }
   661 // No CMOVF/CMOVD with SSE2
   662 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
   664 // Does the CPU require late expand (see block.cpp for description of late expand)?
   665 const bool Matcher::require_postalloc_expand = false;
   667 // Should the Matcher clone shifts on addressing modes, expecting them
   668 // to be subsumed into complex addressing expressions or compute them
   669 // into registers?  True for Intel but false for most RISCs
   670 const bool Matcher::clone_shift_expressions = false;
   672 // Do we need to mask the count passed to shift instructions or does
   673 // the cpu only look at the lower 5/6 bits anyway?
   674 const bool Matcher::need_masked_shift_count = false;
   676 bool Matcher::narrow_oop_use_complex_address() {
   677   NOT_LP64(ShouldNotCallThis());
   678   assert(UseCompressedOops, "only for compressed oops code");
   679   return false;
   680 }
   682 bool Matcher::narrow_klass_use_complex_address() {
   683   NOT_LP64(ShouldNotCallThis());
   684   assert(UseCompressedClassPointers, "only for compressed klass code");
   685   return false;
   686 }
   688 // This is UltraSparc specific, true just means we have fast l2f conversion
   689 const bool Matcher::convL2FSupported(void) {
   690   return true;
   691 }
   693 // Max vector size in bytes. 0 if not supported.
   694 const int Matcher::vector_width_in_bytes(BasicType bt) {
   695   if (MaxVectorSize == 0)
   696     return 0;
   697   assert(MaxVectorSize == 8, "");
   698   return 8;
   699 }
   701 // Vector ideal reg
   702 const int Matcher::vector_ideal_reg(int size) {
   703   assert(MaxVectorSize == 8, "");
   704   switch(size) {
   705     case  8: return Op_VecD;
   706   }
   707   ShouldNotReachHere();
   708   return 0;
   709 }
   711 // Only lowest bits of xmm reg are used for vector shift count.
   712 const int Matcher::vector_shift_count_ideal_reg(int size) {
   713   fatal("vector shift is not supported");
   714   return Node::NotAMachineReg;
   715 }
   717 // Limits on vector size (number of elements) loaded into vector.
   718 const int Matcher::max_vector_size(const BasicType bt) {
   719   assert(is_java_primitive(bt), "only primitive type vectors");
   720   return vector_width_in_bytes(bt)/type2aelembytes(bt);
   721 }
   723 const int Matcher::min_vector_size(const BasicType bt) {
   724   return max_vector_size(bt); // Same as max.
   725 }
   727 // MIPS supports misaligned vectors store/load? FIXME
   728 const bool Matcher::misaligned_vectors_ok() {
   729   return false;
   730   //return !AlignVector; // can be changed by flag
   731 }
   733 // Register for DIVI projection of divmodI
   734 RegMask Matcher::divI_proj_mask() {
   735   ShouldNotReachHere();
   736   return RegMask();
   737 }
   739 // Register for MODI projection of divmodI
   740 RegMask Matcher::modI_proj_mask() {
   741   ShouldNotReachHere();
   742   return RegMask();
   743 }
   745 // Register for DIVL projection of divmodL
   746 RegMask Matcher::divL_proj_mask() {
   747   ShouldNotReachHere();
   748   return RegMask();
   749 }
   751 int Matcher::regnum_to_fpu_offset(int regnum) {
   752   return regnum - 32; // The FP registers are in the second chunk
   753 }
   756 const bool Matcher::isSimpleConstant64(jlong value) {
   757   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
   758   return true;
   759 }
   762 // Return whether or not this register is ever used as an argument.  This
   763 // function is used on startup to build the trampoline stubs in generateOptoStub.
   764 // Registers not mentioned will be killed by the VM call in the trampoline, and
   765 // arguments in those registers not be available to the callee.
   766 bool Matcher::can_be_java_arg( int reg ) {
   767   /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
   768   if (    reg == T0_num || reg == T0_H_num
   769        || reg == A0_num || reg == A0_H_num
   770        || reg == A1_num || reg == A1_H_num
   771        || reg == A2_num || reg == A2_H_num
   772        || reg == A3_num || reg == A3_H_num
   773        || reg == A4_num || reg == A4_H_num
   774        || reg == A5_num || reg == A5_H_num
   775        || reg == A6_num || reg == A6_H_num
   776        || reg == A7_num || reg == A7_H_num )
   777     return true;
   779   if (    reg == F12_num || reg == F12_H_num
   780        || reg == F13_num || reg == F13_H_num
   781        || reg == F14_num || reg == F14_H_num
   782        || reg == F15_num || reg == F15_H_num
   783        || reg == F16_num || reg == F16_H_num
   784        || reg == F17_num || reg == F17_H_num
   785        || reg == F18_num || reg == F18_H_num
   786        || reg == F19_num || reg == F19_H_num )
   787     return true;
   789   return false;
   790 }
   792 bool Matcher::is_spillable_arg( int reg ) {
   793   return can_be_java_arg(reg);
   794 }
   796 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
   797   return false;
   798 }
   800 // Register for MODL projection of divmodL
   801 RegMask Matcher::modL_proj_mask() {
   802   ShouldNotReachHere();
   803   return RegMask();
   804 }
   806 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
   807   return FP_REG_mask();
   808 }
   810 // MIPS doesn't support AES intrinsics
   811 const bool Matcher::pass_original_key_for_aes() {
   812   return false;
   813 }
   815 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
   816   //lui
   817   //ori
   818   //dsll
   819   //ori
   821   //jalr
   822   //nop
   824   return round_to(current_offset, alignment_required()) - current_offset;
   825 }
   827 int CallLeafDirectNode::compute_padding(int current_offset) const {
   828   //lui
   829   //ori
   830   //dsll
   831   //ori
   833   //jalr
   834   //nop
   836   return round_to(current_offset, alignment_required()) - current_offset;
   837 }
   839 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
   840   //lui
   841   //ori
   842   //dsll
   843   //ori
   845   //jalr
   846   //nop
   848   return round_to(current_offset, alignment_required()) - current_offset;
   849 }
   851 // If CPU can load and store mis-aligned doubles directly then no fixup is
   852 // needed.  Else we split the double into 2 integer pieces and move it
   853 // piece-by-piece.  Only happens when passing doubles into C code as the
   854 // Java calling convention forces doubles to be aligned.
   855 const bool Matcher::misaligned_doubles_ok = false;
   856 // Do floats take an entire double register or just half?
   857 //const bool Matcher::float_in_double = true;
   858 bool Matcher::float_in_double() { return false; }
   859 // Threshold size for cleararray.
   860 const int Matcher::init_array_short_size = 8 * BytesPerLong;
   861 // Do ints take an entire long register or just half?
   862 const bool Matcher::int_in_long = true;
   863 // Is it better to copy float constants, or load them directly from memory?
   864 // Intel can load a float constant from a direct address, requiring no
   865 // extra registers.  Most RISCs will have to materialize an address into a
   866 // register first, so they would do better to copy the constant from stack.
   867 const bool Matcher::rematerialize_float_constants = false;
   868 // Advertise here if the CPU requires explicit rounding operations
   869 // to implement the UseStrictFP mode.
   870 const bool Matcher::strict_fp_requires_explicit_rounding = false;
   871 // The ecx parameter to rep stos for the ClearArray node is in dwords.
   872 const bool Matcher::init_array_count_is_in_bytes = false;
   875 // Indicate if the safepoint node needs the polling page as an input.
   876 // Since MIPS doesn't have absolute addressing, it needs.
   877 bool SafePointNode::needs_polling_address_input() {
   878   return false;
   879 }
   881 // !!!!! Special hack to get all type of calls to specify the byte offset
   882 //       from the start of the call to the point where the return address
   883 //       will point.
   884 int MachCallStaticJavaNode::ret_addr_offset() {
   885   //lui
   886   //ori
   887   //nop
   888   //nop
   889   //jalr
   890   //nop
   891   return 24;
   892 }
   894 int MachCallDynamicJavaNode::ret_addr_offset() {
   895   //lui IC_Klass,
   896   //ori IC_Klass,
   897   //dsll IC_Klass
   898   //ori IC_Klass
   900   //lui T9
   901   //ori T9
   902   //nop
   903   //nop
   904   //jalr T9
   905   //nop
   906   return 4 * 4 + 4 * 6;
   907 }
   909 //=============================================================================
   911 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
   912 enum RC { rc_bad, rc_int, rc_float, rc_stack };
   913 static enum RC rc_class( OptoReg::Name reg ) {
   914   if( !OptoReg::is_valid(reg)  ) return rc_bad;
   915   if (OptoReg::is_stack(reg)) return rc_stack;
   916   VMReg r = OptoReg::as_VMReg(reg);
   917   if (r->is_Register()) return rc_int;
   918   assert(r->is_FloatRegister(), "must be");
   919   return rc_float;
   920 }
   922 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
   923   // Get registers to move
   924   OptoReg::Name src_second = ra_->get_reg_second(in(1));
   925   OptoReg::Name src_first = ra_->get_reg_first(in(1));
   926   OptoReg::Name dst_second = ra_->get_reg_second(this );
   927   OptoReg::Name dst_first = ra_->get_reg_first(this );
   929   enum RC src_second_rc = rc_class(src_second);
   930   enum RC src_first_rc = rc_class(src_first);
   931   enum RC dst_second_rc = rc_class(dst_second);
   932   enum RC dst_first_rc = rc_class(dst_first);
   934   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
   936   // Generate spill code!
   937   int size = 0;
   939   if( src_first == dst_first && src_second == dst_second )
   940     return 0;            // Self copy, no move
   942   if (src_first_rc == rc_stack) {
   943     // mem ->
   944     if (dst_first_rc == rc_stack) {
   945       // mem -> mem
   946       assert(src_second != dst_first, "overlap");
   947       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   948           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   949         // 64-bit
   950         int src_offset = ra_->reg2offset(src_first);
   951         int dst_offset = ra_->reg2offset(dst_first);
   952         if (cbuf) {
   953           MacroAssembler _masm(cbuf);
   954           __ ld(AT, Address(SP, src_offset));
   955           __ sd(AT, Address(SP, dst_offset));
   956 #ifndef PRODUCT
   957         } else {
   958           if(!do_size){
   959             if (size != 0) st->print("\n\t");
   960               st->print("ld    AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
   961                         "sd    AT, [SP + #%d]",
   962                         src_offset, dst_offset);
   963           }
   964 #endif
   965         }
   966         size += 8;
   967       } else {
   968         // 32-bit
   969         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
   970         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
   971         // No pushl/popl, so:
   972         int src_offset = ra_->reg2offset(src_first);
   973         int dst_offset = ra_->reg2offset(dst_first);
   974         if (cbuf) {
   975           MacroAssembler _masm(cbuf);
   976           __ lw(AT, Address(SP, src_offset));
   977           __ sw(AT, Address(SP, dst_offset));
   978 #ifndef PRODUCT
   979         } else {
   980           if(!do_size){
   981             if (size != 0) st->print("\n\t");
   982               st->print("lw    AT, [SP + #%d] spill 2\n\t"
   983                         "sw    AT, [SP + #%d]\n\t",
   984                         src_offset, dst_offset);
   985           }
   986 #endif
   987         }
   988         size += 8;
   989       }
   990       return size;
   991     } else if (dst_first_rc == rc_int) {
   992       // mem -> gpr
   993       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
   994           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
   995         // 64-bit
   996         int offset = ra_->reg2offset(src_first);
   997         if (cbuf) {
   998           MacroAssembler _masm(cbuf);
   999           __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1000 #ifndef PRODUCT
  1001         } else {
  1002           if(!do_size){
  1003             if (size != 0) st->print("\n\t");
  1004               st->print("ld    %s, [SP + #%d]\t# spill 3",
  1005                         Matcher::regName[dst_first],
  1006                         offset);
  1008 #endif
  1010         size += 4;
  1011       } else {
  1012         // 32-bit
  1013         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1014         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1015         int offset = ra_->reg2offset(src_first);
  1016         if (cbuf) {
  1017           MacroAssembler _masm(cbuf);
  1018           if (this->ideal_reg() == Op_RegI)
  1019             __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1020           else
  1021             __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1022 #ifndef PRODUCT
  1023           } else {
  1024             if(!do_size){
  1025               if (size != 0) st->print("\n\t");
  1026               if (this->ideal_reg() == Op_RegI)
  1027                 st->print("lw    %s, [SP + #%d]\t# spill 4",
  1028                           Matcher::regName[dst_first],
  1029                           offset);
  1030               else
  1031                 st->print("lwu    %s, [SP + #%d]\t# spill 5",
  1032                           Matcher::regName[dst_first],
  1033                           offset);
  1035 #endif
  1037           size += 4;
  1039       return size;
  1040     } else if (dst_first_rc == rc_float) {
  1041       // mem-> xmm
  1042       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1043           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1044         // 64-bit
  1045         int offset = ra_->reg2offset(src_first);
  1046         if (cbuf) {
  1047           MacroAssembler _masm(cbuf);
  1048           __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1049 #ifndef PRODUCT
  1050         } else {
  1051           if (!do_size) {
  1052             if (size != 0) st->print("\n\t");
  1053             st->print("ldc1  %s, [SP + #%d]\t# spill 6",
  1054                       Matcher::regName[dst_first],
  1055                       offset);
  1057 #endif
  1059         size += 4;
  1060       } else {
  1061         // 32-bit
  1062         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1063         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1064         int offset = ra_->reg2offset(src_first);
  1065         if (cbuf) {
  1066           MacroAssembler _masm(cbuf);
  1067           __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
  1068 #ifndef PRODUCT
  1069         } else {
  1070           if(!do_size){
  1071             if (size != 0) st->print("\n\t");
  1072             st->print("lwc1   %s, [SP + #%d]\t# spill 7",
  1073                       Matcher::regName[dst_first],
  1074                       offset);
  1076 #endif
  1078         size += 4;
  1080       return size;
  1082   } else if (src_first_rc == rc_int) {
  1083     // gpr ->
  1084     if (dst_first_rc == rc_stack) {
  1085       // gpr -> mem
  1086       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1087           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1088         // 64-bit
  1089         int offset = ra_->reg2offset(dst_first);
  1090         if (cbuf) {
  1091           MacroAssembler _masm(cbuf);
  1092           __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1093 #ifndef PRODUCT
  1094         } else {
  1095           if(!do_size){
  1096             if (size != 0) st->print("\n\t");
  1097             st->print("sd    %s, [SP + #%d] # spill 8",
  1098                       Matcher::regName[src_first],
  1099                       offset);
  1101 #endif
  1103         size += 4;
  1104       } else {
  1105         // 32-bit
  1106         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1107         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1108         int offset = ra_->reg2offset(dst_first);
  1109         if (cbuf) {
  1110           MacroAssembler _masm(cbuf);
  1111           __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
  1112 #ifndef PRODUCT
  1113         } else {
  1114           if (!do_size) {
  1115             if (size != 0) st->print("\n\t");
  1116             st->print("sw    %s, [SP + #%d]\t# spill 9",
  1117                       Matcher::regName[src_first], offset);
  1119 #endif
  1121         size += 4;
  1123       return size;
  1124     } else if (dst_first_rc == rc_int) {
  1125       // gpr -> gpr
  1126       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1127           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1128         // 64-bit
  1129         if (cbuf) {
  1130           MacroAssembler _masm(cbuf);
  1131           __ move(as_Register(Matcher::_regEncode[dst_first]),
  1132                   as_Register(Matcher::_regEncode[src_first]));
  1133 #ifndef PRODUCT
  1134         } else {
  1135           if(!do_size){
  1136             if (size != 0) st->print("\n\t");
  1137             st->print("move(64bit)    %s <-- %s\t# spill 10",
  1138                       Matcher::regName[dst_first],
  1139                       Matcher::regName[src_first]);
  1141 #endif
  1143         size += 4;
  1144         return size;
  1145       } else {
  1146         // 32-bit
  1147         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1148         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1149         if (cbuf) {
  1150           MacroAssembler _masm(cbuf);
  1151           if (this->ideal_reg() == Op_RegI)
  1152               __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
  1153           else
  1154               __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
  1155 #ifndef PRODUCT
  1156         } else {
  1157           if (!do_size) {
  1158             if (size != 0) st->print("\n\t");
  1159             st->print("move(32-bit)    %s <-- %s\t# spill 11",
  1160                       Matcher::regName[dst_first],
  1161                       Matcher::regName[src_first]);
  1163 #endif
  1165         size += 4;
  1166         return size;
  1168     } else if (dst_first_rc == rc_float) {
  1169       // gpr -> xmm
  1170       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1171           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1172         // 64-bit
  1173         if (cbuf) {
  1174           MacroAssembler _masm(cbuf);
  1175           __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
  1176 #ifndef PRODUCT
  1177         } else {
  1178           if(!do_size){
  1179             if (size != 0) st->print("\n\t");
  1180             st->print("dmtc1   %s, %s\t# spill 12",
  1181                       Matcher::regName[dst_first],
  1182                       Matcher::regName[src_first]);
  1184 #endif
  1186         size += 4;
  1187       } else {
  1188         // 32-bit
  1189         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1190         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1191         if (cbuf) {
  1192           MacroAssembler _masm(cbuf);
  1193           __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
  1194 #ifndef PRODUCT
  1195         } else {
  1196           if(!do_size){
  1197             if (size != 0) st->print("\n\t");
  1198             st->print("mtc1   %s, %s\t# spill 13",
  1199                       Matcher::regName[dst_first],
  1200                       Matcher::regName[src_first]);
  1202 #endif
  1204         size += 4;
  1206       return size;
  1208   } else if (src_first_rc == rc_float) {
  1209     // xmm ->
  1210     if (dst_first_rc == rc_stack) {
  1211       // xmm -> mem
  1212       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1213           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1214         // 64-bit
  1215         int offset = ra_->reg2offset(dst_first);
  1216         if (cbuf) {
  1217           MacroAssembler _masm(cbuf);
  1218           __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
  1219 #ifndef PRODUCT
  1220         } else {
  1221           if(!do_size){
  1222             if (size != 0) st->print("\n\t");
  1223             st->print("sdc1   %s, [SP + #%d]\t# spill 14",
  1224                       Matcher::regName[src_first],
  1225                       offset);
  1227 #endif
  1229         size += 4;
  1230       } else {
  1231         // 32-bit
  1232         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1233         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1234         int offset = ra_->reg2offset(dst_first);
  1235         if (cbuf) {
  1236           MacroAssembler _masm(cbuf);
  1237           __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
  1238 #ifndef PRODUCT
  1239         } else {
  1240           if(!do_size){
  1241             if (size != 0) st->print("\n\t");
  1242             st->print("swc1   %s, [SP + #%d]\t# spill 15",
  1243                       Matcher::regName[src_first],
  1244                       offset);
  1246 #endif
  1248         size += 4;
  1250       return size;
  1251     } else if (dst_first_rc == rc_int) {
  1252       // xmm -> gpr
  1253       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1254           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1255         // 64-bit
  1256         if (cbuf) {
  1257           MacroAssembler _masm(cbuf);
  1258           __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1259 #ifndef PRODUCT
  1260         } else {
  1261           if(!do_size){
  1262             if (size != 0) st->print("\n\t");
  1263             st->print("dmfc1   %s, %s\t# spill 16",
  1264                       Matcher::regName[dst_first],
  1265                       Matcher::regName[src_first]);
  1267 #endif
  1269         size += 4;
  1270       } else {
  1271         // 32-bit
  1272         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1273         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1274         if (cbuf) {
  1275           MacroAssembler _masm(cbuf);
  1276           __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1277 #ifndef PRODUCT
  1278         } else {
  1279       if(!do_size){
  1280             if (size != 0) st->print("\n\t");
  1281             st->print("mfc1   %s, %s\t# spill 17",
  1282                       Matcher::regName[dst_first],
  1283                       Matcher::regName[src_first]);
  1285 #endif
  1287         size += 4;
  1289       return size;
  1290     } else if (dst_first_rc == rc_float) {
  1291       // xmm -> xmm
  1292       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
  1293           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
  1294         // 64-bit
  1295         if (cbuf) {
  1296           MacroAssembler _masm(cbuf);
  1297           __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1298 #ifndef PRODUCT
  1299         } else {
  1300           if(!do_size){
  1301             if (size != 0) st->print("\n\t");
  1302             st->print("mov_d  %s <-- %s\t# spill 18",
  1303                       Matcher::regName[dst_first],
  1304                       Matcher::regName[src_first]);
  1306 #endif
  1308         size += 4;
  1309       } else {
  1310         // 32-bit
  1311         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
  1312         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
  1313         if (cbuf) {
  1314           MacroAssembler _masm(cbuf);
  1315           __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
  1316 #ifndef PRODUCT
  1317         } else {
  1318           if(!do_size){
  1319             if (size != 0) st->print("\n\t");
  1320             st->print("mov_s  %s <-- %s\t# spill 19",
  1321                       Matcher::regName[dst_first],
  1322                       Matcher::regName[src_first]);
  1324 #endif
  1326         size += 4;
  1328       return size;
  1332   assert(0," foo ");
  1333   Unimplemented();
  1334   return size;
  1338 #ifndef PRODUCT
  1339 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1340   implementation( NULL, ra_, false, st );
  1342 #endif
  1344 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1345   implementation( &cbuf, ra_, false, NULL );
  1348 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
  1349   return implementation( NULL, ra_, true, NULL );
  1352 //=============================================================================
  1355 #ifndef PRODUCT
  1356 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1357   st->print("INT3");
  1359 #endif
  1361 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
  1362   MacroAssembler _masm(&cbuf);
  1363   __ int3();
  1366 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
  1367   return MachNode::size(ra_);
  1371 //=============================================================================
  1372 #ifndef PRODUCT
  1373 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1374   Compile *C = ra_->C;
  1375   int framesize = C->frame_size_in_bytes();
  1377   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1379   st->print("daddiu   SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
  1380   st->cr(); st->print("\t");
  1381   if (UseLoongsonISA) {
  1382     st->print("gslq  RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
  1383   } else {
  1384     st->print("ld    RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
  1385     st->cr(); st->print("\t");
  1386     st->print("ld    FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
  1389   if( do_polling() && C->is_method_compilation() ) {
  1390     st->print("Poll Safepoint # MachEpilogNode");
  1393 #endif
  1395 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1396   Compile *C = ra_->C;
  1397   MacroAssembler _masm(&cbuf);
  1398   int framesize = C->frame_size_in_bytes();
  1400   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1402   __ daddiu(SP, SP, framesize);
  1404   if (UseLoongsonISA) {
  1405     __ gslq(RA, FP, SP, -wordSize*2);
  1406   } else {
  1407     __ ld(RA, SP, -wordSize );
  1408     __ ld(FP, SP, -wordSize*2 );
  1411   if( do_polling() && C->is_method_compilation() ) {
  1412     __ set64(AT, (long)os::get_polling_page());
  1413     __ relocate(relocInfo::poll_return_type);
  1414     __ lw(AT, AT, 0);
  1418 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
  1419   return MachNode::size(ra_); // too many variables; just compute it the hard way  fujie debug
  1422 int MachEpilogNode::reloc() const {
  1423   return 0; // a large enough number
  1426 const Pipeline * MachEpilogNode::pipeline() const {
  1427   return MachNode::pipeline_class();
  1430 int MachEpilogNode::safepoint_offset() const { return 0; }
  1432 //=============================================================================
  1434 #ifndef PRODUCT
  1435 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1436   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1437   int reg = ra_->get_reg_first(this);
  1438   st->print("ADDI %s, SP, %d   @BoxLockNode",Matcher::regName[reg],offset);
  1440 #endif
  1443 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
  1444   return 4;
  1447 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1448   MacroAssembler _masm(&cbuf);
  1449   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
  1450   int reg = ra_->get_encode(this);
  1452   __ addi(as_Register(reg), SP, offset);
  1456 //static int sizeof_FFree_Float_Stack_All = -1;
  1458 int MachCallRuntimeNode::ret_addr_offset() {
  1459   //lui
  1460   //ori
  1461   //dsll
  1462   //ori
  1463   //jalr
  1464   //nop
  1465   assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
  1466   return NativeCall::instruction_size;
  1470 //=============================================================================
  1471 #ifndef PRODUCT
  1472 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
  1473   st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
  1475 #endif
  1477 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
  1478   MacroAssembler _masm(&cbuf);
  1479   int i = 0;
  1480   for(i = 0; i < _count; i++)
  1481      __ nop();
  1484 uint MachNopNode::size(PhaseRegAlloc *) const {
  1485   return 4 * _count;
  1487 const Pipeline* MachNopNode::pipeline() const {
  1488   return MachNode::pipeline_class();
  1491 //=============================================================================
  1493 //=============================================================================
  1494 #ifndef PRODUCT
  1495 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1496   st->print_cr("load_klass(T9, T0)");
  1497   st->print_cr("\tbeq(T9, iCache, L)");
  1498   st->print_cr("\tnop");
  1499   st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
  1500   st->print_cr("\tnop");
  1501   st->print_cr("\tnop");
  1502   st->print_cr("    L:");
  1504 #endif
  1507 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1508   MacroAssembler _masm(&cbuf);
  1509 #ifdef ASSERT
  1510   //uint code_size = cbuf.code_size();
  1511 #endif
  1512   int  ic_reg = Matcher::inline_cache_reg_encode();
  1513   Label L;
  1514   Register receiver = T0;
  1515   Register   iCache = as_Register(ic_reg);
  1516   __ load_klass(T9, receiver);
  1517   __ beq(T9, iCache, L);
  1518   __ nop();
  1520   __ relocate(relocInfo::runtime_call_type);
  1521   __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
  1523   /* WARNING these NOPs are critical so that verified entry point is properly
  1524    *      8 bytes aligned for patching by NativeJump::patch_verified_entry() */
  1525   __ align(CodeEntryAlignment);
  1526   __ bind(L);
  1529 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
  1530   return MachNode::size(ra_);
  1535 //=============================================================================
  1537 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
  1539 int Compile::ConstantTable::calculate_table_base_offset() const {
  1540   return 0;  // absolute addressing, no offset
  1543 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
  1544 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
  1545   ShouldNotReachHere();
  1548 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
  1549   Compile* C = ra_->C;
  1550   Compile::ConstantTable& constant_table = C->constant_table();
  1551   MacroAssembler _masm(&cbuf);
  1553   Register Rtoc = as_Register(ra_->get_encode(this));
  1554   CodeSection* consts_section = __ code()->consts();
  1555   int consts_size = consts_section->align_at_start(consts_section->size());
  1556   assert(constant_table.size() == consts_size, "must be equal");
  1558   if (consts_section->size()) {
  1559     // Materialize the constant table base.
  1560     address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
  1561     // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
  1562     __ relocate(relocInfo::internal_pc_type);
  1563     __ patchable_set48(Rtoc, (long)baseaddr);
  1567 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
  1568   // patchable_set48 (4 insts)
  1569   return 4 * 4;
  1572 #ifndef PRODUCT
  1573 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
  1574   Register r = as_Register(ra_->get_encode(this));
  1575   st->print("patchable_set48    %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
  1577 #endif
  1580 //=============================================================================
  1581 #ifndef PRODUCT
  1582 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
  1583   Compile* C = ra_->C;
  1585   int framesize = C->frame_size_in_bytes();
  1586   int bangsize = C->bang_size_in_bytes();
  1587   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1589   // Calls to C2R adapters often do not accept exceptional returns.
  1590   // We require that their callers must bang for them.  But be careful, because
  1591   // some VM calls (such as call site linkage) can use several kilobytes of
  1592   // stack.  But the stack safety zone should account for that.
  1593   // See bugs 4446381, 4468289, 4497237.
  1594   if (C->need_stack_bang(bangsize)) {
  1595     st->print_cr("# stack bang"); st->print("\t");
  1597   if (UseLoongsonISA) {
  1598     st->print("gssq     RA, FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1599   } else {
  1600     st->print("sd       RA, %d(SP)  @ MachPrologNode\n\t", -wordSize);
  1601     st->print("sd       FP, %d(SP)  @ MachPrologNode\n\t", -wordSize*2);
  1603   st->print("daddiu   FP, SP, -%d \n\t", wordSize*2);
  1604   st->print("daddiu   SP, SP, -%d \t",framesize);
  1606 #endif
  1609 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1610   Compile* C = ra_->C;
  1611   MacroAssembler _masm(&cbuf);
  1613   int framesize = C->frame_size_in_bytes();
  1614   int bangsize = C->bang_size_in_bytes();
  1616   assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
  1618   if (C->need_stack_bang(bangsize)) {
  1619     __ generate_stack_overflow_check(bangsize);
  1622   if (UseLoongsonISA) {
  1623     __ gssq(RA, FP, SP, -wordSize*2);
  1624   } else {
  1625     __ sd(RA, SP, -wordSize);
  1626     __ sd(FP, SP, -wordSize*2);
  1628   __ daddiu(FP, SP, -wordSize*2);
  1629   __ daddiu(SP, SP, -framesize);
  1630   __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
  1631   __ nop();
  1633   C->set_frame_complete(cbuf.insts_size());
  1634   if (C->has_mach_constant_base_node()) {
  1635     // NOTE: We set the table base offset here because users might be
  1636     // emitted before MachConstantBaseNode.
  1637     Compile::ConstantTable& constant_table = C->constant_table();
  1638     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
  1644 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
  1645   return MachNode::size(ra_); // too many variables; just compute it the hard way
  1648 int MachPrologNode::reloc() const {
  1649   return 0; // a large enough number
  1652 %}
  1654 //----------ENCODING BLOCK-----------------------------------------------------
  1655 // This block specifies the encoding classes used by the compiler to output
  1656 // byte streams.  Encoding classes generate functions which are called by
  1657 // Machine Instruction Nodes in order to generate the bit encoding of the
  1658 // instruction.  Operands specify their base encoding interface with the
  1659 // interface keyword.  There are currently supported four interfaces,
  1660 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
  1661 // operand to generate a function which returns its register number when
  1662 // queried.   CONST_INTER causes an operand to generate a function which
  1663 // returns the value of the constant when queried.  MEMORY_INTER causes an
  1664 // operand to generate four functions which return the Base Register, the
  1665 // Index Register, the Scale Value, and the Offset Value of the operand when
  1666 // queried.  COND_INTER causes an operand to generate six functions which
  1667 // return the encoding code (ie - encoding bits for the instruction)
  1668 // associated with each basic boolean condition for a conditional instruction.
  1669 // Instructions specify two basic values for encoding.  They use the
  1670 // ins_encode keyword to specify their encoding class (which must be one of
  1671 // the class names specified in the encoding block), and they use the
  1672 // opcode keyword to specify, in order, their primary, secondary, and
  1673 // tertiary opcode.  Only the opcode sections which a particular instruction
  1674 // needs for encoding need to be specified.
  1675 encode %{
  1677   //Load byte signed
  1678   enc_class load_B_enc (mRegI dst, memory mem) %{
  1679     MacroAssembler _masm(&cbuf);
  1680     int  dst = $dst$$reg;
  1681     int  base = $mem$$base;
  1682     int  index = $mem$$index;
  1683     int  scale = $mem$$scale;
  1684     int  disp = $mem$$disp;
  1686     if( index != 0 ) {
  1687       if( Assembler::is_simm16(disp) ) {
  1688         if( UseLoongsonISA ) {
  1689           if (scale == 0) {
  1690             __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
  1691           } else {
  1692             __ dsll(AT, as_Register(index), scale);
  1693             __ gslbx(as_Register(dst), as_Register(base), AT, disp);
  1695         } else {
  1696           if (scale == 0) {
  1697             __ addu(AT, as_Register(base), as_Register(index));
  1698           } else {
  1699             __ dsll(AT, as_Register(index), scale);
  1700             __ addu(AT, as_Register(base), AT);
  1702           __ lb(as_Register(dst), AT, disp);
  1704       } else {
  1705         if (scale == 0) {
  1706           __ addu(AT, as_Register(base), as_Register(index));
  1707         } else {
  1708           __ dsll(AT, as_Register(index), scale);
  1709           __ addu(AT, as_Register(base), AT);
  1711         __ move(T9, disp);
  1712         if( UseLoongsonISA ) {
  1713           __ gslbx(as_Register(dst), AT, T9, 0);
  1714         } else {
  1715           __ addu(AT, AT, T9);
  1716           __ lb(as_Register(dst), AT, 0);
  1719     } else {
  1720       if( Assembler::is_simm16(disp) ) {
  1721         __ lb(as_Register(dst), as_Register(base), disp);
  1722       } else {
  1723         __ move(T9, disp);
  1724         if( UseLoongsonISA ) {
  1725           __ gslbx(as_Register(dst), as_Register(base), T9, 0);
  1726         } else {
  1727           __ addu(AT, as_Register(base), T9);
  1728           __ lb(as_Register(dst), AT, 0);
  1732   %}
  1734   //Load byte unsigned
  1735   enc_class load_UB_enc (mRegI dst, memory mem) %{
  1736     MacroAssembler _masm(&cbuf);
  1737     int  dst = $dst$$reg;
  1738     int  base = $mem$$base;
  1739     int  index = $mem$$index;
  1740     int  scale = $mem$$scale;
  1741     int  disp = $mem$$disp;
  1743     if( index != 0 ) {
  1744       if (scale == 0) {
  1745         __ daddu(AT, as_Register(base), as_Register(index));
  1746       } else {
  1747         __ dsll(AT, as_Register(index), scale);
  1748         __ daddu(AT, as_Register(base), AT);
  1750       if( Assembler::is_simm16(disp) ) {
  1751         __ lbu(as_Register(dst), AT, disp);
  1752       } else {
  1753         __ move(T9, disp);
  1754         __ daddu(AT, AT, T9);
  1755         __ lbu(as_Register(dst), AT, 0);
  1757     } else {
  1758       if( Assembler::is_simm16(disp) ) {
  1759         __ lbu(as_Register(dst), as_Register(base), disp);
  1760       } else {
  1761         __ move(T9, disp);
  1762         __ daddu(AT, as_Register(base), T9);
  1763         __ lbu(as_Register(dst), AT, 0);
  1766   %}
  1768   enc_class store_B_reg_enc (memory mem, mRegI src) %{
  1769     MacroAssembler _masm(&cbuf);
  1770     int  src = $src$$reg;
  1771     int  base = $mem$$base;
  1772     int  index = $mem$$index;
  1773     int  scale = $mem$$scale;
  1774     int  disp = $mem$$disp;
  1776     if( index != 0 ) {
  1777       if (scale == 0) {
  1778         if( Assembler::is_simm(disp, 8) ) {
  1779           if (UseLoongsonISA) {
  1780             __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
  1781           } else {
  1782             __ addu(AT, as_Register(base), as_Register(index));
  1783             __ sb(as_Register(src), AT, disp);
  1785         } else if( Assembler::is_simm16(disp) ) {
  1786           __ addu(AT, as_Register(base), as_Register(index));
  1787           __ sb(as_Register(src), AT, disp);
  1788         } else {
  1789           __ addu(AT, as_Register(base), as_Register(index));
  1790           __ move(T9, disp);
  1791           if (UseLoongsonISA) {
  1792             __ gssbx(as_Register(src), AT, T9, 0);
  1793           } else {
  1794             __ addu(AT, AT, T9);
  1795             __ sb(as_Register(src), AT, 0);
  1798       } else {
  1799         __ dsll(AT, as_Register(index), scale);
  1800         if( Assembler::is_simm(disp, 8) ) {
  1801           if (UseLoongsonISA) {
  1802             __ gssbx(as_Register(src), AT, as_Register(base), disp);
  1803           } else {
  1804             __ addu(AT, as_Register(base), AT);
  1805             __ sb(as_Register(src), AT, disp);
  1807         } else if( Assembler::is_simm16(disp) ) {
  1808           __ addu(AT, as_Register(base), AT);
  1809           __ sb(as_Register(src), AT, disp);
  1810         } else {
  1811           __ addu(AT, as_Register(base), AT);
  1812           __ move(T9, disp);
  1813           if (UseLoongsonISA) {
  1814             __ gssbx(as_Register(src), AT, T9, 0);
  1815           } else {
  1816             __ addu(AT, AT, T9);
  1817             __ sb(as_Register(src), AT, 0);
  1821     } else {
  1822       if( Assembler::is_simm16(disp) ) {
  1823         __ sb(as_Register(src), as_Register(base), disp);
  1824       } else {
  1825         __ move(T9, disp);
  1826         if (UseLoongsonISA) {
  1827           __ gssbx(as_Register(src), as_Register(base), T9, 0);
  1828         } else {
  1829           __ addu(AT, as_Register(base), T9);
  1830           __ sb(as_Register(src), AT, 0);
  1834   %}
  1836   enc_class store_B_immI_enc (memory mem, immI8 src) %{
  1837     MacroAssembler _masm(&cbuf);
  1838     int  base = $mem$$base;
  1839     int  index = $mem$$index;
  1840     int  scale = $mem$$scale;
  1841     int  disp = $mem$$disp;
  1842     int value = $src$$constant;
  1844     if( index != 0 ) {
  1845       if (!UseLoongsonISA) {
  1846         if (scale == 0) {
  1847           __ daddu(AT, as_Register(base), as_Register(index));
  1848         } else {
  1849           __ dsll(AT, as_Register(index), scale);
  1850           __ daddu(AT, as_Register(base), AT);
  1852         if( Assembler::is_simm16(disp) ) {
  1853           if (value == 0) {
  1854             __ sb(R0, AT, disp);
  1855           } else {
  1856             __ move(T9, value);
  1857             __ sb(T9, AT, disp);
  1859         } else {
  1860           if (value == 0) {
  1861             __ move(T9, disp);
  1862             __ daddu(AT, AT, T9);
  1863             __ sb(R0, AT, 0);
  1864           } else {
  1865             __ move(T9, disp);
  1866             __ daddu(AT, AT, T9);
  1867             __ move(T9, value);
  1868             __ sb(T9, AT, 0);
  1871       } else {
  1873         if (scale == 0) {
  1874           if( Assembler::is_simm(disp, 8) ) {
  1875             if (value == 0) {
  1876               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1877             } else {
  1878               __ move(T9, value);
  1879               __ gssbx(T9, as_Register(base), as_Register(index), disp);
  1881           } else if( Assembler::is_simm16(disp) ) {
  1882             __ daddu(AT, as_Register(base), as_Register(index));
  1883             if (value == 0) {
  1884               __ sb(R0, AT, disp);
  1885             } else {
  1886               __ move(T9, value);
  1887               __ sb(T9, AT, disp);
  1889           } else {
  1890             if (value == 0) {
  1891               __ daddu(AT, as_Register(base), as_Register(index));
  1892               __ move(T9, disp);
  1893               __ gssbx(R0, AT, T9, 0);
  1894             } else {
  1895               __ move(AT, disp);
  1896               __ move(T9, value);
  1897               __ daddu(AT, as_Register(base), AT);
  1898               __ gssbx(T9, AT, as_Register(index), 0);
  1902         } else {
  1904           if( Assembler::is_simm(disp, 8) ) {
  1905             __ dsll(AT, as_Register(index), scale);
  1906             if (value == 0) {
  1907               __ gssbx(R0, as_Register(base), AT, disp);
  1908             } else {
  1909               __ move(T9, value);
  1910               __ gssbx(T9, as_Register(base), AT, disp);
  1912           } else if( Assembler::is_simm16(disp) ) {
  1913             __ dsll(AT, as_Register(index), scale);
  1914             __ daddu(AT, as_Register(base), AT);
  1915             if (value == 0) {
  1916               __ sb(R0, AT, disp);
  1917             } else {
  1918               __ move(T9, value);
  1919               __ sb(T9, AT, disp);
  1921           } else {
  1922             __ dsll(AT, as_Register(index), scale);
  1923             if (value == 0) {
  1924               __ daddu(AT, as_Register(base), AT);
  1925               __ move(T9, disp);
  1926               __ gssbx(R0, AT, T9, 0);
  1927             } else {
  1928               __ move(T9, disp);
  1929               __ daddu(AT, AT, T9);
  1930               __ move(T9, value);
  1931               __ gssbx(T9, as_Register(base), AT, 0);
  1936     } else {
  1937       if( Assembler::is_simm16(disp) ) {
  1938         if (value == 0) {
  1939           __ sb(R0, as_Register(base), disp);
  1940         } else {
  1941           __ move(AT, value);
  1942           __ sb(AT, as_Register(base), disp);
  1944       } else {
  1945         if (value == 0) {
  1946           __ move(T9, disp);
  1947           if (UseLoongsonISA) {
  1948             __ gssbx(R0, as_Register(base), T9, 0);
  1949           } else {
  1950             __ daddu(AT, as_Register(base), T9);
  1951             __ sb(R0, AT, 0);
  1953         } else {
  1954           __ move(T9, disp);
  1955           if (UseLoongsonISA) {
  1956             __ move(AT, value);
  1957             __ gssbx(AT, as_Register(base), T9, 0);
  1958           } else {
  1959             __ daddu(AT, as_Register(base), T9);
  1960             __ move(T9, value);
  1961             __ sb(T9, AT, 0);
  1966   %}
  1969   enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
  1970     MacroAssembler _masm(&cbuf);
  1971     int  base = $mem$$base;
  1972     int  index = $mem$$index;
  1973     int  scale = $mem$$scale;
  1974     int  disp = $mem$$disp;
  1975     int value = $src$$constant;
  1977     if( index != 0 ) {
  1978       if ( UseLoongsonISA ) {
  1979         if ( Assembler::is_simm(disp,8) ) {
  1980           if ( scale == 0 ) {
  1981             if ( value == 0 ) {
  1982               __ gssbx(R0, as_Register(base), as_Register(index), disp);
  1983             } else {
  1984               __ move(AT, value);
  1985               __ gssbx(AT, as_Register(base), as_Register(index), disp);
  1987           } else {
  1988             __ dsll(AT, as_Register(index), scale);
  1989             if ( value == 0 ) {
  1990               __ gssbx(R0, as_Register(base), AT, disp);
  1991             } else {
  1992               __ move(T9, value);
  1993               __ gssbx(T9, as_Register(base), AT, disp);
  1996         } else if ( Assembler::is_simm16(disp) ) {
  1997           if ( scale == 0 ) {
  1998             __ daddu(AT, as_Register(base), as_Register(index));
  1999             if ( value == 0 ){
  2000               __ sb(R0, AT, disp);
  2001             } else {
  2002               __ move(T9, value);
  2003               __ sb(T9, AT, disp);
  2005           } else {
  2006             __ dsll(AT, as_Register(index), scale);
  2007             __ daddu(AT, as_Register(base), AT);
  2008             if ( value == 0 ) {
  2009               __ sb(R0, AT, disp);
  2010             } else {
  2011               __ move(T9, value);
  2012               __ sb(T9, AT, disp);
  2015         } else {
  2016           if ( scale == 0 ) {
  2017             __ move(AT, disp);
  2018             __ daddu(AT, as_Register(index), AT);
  2019             if ( value == 0 ) {
  2020               __ gssbx(R0, as_Register(base), AT, 0);
  2021             } else {
  2022               __ move(T9, value);
  2023               __ gssbx(T9, as_Register(base), AT, 0);
  2025           } else {
  2026             __ dsll(AT, as_Register(index), scale);
  2027             __ move(T9, disp);
  2028             __ daddu(AT, AT, T9);
  2029             if ( value == 0 ) {
  2030               __ gssbx(R0, as_Register(base), AT, 0);
  2031             } else {
  2032               __ move(T9, value);
  2033               __ gssbx(T9, as_Register(base), AT, 0);
  2037       } else { //not use loongson isa
  2038         if (scale == 0) {
  2039           __ daddu(AT, as_Register(base), as_Register(index));
  2040         } else {
  2041           __ dsll(AT, as_Register(index), scale);
  2042           __ daddu(AT, as_Register(base), AT);
  2044         if( Assembler::is_simm16(disp) ) {
  2045           if (value == 0) {
  2046             __ sb(R0, AT, disp);
  2047           } else {
  2048             __ move(T9, value);
  2049             __ sb(T9, AT, disp);
  2051         } else {
  2052           if (value == 0) {
  2053             __ move(T9, disp);
  2054             __ daddu(AT, AT, T9);
  2055             __ sb(R0, AT, 0);
  2056           } else {
  2057             __ move(T9, disp);
  2058             __ daddu(AT, AT, T9);
  2059             __ move(T9, value);
  2060             __ sb(T9, AT, 0);
  2064     } else {
  2065       if ( UseLoongsonISA ){
  2066         if ( Assembler::is_simm16(disp) ){
  2067           if ( value == 0 ) {
  2068             __ sb(R0, as_Register(base), disp);
  2069           } else {
  2070             __ move(AT, value);
  2071             __ sb(AT, as_Register(base), disp);
  2073         } else {
  2074           __ move(AT, disp);
  2075           if ( value == 0 ) {
  2076             __ gssbx(R0, as_Register(base), AT, 0);
  2077           } else {
  2078             __ move(T9, value);
  2079             __ gssbx(T9, as_Register(base), AT, 0);
  2082       } else {
  2083         if( Assembler::is_simm16(disp) ) {
  2084           if (value == 0) {
  2085             __ sb(R0, as_Register(base), disp);
  2086           } else {
  2087             __ move(AT, value);
  2088             __ sb(AT, as_Register(base), disp);
  2090         } else {
  2091           if (value == 0) {
  2092             __ move(T9, disp);
  2093             __ daddu(AT, as_Register(base), T9);
  2094             __ sb(R0, AT, 0);
  2095           } else {
  2096             __ move(T9, disp);
  2097             __ daddu(AT, as_Register(base), T9);
  2098             __ move(T9, value);
  2099             __ sb(T9, AT, 0);
  2105     __ sync();
  2106   %}
  2108   // Load Short (16bit signed)
  2109   enc_class load_S_enc (mRegI dst, memory mem) %{
  2110     MacroAssembler _masm(&cbuf);
  2111     int  dst = $dst$$reg;
  2112     int  base = $mem$$base;
  2113     int  index = $mem$$index;
  2114     int  scale = $mem$$scale;
  2115     int  disp = $mem$$disp;
  2117     if( index != 0 ) {
  2118       if ( UseLoongsonISA ) {
  2119         if ( Assembler::is_simm(disp, 8) ) {
  2120           if (scale == 0) {
  2121             __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2122           } else {
  2123             __ dsll(AT, as_Register(index), scale);
  2124             __ gslhx(as_Register(dst), as_Register(base), AT, disp);
  2126         } else if ( Assembler::is_simm16(disp) ) {
  2127           if (scale == 0) {
  2128             __ daddu(AT, as_Register(base), as_Register(index));
  2129             __ lh(as_Register(dst), AT, disp);
  2130           } else {
  2131             __ dsll(AT, as_Register(index), scale);
  2132             __ daddu(AT, as_Register(base), AT);
  2133             __ lh(as_Register(dst), AT, disp);
  2135         } else {
  2136           if (scale == 0) {
  2137             __ move(AT, disp);
  2138             __ daddu(AT, as_Register(index), AT);
  2139             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2140           } else {
  2141             __ dsll(AT, as_Register(index), scale);
  2142             __ move(T9, disp);
  2143             __ daddu(AT, AT, T9);
  2144             __ gslhx(as_Register(dst), as_Register(base), AT, 0);
  2147       } else { // not use loongson isa
  2148         if (scale == 0) {
  2149           __ daddu(AT, as_Register(base), as_Register(index));
  2150         } else {
  2151           __ dsll(AT, as_Register(index), scale);
  2152           __ daddu(AT, as_Register(base), AT);
  2154         if( Assembler::is_simm16(disp) ) {
  2155           __ lh(as_Register(dst), AT, disp);
  2156         } else {
  2157           __ move(T9, disp);
  2158           __ daddu(AT, AT, T9);
  2159           __ lh(as_Register(dst), AT, 0);
  2162     } else { // index is 0
  2163       if ( UseLoongsonISA ) {
  2164         if ( Assembler::is_simm16(disp) ) {
  2165           __ lh(as_Register(dst), as_Register(base), disp);
  2166         } else {
  2167           __ move(T9, disp);
  2168           __ gslhx(as_Register(dst), as_Register(base), T9, 0);
  2170       } else { //not use loongson isa
  2171         if( Assembler::is_simm16(disp) ) {
  2172           __ lh(as_Register(dst), as_Register(base), disp);
  2173         } else {
  2174           __ move(T9, disp);
  2175           __ daddu(AT, as_Register(base), T9);
  2176           __ lh(as_Register(dst), AT, 0);
  2180   %}
  2182   // Load Char (16bit unsigned)
  2183   enc_class load_C_enc (mRegI dst, memory mem) %{
  2184     MacroAssembler _masm(&cbuf);
  2185     int  dst = $dst$$reg;
  2186     int  base = $mem$$base;
  2187     int  index = $mem$$index;
  2188     int  scale = $mem$$scale;
  2189     int  disp = $mem$$disp;
  2191     if( index != 0 ) {
  2192       if (scale == 0) {
  2193         __ daddu(AT, as_Register(base), as_Register(index));
  2194       } else {
  2195         __ dsll(AT, as_Register(index), scale);
  2196         __ daddu(AT, as_Register(base), AT);
  2198       if( Assembler::is_simm16(disp) ) {
  2199         __ lhu(as_Register(dst), AT, disp);
  2200       } else {
  2201         __ move(T9, disp);
  2202         __ addu(AT, AT, T9);
  2203         __ lhu(as_Register(dst), AT, 0);
  2205     } else {
  2206       if( Assembler::is_simm16(disp) ) {
  2207         __ lhu(as_Register(dst), as_Register(base), disp);
  2208       } else {
  2209         __ move(T9, disp);
  2210         __ daddu(AT, as_Register(base), T9);
  2211         __ lhu(as_Register(dst), AT, 0);
  2214   %}
  2216   // Store Char (16bit unsigned)
  2217   enc_class store_C_reg_enc (memory mem, mRegI src) %{
  2218     MacroAssembler _masm(&cbuf);
  2219     int  src = $src$$reg;
  2220     int  base = $mem$$base;
  2221     int  index = $mem$$index;
  2222     int  scale = $mem$$scale;
  2223     int  disp = $mem$$disp;
  2225     if( index != 0 ) {
  2226       if( Assembler::is_simm16(disp) ) {
  2227         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2228           if (scale == 0) {
  2229             __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
  2230           } else {
  2231             __ dsll(AT, as_Register(index), scale);
  2232             __ gsshx(as_Register(src), as_Register(base), AT, disp);
  2234         } else {
  2235           if (scale == 0) {
  2236             __ addu(AT, as_Register(base), as_Register(index));
  2237           } else {
  2238             __ dsll(AT, as_Register(index), scale);
  2239             __ addu(AT, as_Register(base), AT);
  2241           __ sh(as_Register(src), AT, disp);
  2243       } else {
  2244         if (scale == 0) {
  2245           __ addu(AT, as_Register(base), as_Register(index));
  2246         } else {
  2247           __ dsll(AT, as_Register(index), scale);
  2248           __ addu(AT, as_Register(base), AT);
  2250         __ move(T9, disp);
  2251         if( UseLoongsonISA ) {
  2252           __ gsshx(as_Register(src), AT, T9, 0);
  2253         } else {
  2254           __ addu(AT, AT, T9);
  2255           __ sh(as_Register(src), AT, 0);
  2258     } else {
  2259       if( Assembler::is_simm16(disp) ) {
  2260         __ sh(as_Register(src), as_Register(base), disp);
  2261       } else {
  2262         __ move(T9, disp);
  2263         if( UseLoongsonISA ) {
  2264           __ gsshx(as_Register(src), as_Register(base), T9, 0);
  2265         } else {
  2266           __ addu(AT, as_Register(base), T9);
  2267           __ sh(as_Register(src), AT, 0);
  2271   %}
  2273   enc_class store_C0_enc (memory mem) %{
  2274     MacroAssembler _masm(&cbuf);
  2275     int  base = $mem$$base;
  2276     int  index = $mem$$index;
  2277     int  scale = $mem$$scale;
  2278     int  disp = $mem$$disp;
  2280     if( index != 0 ) {
  2281       if( Assembler::is_simm16(disp) ) {
  2282         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2283           if (scale == 0) {
  2284             __ gsshx(R0, as_Register(base), as_Register(index), disp);
  2285           } else {
  2286             __ dsll(AT, as_Register(index), scale);
  2287             __ gsshx(R0, as_Register(base), AT, disp);
  2289         } else {
  2290           if (scale == 0) {
  2291             __ addu(AT, as_Register(base), as_Register(index));
  2292           } else {
  2293             __ dsll(AT, as_Register(index), scale);
  2294             __ addu(AT, as_Register(base), AT);
  2296           __ sh(R0, AT, disp);
  2298       } else {
  2299         if (scale == 0) {
  2300           __ addu(AT, as_Register(base), as_Register(index));
  2301         } else {
  2302           __ dsll(AT, as_Register(index), scale);
  2303           __ addu(AT, as_Register(base), AT);
  2305         __ move(T9, disp);
  2306         if( UseLoongsonISA ) {
  2307           __ gsshx(R0, AT, T9, 0);
  2308         } else {
  2309           __ addu(AT, AT, T9);
  2310           __ sh(R0, AT, 0);
  2313     } else {
  2314       if( Assembler::is_simm16(disp) ) {
  2315         __ sh(R0, as_Register(base), disp);
  2316       } else {
  2317         __ move(T9, disp);
  2318         if( UseLoongsonISA ) {
  2319           __ gsshx(R0, as_Register(base), T9, 0);
  2320         } else {
  2321           __ addu(AT, as_Register(base), T9);
  2322           __ sh(R0, AT, 0);
  2326   %}
  2328   enc_class load_I_enc (mRegI dst, memory mem) %{
  2329     MacroAssembler _masm(&cbuf);
  2330     int  dst = $dst$$reg;
  2331     int  base = $mem$$base;
  2332     int  index = $mem$$index;
  2333     int  scale = $mem$$scale;
  2334     int  disp = $mem$$disp;
  2336     if( index != 0 ) {
  2337       if( Assembler::is_simm16(disp) ) {
  2338         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2339           if (scale == 0) {
  2340             __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2341           } else {
  2342             __ dsll(AT, as_Register(index), scale);
  2343             __ gslwx(as_Register(dst), as_Register(base), AT, disp);
  2345         } else {
  2346           if (scale == 0) {
  2347             __ addu(AT, as_Register(base), as_Register(index));
  2348           } else {
  2349             __ dsll(AT, as_Register(index), scale);
  2350             __ addu(AT, as_Register(base), AT);
  2352           __ lw(as_Register(dst), AT, disp);
  2354       } else {
  2355         if (scale == 0) {
  2356           __ addu(AT, as_Register(base), as_Register(index));
  2357         } else {
  2358           __ dsll(AT, as_Register(index), scale);
  2359           __ addu(AT, as_Register(base), AT);
  2361         __ move(T9, disp);
  2362         if( UseLoongsonISA ) {
  2363           __ gslwx(as_Register(dst), AT, T9, 0);
  2364         } else {
  2365           __ addu(AT, AT, T9);
  2366           __ lw(as_Register(dst), AT, 0);
  2369     } else {
  2370       if( Assembler::is_simm16(disp) ) {
  2371         __ lw(as_Register(dst), as_Register(base), disp);
  2372       } else {
  2373         __ move(T9, disp);
  2374         if( UseLoongsonISA ) {
  2375           __ gslwx(as_Register(dst), as_Register(base), T9, 0);
  2376         } else {
  2377           __ addu(AT, as_Register(base), T9);
  2378           __ lw(as_Register(dst), AT, 0);
  2382   %}
  2384   enc_class store_I_reg_enc (memory mem, mRegI src) %{
  2385     MacroAssembler _masm(&cbuf);
  2386     int  src = $src$$reg;
  2387     int  base = $mem$$base;
  2388     int  index = $mem$$index;
  2389     int  scale = $mem$$scale;
  2390     int  disp = $mem$$disp;
  2392     if( index != 0 ) {
  2393       if( Assembler::is_simm16(disp) ) {
  2394         if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
  2395           if (scale == 0) {
  2396             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2397           } else {
  2398             __ dsll(AT, as_Register(index), scale);
  2399             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2401         } else {
  2402           if (scale == 0) {
  2403             __ addu(AT, as_Register(base), as_Register(index));
  2404           } else {
  2405             __ dsll(AT, as_Register(index), scale);
  2406             __ addu(AT, as_Register(base), AT);
  2408           __ sw(as_Register(src), AT, disp);
  2410       } else {
  2411         if (scale == 0) {
  2412           __ addu(AT, as_Register(base), as_Register(index));
  2413         } else {
  2414           __ dsll(AT, as_Register(index), scale);
  2415           __ addu(AT, as_Register(base), AT);
  2417         __ move(T9, disp);
  2418         if( UseLoongsonISA ) {
  2419           __ gsswx(as_Register(src), AT, T9, 0);
  2420         } else {
  2421           __ addu(AT, AT, T9);
  2422           __ sw(as_Register(src), AT, 0);
  2425     } else {
  2426       if( Assembler::is_simm16(disp) ) {
  2427         __ sw(as_Register(src), as_Register(base), disp);
  2428       } else {
  2429         __ move(T9, disp);
  2430         if( UseLoongsonISA ) {
  2431           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2432         } else {
  2433           __ addu(AT, as_Register(base), T9);
  2434           __ sw(as_Register(src), AT, 0);
  2438   %}
  2440   enc_class store_I_immI_enc (memory mem, immI src) %{
  2441     MacroAssembler _masm(&cbuf);
  2442     int  base = $mem$$base;
  2443     int  index = $mem$$index;
  2444     int  scale = $mem$$scale;
  2445     int  disp = $mem$$disp;
  2446     int value = $src$$constant;
  2448     if( index != 0 ) {
  2449       if ( UseLoongsonISA ) {
  2450         if ( Assembler::is_simm(disp, 8) ) {
  2451           if ( scale == 0 ) {
  2452             if ( value == 0 ) {
  2453               __ gsswx(R0, as_Register(base), as_Register(index), disp);
  2454             } else {
  2455               __ move(T9, value);
  2456               __ gsswx(T9, as_Register(base), as_Register(index), disp);
  2458           } else {
  2459             __ dsll(AT, as_Register(index), scale);
  2460             if ( value == 0 ) {
  2461               __ gsswx(R0, as_Register(base), AT, disp);
  2462             } else {
  2463               __ move(T9, value);
  2464               __ gsswx(T9, as_Register(base), AT, disp);
  2467         } else if ( Assembler::is_simm16(disp) ) {
  2468           if ( scale == 0 ) {
  2469             __ daddu(AT, as_Register(base), as_Register(index));
  2470             if ( value == 0 ) {
  2471               __ sw(R0, AT, disp);
  2472             } else {
  2473               __ move(T9, value);
  2474               __ sw(T9, AT, disp);
  2476           } else {
  2477             __ dsll(AT, as_Register(index), scale);
  2478             __ daddu(AT, as_Register(base), AT);
  2479             if ( value == 0 ) {
  2480               __ sw(R0, AT, disp);
  2481             } else {
  2482               __ move(T9, value);
  2483               __ sw(T9, AT, disp);
  2486         } else {
  2487           if ( scale == 0 ) {
  2488             __ move(T9, disp);
  2489             __ daddu(AT, as_Register(index), T9);
  2490             if ( value ==0 ) {
  2491               __ gsswx(R0, as_Register(base), AT, 0);
  2492             } else {
  2493               __ move(T9, value);
  2494               __ gsswx(T9, as_Register(base), AT, 0);
  2496           } else {
  2497             __ dsll(AT, as_Register(index), scale);
  2498             __ move(T9, disp);
  2499             __ daddu(AT, AT, T9);
  2500             if ( value == 0 ) {
  2501               __ gsswx(R0, as_Register(base), AT, 0);
  2502             } else {
  2503               __ move(T9, value);
  2504               __ gsswx(T9, as_Register(base), AT, 0);
  2508       } else { //not use loongson isa
  2509         if (scale == 0) {
  2510           __ daddu(AT, as_Register(base), as_Register(index));
  2511         } else {
  2512           __ dsll(AT, as_Register(index), scale);
  2513           __ daddu(AT, as_Register(base), AT);
  2515         if( Assembler::is_simm16(disp) ) {
  2516           if (value == 0) {
  2517             __ sw(R0, AT, disp);
  2518           } else {
  2519             __ move(T9, value);
  2520             __ sw(T9, AT, disp);
  2522         } else {
  2523           if (value == 0) {
  2524             __ move(T9, disp);
  2525             __ daddu(AT, AT, T9);
  2526             __ sw(R0, AT, 0);
  2527           } else {
  2528             __ move(T9, disp);
  2529             __ daddu(AT, AT, T9);
  2530             __ move(T9, value);
  2531             __ sw(T9, AT, 0);
  2535     } else {
  2536       if ( UseLoongsonISA ) {
  2537         if ( Assembler::is_simm16(disp) ) {
  2538           if ( value == 0 ) {
  2539             __ sw(R0, as_Register(base), disp);
  2540           } else {
  2541             __ move(AT, value);
  2542             __ sw(AT, as_Register(base), disp);
  2544         } else {
  2545           __ move(T9, disp);
  2546           if ( value == 0 ) {
  2547             __ gsswx(R0, as_Register(base), T9, 0);
  2548           } else {
  2549             __ move(AT, value);
  2550             __ gsswx(AT, as_Register(base), T9, 0);
  2553       } else {
  2554         if( Assembler::is_simm16(disp) ) {
  2555           if (value == 0) {
  2556             __ sw(R0, as_Register(base), disp);
  2557           } else {
  2558             __ move(AT, value);
  2559             __ sw(AT, as_Register(base), disp);
  2561         } else {
  2562           if (value == 0) {
  2563             __ move(T9, disp);
  2564             __ daddu(AT, as_Register(base), T9);
  2565             __ sw(R0, AT, 0);
  2566           } else {
  2567             __ move(T9, disp);
  2568             __ daddu(AT, as_Register(base), T9);
  2569             __ move(T9, value);
  2570             __ sw(T9, AT, 0);
  2575   %}
  2577   enc_class load_N_enc (mRegN dst, memory mem) %{
  2578     MacroAssembler _masm(&cbuf);
  2579     int  dst = $dst$$reg;
  2580     int  base = $mem$$base;
  2581     int  index = $mem$$index;
  2582     int  scale = $mem$$scale;
  2583     int  disp = $mem$$disp;
  2584     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2585     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2587     if( index != 0 ) {
  2588       if (scale == 0) {
  2589         __ daddu(AT, as_Register(base), as_Register(index));
  2590       } else {
  2591         __ dsll(AT, as_Register(index), scale);
  2592         __ daddu(AT, as_Register(base), AT);
  2594       if( Assembler::is_simm16(disp) ) {
  2595         __ lwu(as_Register(dst), AT, disp);
  2596       } else {
  2597         __ set64(T9, disp);
  2598         __ daddu(AT, AT, T9);
  2599         __ lwu(as_Register(dst), AT, 0);
  2601     } else {
  2602       if( Assembler::is_simm16(disp) ) {
  2603         __ lwu(as_Register(dst), as_Register(base), disp);
  2604       } else {
  2605         __ set64(T9, disp);
  2606         __ daddu(AT, as_Register(base), T9);
  2607         __ lwu(as_Register(dst), AT, 0);
  2610   %}
  2613   enc_class load_P_enc (mRegP dst, memory mem) %{
  2614     MacroAssembler _masm(&cbuf);
  2615     int  dst = $dst$$reg;
  2616     int  base = $mem$$base;
  2617     int  index = $mem$$index;
  2618     int  scale = $mem$$scale;
  2619     int  disp = $mem$$disp;
  2620     relocInfo::relocType disp_reloc = $mem->disp_reloc();
  2621     assert(disp_reloc == relocInfo::none, "cannot have disp");
  2623     if( index != 0 ) {
  2624       if ( UseLoongsonISA ) {
  2625         if ( Assembler::is_simm(disp, 8) ) {
  2626           if ( scale != 0 ) {
  2627             __ dsll(AT, as_Register(index), scale);
  2628             __ gsldx(as_Register(dst), as_Register(base), AT, disp);
  2629           } else {
  2630             __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
  2632         } else if ( Assembler::is_simm16(disp) ){
  2633           if ( scale != 0 ) {
  2634             __ dsll(AT, as_Register(index), scale);
  2635             __ daddu(AT, AT, as_Register(base));
  2636           } else {
  2637             __ daddu(AT, as_Register(index), as_Register(base));
  2639           __ ld(as_Register(dst), AT, disp);
  2640         } else {
  2641           if ( scale != 0 ) {
  2642             __ dsll(AT, as_Register(index), scale);
  2643             __ move(T9, disp);
  2644             __ daddu(AT, AT, T9);
  2645           } else {
  2646             __ move(T9, disp);
  2647             __ daddu(AT, as_Register(index), T9);
  2649           __ gsldx(as_Register(dst), as_Register(base), AT, 0);
  2651       } else { //not use loongson isa
  2652         if (scale == 0) {
  2653           __ daddu(AT, as_Register(base), as_Register(index));
  2654         } else {
  2655           __ dsll(AT, as_Register(index), scale);
  2656           __ daddu(AT, as_Register(base), AT);
  2658         if( Assembler::is_simm16(disp) ) {
  2659           __ ld(as_Register(dst), AT, disp);
  2660         } else {
  2661           __ set64(T9, disp);
  2662           __ daddu(AT, AT, T9);
  2663           __ ld(as_Register(dst), AT, 0);
  2666     } else {
  2667       if ( UseLoongsonISA ) {
  2668         if ( Assembler::is_simm16(disp) ){
  2669           __ ld(as_Register(dst), as_Register(base), disp);
  2670         } else {
  2671           __ set64(T9, disp);
  2672           __ gsldx(as_Register(dst), as_Register(base), T9, 0);
  2674       } else { //not use loongson isa
  2675         if( Assembler::is_simm16(disp) ) {
  2676           __ ld(as_Register(dst), as_Register(base), disp);
  2677         } else {
  2678           __ set64(T9, disp);
  2679           __ daddu(AT, as_Register(base), T9);
  2680           __ ld(as_Register(dst), AT, 0);
  2684   %}
  2686   enc_class store_P_reg_enc (memory mem, mRegP src) %{
  2687     MacroAssembler _masm(&cbuf);
  2688     int  src = $src$$reg;
  2689     int  base = $mem$$base;
  2690     int  index = $mem$$index;
  2691     int  scale = $mem$$scale;
  2692     int  disp = $mem$$disp;
  2694     if( index != 0 ) {
  2695       if ( UseLoongsonISA ){
  2696         if ( Assembler::is_simm(disp, 8) ) {
  2697           if ( scale == 0 ) {
  2698             __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
  2699           } else {
  2700             __ dsll(AT, as_Register(index), scale);
  2701             __ gssdx(as_Register(src), as_Register(base), AT, disp);
  2703         } else if ( Assembler::is_simm16(disp) ) {
  2704           if ( scale == 0 ) {
  2705             __ daddu(AT, as_Register(base), as_Register(index));
  2706           } else {
  2707             __ dsll(AT, as_Register(index), scale);
  2708             __ daddu(AT, as_Register(base), AT);
  2710           __ sd(as_Register(src), AT, disp);
  2711         } else {
  2712           if ( scale == 0 ) {
  2713             __ move(T9, disp);
  2714             __ daddu(AT, as_Register(index), T9);
  2715           } else {
  2716             __ dsll(AT, as_Register(index), scale);
  2717             __ move(T9, disp);
  2718             __ daddu(AT, AT, T9);
  2720           __ gssdx(as_Register(src), as_Register(base), AT, 0);
  2722       } else { //not use loongson isa
  2723         if (scale == 0) {
  2724           __ daddu(AT, as_Register(base), as_Register(index));
  2725         } else {
  2726           __ dsll(AT, as_Register(index), scale);
  2727           __ daddu(AT, as_Register(base), AT);
  2729         if( Assembler::is_simm16(disp) ) {
  2730           __ sd(as_Register(src), AT, disp);
  2731         } else {
  2732           __ move(T9, disp);
  2733           __ daddu(AT, AT, T9);
  2734           __ sd(as_Register(src), AT, 0);
  2737     } else {
  2738       if ( UseLoongsonISA ) {
  2739         if ( Assembler::is_simm16(disp) ) {
  2740           __ sd(as_Register(src), as_Register(base), disp);
  2741         } else {
  2742           __ move(T9, disp);
  2743           __ gssdx(as_Register(src), as_Register(base), T9, 0);
  2745       } else {
  2746         if( Assembler::is_simm16(disp) ) {
  2747           __ sd(as_Register(src), as_Register(base), disp);
  2748         } else {
  2749           __ move(T9, disp);
  2750           __ daddu(AT, as_Register(base), T9);
  2751           __ sd(as_Register(src), AT, 0);
  2755   %}
  2757   enc_class store_N_reg_enc (memory mem, mRegN src) %{
  2758     MacroAssembler _masm(&cbuf);
  2759     int  src = $src$$reg;
  2760     int  base = $mem$$base;
  2761     int  index = $mem$$index;
  2762     int  scale = $mem$$scale;
  2763     int  disp = $mem$$disp;
  2765     if( index != 0 ) {
  2766       if ( UseLoongsonISA ){
  2767         if ( Assembler::is_simm(disp, 8) ) {
  2768           if ( scale == 0 ) {
  2769             __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
  2770           } else {
  2771             __ dsll(AT, as_Register(index), scale);
  2772             __ gsswx(as_Register(src), as_Register(base), AT, disp);
  2774         } else if ( Assembler::is_simm16(disp) ) {
  2775           if ( scale == 0 ) {
  2776             __ daddu(AT, as_Register(base), as_Register(index));
  2777           } else {
  2778             __ dsll(AT, as_Register(index), scale);
  2779             __ daddu(AT, as_Register(base), AT);
  2781           __ sw(as_Register(src), AT, disp);
  2782         } else {
  2783           if ( scale == 0 ) {
  2784             __ move(T9, disp);
  2785             __ daddu(AT, as_Register(index), T9);
  2786           } else {
  2787             __ dsll(AT, as_Register(index), scale);
  2788             __ move(T9, disp);
  2789             __ daddu(AT, AT, T9);
  2791           __ gsswx(as_Register(src), as_Register(base), AT, 0);
  2793       } else { //not use loongson isa
  2794         if (scale == 0) {
  2795           __ daddu(AT, as_Register(base), as_Register(index));
  2796         } else {
  2797           __ dsll(AT, as_Register(index), scale);
  2798           __ daddu(AT, as_Register(base), AT);
  2800         if( Assembler::is_simm16(disp) ) {
  2801           __ sw(as_Register(src), AT, disp);
  2802         } else {
  2803           __ move(T9, disp);
  2804           __ daddu(AT, AT, T9);
  2805           __ sw(as_Register(src), AT, 0);
  2808     } else {
  2809       if ( UseLoongsonISA ) {
  2810         if ( Assembler::is_simm16(disp) ) {
  2811           __ sw(as_Register(src), as_Register(base), disp);
  2812         } else {
  2813           __ move(T9, disp);
  2814           __ gsswx(as_Register(src), as_Register(base), T9, 0);
  2816       } else {
  2817         if( Assembler::is_simm16(disp) ) {
  2818           __ sw(as_Register(src), as_Register(base), disp);
  2819         } else {
  2820           __ move(T9, disp);
  2821           __ daddu(AT, as_Register(base), T9);
  2822           __ sw(as_Register(src), AT, 0);
  2826   %}
  2828   enc_class store_P_immP0_enc (memory mem) %{
  2829     MacroAssembler _masm(&cbuf);
  2830     int  base = $mem$$base;
  2831     int  index = $mem$$index;
  2832     int  scale = $mem$$scale;
  2833     int  disp = $mem$$disp;
  2835     if( index != 0 ) {
  2836       if (scale == 0) {
  2837         if( Assembler::is_simm16(disp) ) {
  2838           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2839             __ gssdx(R0, as_Register(base), as_Register(index), disp);
  2840           } else {
  2841             __ daddu(AT, as_Register(base), as_Register(index));
  2842             __ sd(R0, AT, disp);
  2844         } else {
  2845           __ daddu(AT, as_Register(base), as_Register(index));
  2846           __ move(T9, disp);
  2847           if(UseLoongsonISA) {
  2848             __ gssdx(R0, AT, T9, 0);
  2849           } else {
  2850             __ daddu(AT, AT, T9);
  2851             __ sd(R0, AT, 0);
  2854       } else {
  2855         __ dsll(AT, as_Register(index), scale);
  2856         if( Assembler::is_simm16(disp) ) {
  2857           if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
  2858             __ gssdx(R0, as_Register(base), AT, disp);
  2859           } else {
  2860             __ daddu(AT, as_Register(base), AT);
  2861             __ sd(R0, AT, disp);
  2863         } else {
  2864           __ daddu(AT, as_Register(base), AT);
  2865           __ move(T9, disp);
  2866           if (UseLoongsonISA) {
  2867             __ gssdx(R0, AT, T9, 0);
  2868           } else {
  2869             __ daddu(AT, AT, T9);
  2870             __ sd(R0, AT, 0);
  2874     } else {
  2875       if( Assembler::is_simm16(disp) ) {
  2876         __ sd(R0, as_Register(base), disp);
  2877       } else {
  2878         __ move(T9, disp);
  2879         if (UseLoongsonISA) {
  2880           __ gssdx(R0, as_Register(base), T9, 0);
  2881         } else {
  2882           __ daddu(AT, as_Register(base), T9);
  2883           __ sd(R0, AT, 0);
  2887   %}
  2889   enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
  2890     MacroAssembler _masm(&cbuf);
  2891     int  base = $mem$$base;
  2892     int  index = $mem$$index;
  2893     int  scale = $mem$$scale;
  2894     int  disp = $mem$$disp;
  2896     if(index!=0){
  2897       if (scale == 0) {
  2898         __ daddu(AT, as_Register(base), as_Register(index));
  2899       } else {
  2900         __ dsll(AT, as_Register(index), scale);
  2901         __ daddu(AT, as_Register(base), AT);
  2904       if( Assembler::is_simm16(disp) ) {
  2905         __ sw(R0, AT, disp);
  2906       } else {
  2907         __ move(T9, disp);
  2908         __ daddu(AT, AT, T9);
  2909         __ sw(R0, AT, 0);
  2911     } else {
  2912       if( Assembler::is_simm16(disp) ) {
  2913         __ sw(R0, as_Register(base), disp);
  2914       } else {
  2915         __ move(T9, disp);
  2916         __ daddu(AT, as_Register(base), T9);
  2917         __ sw(R0, AT, 0);
  2920   %}
  2922   enc_class load_L_enc (mRegL dst, memory mem) %{
  2923     MacroAssembler _masm(&cbuf);
  2924     int  base = $mem$$base;
  2925     int  index = $mem$$index;
  2926     int  scale = $mem$$scale;
  2927     int  disp = $mem$$disp;
  2928     Register  dst_reg = as_Register($dst$$reg);
  2930     // For implicit null check
  2931     __ lb(AT, as_Register(base), 0);
  2933     if( index != 0 ) {
  2934       if (scale == 0) {
  2935         __ daddu(AT, as_Register(base), as_Register(index));
  2936       } else {
  2937         __ dsll(AT, as_Register(index), scale);
  2938         __ daddu(AT, as_Register(base), AT);
  2940       if( Assembler::is_simm16(disp) ) {
  2941         __ ld(dst_reg, AT, disp);
  2942       } else {
  2943         __ move(T9, disp);
  2944         __ daddu(AT, AT, T9);
  2945         __ ld(dst_reg, AT, 0);
  2947     } else {
  2948       if( Assembler::is_simm16(disp) ) {
  2949         __ ld(dst_reg, as_Register(base), disp);
  2950       } else {
  2951         __ move(T9, disp);
  2952         __ daddu(AT, as_Register(base), T9);
  2953         __ ld(dst_reg, AT, 0);
  2956   %}
  2958   enc_class store_L_reg_enc (memory mem, mRegL src) %{
  2959     MacroAssembler _masm(&cbuf);
  2960     int  base = $mem$$base;
  2961     int  index = $mem$$index;
  2962     int  scale = $mem$$scale;
  2963     int  disp = $mem$$disp;
  2964     Register  src_reg = as_Register($src$$reg);
  2966     if( index != 0 ) {
  2967       if (scale == 0) {
  2968         __ daddu(AT, as_Register(base), as_Register(index));
  2969       } else {
  2970         __ dsll(AT, as_Register(index), scale);
  2971         __ daddu(AT, as_Register(base), AT);
  2973       if( Assembler::is_simm16(disp) ) {
  2974         __ sd(src_reg, AT, disp);
  2975       } else {
  2976         __ move(T9, disp);
  2977         __ daddu(AT, AT, T9);
  2978         __ sd(src_reg, AT, 0);
  2980     } else {
  2981       if( Assembler::is_simm16(disp) ) {
  2982         __ sd(src_reg, as_Register(base), disp);
  2983       } else {
  2984         __ move(T9, disp);
  2985         __ daddu(AT, as_Register(base), T9);
  2986         __ sd(src_reg, AT, 0);
  2989   %}
  2991   enc_class store_L_immL0_enc (memory mem, immL0 src) %{
  2992     MacroAssembler _masm(&cbuf);
  2993     int  base = $mem$$base;
  2994     int  index = $mem$$index;
  2995     int  scale = $mem$$scale;
  2996     int  disp = $mem$$disp;
  2998     if( index != 0 ) {
  2999       // For implicit null check
  3000       __ lb(AT, as_Register(base), 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     /* 2012/9/28 Jin: 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     /* 2013/7/22 Jin: Refer to X86_64's RDI */
  3362     __ move(result, 0);
  3363     __ b(done);
  3364     __ 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. by yjl 3/16/2006
  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. by yjl 3/16/2006
  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. by yjl 3/16/2006
  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. by yjl 3/16/2006
  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. by yjl 3/16/2006
  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 %{ "EFLAGS" %}
  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);
  4600   format %{  %}
  4601   interface(REG_INTER);
  4602 %}
  4604 operand no_T8_mRegP() %{
  4605   constraint(ALLOC_IN_RC(no_T8_p_reg));
  4606   match(RegP);
  4607   match(mRegP);
  4609   format %{  %}
  4610   interface(REG_INTER);
  4611 %}
  4613 operand s0_RegP()
  4614 %{
  4615   constraint(ALLOC_IN_RC(s0_long_reg));
  4616   match(RegP);
  4617   match(mRegP);
  4618   match(no_T8_mRegP);
  4620   format %{ %}
  4621   interface(REG_INTER);
  4622 %}
  4624 operand s1_RegP()
  4625 %{
  4626   constraint(ALLOC_IN_RC(s1_long_reg));
  4627   match(RegP);
  4628   match(mRegP);
  4629   match(no_T8_mRegP);
  4631   format %{ %}
  4632   interface(REG_INTER);
  4633 %}
  4635 operand s2_RegP()
  4636 %{
  4637   constraint(ALLOC_IN_RC(s2_long_reg));
  4638   match(RegP);
  4639   match(mRegP);
  4640   match(no_T8_mRegP);
  4642   format %{ %}
  4643   interface(REG_INTER);
  4644 %}
  4646 operand s3_RegP()
  4647 %{
  4648   constraint(ALLOC_IN_RC(s3_long_reg));
  4649   match(RegP);
  4650   match(mRegP);
  4651   match(no_T8_mRegP);
  4653   format %{ %}
  4654   interface(REG_INTER);
  4655 %}
  4657 operand s4_RegP()
  4658 %{
  4659   constraint(ALLOC_IN_RC(s4_long_reg));
  4660   match(RegP);
  4661   match(mRegP);
  4662   match(no_T8_mRegP);
  4664   format %{ %}
  4665   interface(REG_INTER);
  4666 %}
  4668 operand s5_RegP()
  4669 %{
  4670   constraint(ALLOC_IN_RC(s5_long_reg));
  4671   match(RegP);
  4672   match(mRegP);
  4673   match(no_T8_mRegP);
  4675   format %{ %}
  4676   interface(REG_INTER);
  4677 %}
  4679 operand s6_RegP()
  4680 %{
  4681   constraint(ALLOC_IN_RC(s6_long_reg));
  4682   match(RegP);
  4683   match(mRegP);
  4684   match(no_T8_mRegP);
  4686   format %{ %}
  4687   interface(REG_INTER);
  4688 %}
  4690 operand s7_RegP()
  4691 %{
  4692   constraint(ALLOC_IN_RC(s7_long_reg));
  4693   match(RegP);
  4694   match(mRegP);
  4695   match(no_T8_mRegP);
  4697   format %{ %}
  4698   interface(REG_INTER);
  4699 %}
  4701 operand t0_RegP()
  4702 %{
  4703   constraint(ALLOC_IN_RC(t0_long_reg));
  4704   match(RegP);
  4705   match(mRegP);
  4706   match(no_T8_mRegP);
  4708   format %{ %}
  4709   interface(REG_INTER);
  4710 %}
  4712 operand t1_RegP()
  4713 %{
  4714   constraint(ALLOC_IN_RC(t1_long_reg));
  4715   match(RegP);
  4716   match(mRegP);
  4717   match(no_T8_mRegP);
  4719   format %{ %}
  4720   interface(REG_INTER);
  4721 %}
  4723 operand t2_RegP()
  4724 %{
  4725   constraint(ALLOC_IN_RC(t2_long_reg));
  4726   match(RegP);
  4727   match(mRegP);
  4728   match(no_T8_mRegP);
  4730   format %{ %}
  4731   interface(REG_INTER);
  4732 %}
  4734 operand t3_RegP()
  4735 %{
  4736   constraint(ALLOC_IN_RC(t3_long_reg));
  4737   match(RegP);
  4738   match(mRegP);
  4739   match(no_T8_mRegP);
  4741   format %{ %}
  4742   interface(REG_INTER);
  4743 %}
  4745 operand t8_RegP()
  4746 %{
  4747   constraint(ALLOC_IN_RC(t8_long_reg));
  4748   match(RegP);
  4749   match(mRegP);
  4751   format %{ %}
  4752   interface(REG_INTER);
  4753 %}
  4755 operand t9_RegP()
  4756 %{
  4757   constraint(ALLOC_IN_RC(t9_long_reg));
  4758   match(RegP);
  4759   match(mRegP);
  4760   match(no_T8_mRegP);
  4762   format %{ %}
  4763   interface(REG_INTER);
  4764 %}
  4766 operand a0_RegP()
  4767 %{
  4768   constraint(ALLOC_IN_RC(a0_long_reg));
  4769   match(RegP);
  4770   match(mRegP);
  4771   match(no_T8_mRegP);
  4773   format %{ %}
  4774   interface(REG_INTER);
  4775 %}
  4777 operand a1_RegP()
  4778 %{
  4779   constraint(ALLOC_IN_RC(a1_long_reg));
  4780   match(RegP);
  4781   match(mRegP);
  4782   match(no_T8_mRegP);
  4784   format %{ %}
  4785   interface(REG_INTER);
  4786 %}
  4788 operand a2_RegP()
  4789 %{
  4790   constraint(ALLOC_IN_RC(a2_long_reg));
  4791   match(RegP);
  4792   match(mRegP);
  4793   match(no_T8_mRegP);
  4795   format %{ %}
  4796   interface(REG_INTER);
  4797 %}
  4799 operand a3_RegP()
  4800 %{
  4801   constraint(ALLOC_IN_RC(a3_long_reg));
  4802   match(RegP);
  4803   match(mRegP);
  4804   match(no_T8_mRegP);
  4806   format %{ %}
  4807   interface(REG_INTER);
  4808 %}
  4810 operand a4_RegP()
  4811 %{
  4812   constraint(ALLOC_IN_RC(a4_long_reg));
  4813   match(RegP);
  4814   match(mRegP);
  4815   match(no_T8_mRegP);
  4817   format %{ %}
  4818   interface(REG_INTER);
  4819 %}
  4822 operand a5_RegP()
  4823 %{
  4824   constraint(ALLOC_IN_RC(a5_long_reg));
  4825   match(RegP);
  4826   match(mRegP);
  4827   match(no_T8_mRegP);
  4829   format %{ %}
  4830   interface(REG_INTER);
  4831 %}
  4833 operand a6_RegP()
  4834 %{
  4835   constraint(ALLOC_IN_RC(a6_long_reg));
  4836   match(RegP);
  4837   match(mRegP);
  4838   match(no_T8_mRegP);
  4840   format %{ %}
  4841   interface(REG_INTER);
  4842 %}
  4844 operand a7_RegP()
  4845 %{
  4846   constraint(ALLOC_IN_RC(a7_long_reg));
  4847   match(RegP);
  4848   match(mRegP);
  4849   match(no_T8_mRegP);
  4851   format %{ %}
  4852   interface(REG_INTER);
  4853 %}
  4855 operand v0_RegP()
  4856 %{
  4857   constraint(ALLOC_IN_RC(v0_long_reg));
  4858   match(RegP);
  4859   match(mRegP);
  4860   match(no_T8_mRegP);
  4862   format %{ %}
  4863   interface(REG_INTER);
  4864 %}
  4866 operand v1_RegP()
  4867 %{
  4868   constraint(ALLOC_IN_RC(v1_long_reg));
  4869   match(RegP);
  4870   match(mRegP);
  4871   match(no_T8_mRegP);
  4873   format %{ %}
  4874   interface(REG_INTER);
  4875 %}
  4877 /*
  4878 operand mSPRegP(mRegP reg) %{
  4879   constraint(ALLOC_IN_RC(sp_reg));
  4880   match(reg);
  4882   format %{ "SP"  %}
  4883   interface(REG_INTER);
  4884 %}
  4886 operand mFPRegP(mRegP reg) %{
  4887   constraint(ALLOC_IN_RC(fp_reg));
  4888   match(reg);
  4890   format %{ "FP"  %}
  4891   interface(REG_INTER);
  4892 %}
  4893 */
  4895 operand mRegL() %{
  4896   constraint(ALLOC_IN_RC(long_reg));
  4897   match(RegL);
  4899   format %{ %}
  4900   interface(REG_INTER);
  4901 %}
  4903 operand v0RegL() %{
  4904   constraint(ALLOC_IN_RC(v0_long_reg));
  4905   match(RegL);
  4906   match(mRegL);
  4908   format %{ %}
  4909   interface(REG_INTER);
  4910 %}
  4912 operand v1RegL() %{
  4913   constraint(ALLOC_IN_RC(v1_long_reg));
  4914   match(RegL);
  4915   match(mRegL);
  4917   format %{ %}
  4918   interface(REG_INTER);
  4919 %}
  4921 operand a0RegL() %{
  4922   constraint(ALLOC_IN_RC(a0_long_reg));
  4923   match(RegL);
  4924   match(mRegL);
  4926   format %{ "A0" %}
  4927   interface(REG_INTER);
  4928 %}
  4930 operand a1RegL() %{
  4931   constraint(ALLOC_IN_RC(a1_long_reg));
  4932   match(RegL);
  4933   match(mRegL);
  4935   format %{ %}
  4936   interface(REG_INTER);
  4937 %}
  4939 operand a2RegL() %{
  4940   constraint(ALLOC_IN_RC(a2_long_reg));
  4941   match(RegL);
  4942   match(mRegL);
  4944   format %{ %}
  4945   interface(REG_INTER);
  4946 %}
  4948 operand a3RegL() %{
  4949   constraint(ALLOC_IN_RC(a3_long_reg));
  4950   match(RegL);
  4951   match(mRegL);
  4953   format %{ %}
  4954   interface(REG_INTER);
  4955 %}
  4957 operand t0RegL() %{
  4958   constraint(ALLOC_IN_RC(t0_long_reg));
  4959   match(RegL);
  4960   match(mRegL);
  4962   format %{ %}
  4963   interface(REG_INTER);
  4964 %}
  4966 operand t1RegL() %{
  4967   constraint(ALLOC_IN_RC(t1_long_reg));
  4968   match(RegL);
  4969   match(mRegL);
  4971   format %{ %}
  4972   interface(REG_INTER);
  4973 %}
  4975 operand t2RegL() %{
  4976   constraint(ALLOC_IN_RC(t2_long_reg));
  4977   match(RegL);
  4978   match(mRegL);
  4980   format %{ %}
  4981   interface(REG_INTER);
  4982 %}
  4984 operand t3RegL() %{
  4985   constraint(ALLOC_IN_RC(t3_long_reg));
  4986   match(RegL);
  4987   match(mRegL);
  4989   format %{ %}
  4990   interface(REG_INTER);
  4991 %}
  4993 operand t8RegL() %{
  4994   constraint(ALLOC_IN_RC(t8_long_reg));
  4995   match(RegL);
  4996   match(mRegL);
  4998   format %{ %}
  4999   interface(REG_INTER);
  5000 %}
  5002 operand a4RegL() %{
  5003   constraint(ALLOC_IN_RC(a4_long_reg));
  5004   match(RegL);
  5005   match(mRegL);
  5007   format %{ %}
  5008   interface(REG_INTER);
  5009 %}
  5011 operand a5RegL() %{
  5012   constraint(ALLOC_IN_RC(a5_long_reg));
  5013   match(RegL);
  5014   match(mRegL);
  5016   format %{ %}
  5017   interface(REG_INTER);
  5018 %}
  5020 operand a6RegL() %{
  5021   constraint(ALLOC_IN_RC(a6_long_reg));
  5022   match(RegL);
  5023   match(mRegL);
  5025   format %{ %}
  5026   interface(REG_INTER);
  5027 %}
  5029 operand a7RegL() %{
  5030   constraint(ALLOC_IN_RC(a7_long_reg));
  5031   match(RegL);
  5032   match(mRegL);
  5034   format %{ %}
  5035   interface(REG_INTER);
  5036 %}
  5038 operand s0RegL() %{
  5039   constraint(ALLOC_IN_RC(s0_long_reg));
  5040   match(RegL);
  5041   match(mRegL);
  5043   format %{ %}
  5044   interface(REG_INTER);
  5045 %}
  5047 operand s1RegL() %{
  5048   constraint(ALLOC_IN_RC(s1_long_reg));
  5049   match(RegL);
  5050   match(mRegL);
  5052   format %{ %}
  5053   interface(REG_INTER);
  5054 %}
  5056 operand s2RegL() %{
  5057   constraint(ALLOC_IN_RC(s2_long_reg));
  5058   match(RegL);
  5059   match(mRegL);
  5061   format %{ %}
  5062   interface(REG_INTER);
  5063 %}
  5065 operand s3RegL() %{
  5066   constraint(ALLOC_IN_RC(s3_long_reg));
  5067   match(RegL);
  5068   match(mRegL);
  5070   format %{ %}
  5071   interface(REG_INTER);
  5072 %}
  5074 operand s4RegL() %{
  5075   constraint(ALLOC_IN_RC(s4_long_reg));
  5076   match(RegL);
  5077   match(mRegL);
  5079   format %{ %}
  5080   interface(REG_INTER);
  5081 %}
  5083 operand s7RegL() %{
  5084   constraint(ALLOC_IN_RC(s7_long_reg));
  5085   match(RegL);
  5086   match(mRegL);
  5088   format %{ %}
  5089   interface(REG_INTER);
  5090 %}
  5092 // Floating register operands
  5093 operand regF() %{
  5094   constraint(ALLOC_IN_RC(flt_reg));
  5095   match(RegF);
  5097   format %{ %}
  5098   interface(REG_INTER);
  5099 %}
  5101 //Double Precision Floating register operands
  5102 operand regD() %{
  5103   constraint(ALLOC_IN_RC(dbl_reg));
  5104   match(RegD);
  5106   format %{ %}
  5107   interface(REG_INTER);
  5108 %}
  5110 //----------Memory Operands----------------------------------------------------
  5111 // Indirect Memory Operand
  5112 operand indirect(mRegP reg) %{
  5113   constraint(ALLOC_IN_RC(p_reg));
  5114   match(reg);
  5116   format %{ "[$reg] @ indirect" %}
  5117   interface(MEMORY_INTER) %{
  5118     base($reg);
  5119     index(0x0);  /* NO_INDEX */
  5120     scale(0x0);
  5121     disp(0x0);
  5122   %}
  5123 %}
  5125 // Indirect Memory Plus Short Offset Operand
  5126 operand indOffset8(mRegP reg, immL8 off)
  5127 %{
  5128   constraint(ALLOC_IN_RC(p_reg));
  5129   match(AddP reg off);
  5131   op_cost(10);
  5132   format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
  5133   interface(MEMORY_INTER) %{
  5134     base($reg);
  5135     index(0x0); /* NO_INDEX */
  5136     scale(0x0);
  5137     disp($off);
  5138   %}
  5139 %}
  5141 // Indirect Memory Times Scale Plus Index Register
  5142 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
  5143 %{
  5144   constraint(ALLOC_IN_RC(p_reg));
  5145   match(AddP reg (LShiftL lreg scale));
  5147   op_cost(10);
  5148   format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
  5149   interface(MEMORY_INTER) %{
  5150     base($reg);
  5151     index($lreg);
  5152     scale($scale);
  5153     disp(0x0);
  5154   %}
  5155 %}
  5158 // [base + index + offset]
  5159 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
  5160 %{
  5161   constraint(ALLOC_IN_RC(p_reg));
  5162   op_cost(5);
  5163   match(AddP (AddP base index) off);
  5165   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
  5166   interface(MEMORY_INTER) %{
  5167     base($base);
  5168     index($index);
  5169     scale(0x0);
  5170     disp($off);
  5171   %}
  5172 %}
  5174 // [base + index + offset]
  5175 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
  5176 %{
  5177   constraint(ALLOC_IN_RC(p_reg));
  5178   op_cost(5);
  5179   match(AddP (AddP base (ConvI2L index)) off);
  5181   format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
  5182   interface(MEMORY_INTER) %{
  5183     base($base);
  5184     index($index);
  5185     scale(0x0);
  5186     disp($off);
  5187   %}
  5188 %}
  5190 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5191 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
  5192 %{
  5193   constraint(ALLOC_IN_RC(p_reg));
  5194   match(AddP (AddP reg (LShiftL lreg scale)) off);
  5196   op_cost(10);
  5197   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
  5198   interface(MEMORY_INTER) %{
  5199     base($reg);
  5200     index($lreg);
  5201     scale($scale);
  5202     disp($off);
  5203   %}
  5204 %}
  5206 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
  5207 %{
  5208   constraint(ALLOC_IN_RC(p_reg));
  5209   match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
  5211   op_cost(10);
  5212   format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
  5213   interface(MEMORY_INTER) %{
  5214     base($reg);
  5215     index($ireg);
  5216     scale($scale);
  5217     disp($off);
  5218   %}
  5219 %}
  5221 // [base + index<<scale + offset]
  5222 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
  5223 %{
  5224   constraint(ALLOC_IN_RC(p_reg));
  5225   //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5226   op_cost(10);
  5227   match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
  5229   format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
  5230   interface(MEMORY_INTER) %{
  5231     base($base);
  5232     index($index);
  5233     scale($scale);
  5234     disp($off);
  5235   %}
  5236 %}
  5238 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
  5239 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
  5240 %{
  5241   predicate(Universe::narrow_oop_shift() == 0);
  5242   constraint(ALLOC_IN_RC(p_reg));
  5243   match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
  5245   op_cost(10);
  5246   format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
  5247   interface(MEMORY_INTER) %{
  5248     base($reg);
  5249     index($lreg);
  5250     scale($scale);
  5251     disp($off);
  5252   %}
  5253 %}
  5255 // [base + index<<scale + offset] for compressd Oops
  5256 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
  5257 %{
  5258   constraint(ALLOC_IN_RC(p_reg));
  5259   //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
  5260   predicate(Universe::narrow_oop_shift() == 0);
  5261   op_cost(10);
  5262   match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
  5264   format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
  5265   interface(MEMORY_INTER) %{
  5266     base($base);
  5267     index($index);
  5268     scale($scale);
  5269     disp($off);
  5270   %}
  5271 %}
  5273 //FIXME: I think it's better to limit the immI to be 16-bit at most!
  5274 // Indirect Memory Plus Long Offset Operand
  5275 operand indOffset32(mRegP reg, immL32 off) %{
  5276   constraint(ALLOC_IN_RC(p_reg));
  5277   op_cost(20);
  5278   match(AddP reg off);
  5280   format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
  5281   interface(MEMORY_INTER) %{
  5282     base($reg);
  5283     index(0x0);   /* NO_INDEX */
  5284     scale(0x0);
  5285     disp($off);
  5286   %}
  5287 %}
  5289 // Indirect Memory Plus Index Register
  5290 operand indIndex(mRegP addr, mRegL index) %{
  5291   constraint(ALLOC_IN_RC(p_reg));
  5292   match(AddP addr index);
  5294   op_cost(20);
  5295   format %{"[$addr + $index] @ indIndex" %}
  5296   interface(MEMORY_INTER) %{
  5297     base($addr);
  5298     index($index);
  5299     scale(0x0);
  5300     disp(0x0);
  5301   %}
  5302 %}
  5304 operand indirectNarrowKlass(mRegN reg)
  5305 %{
  5306   predicate(Universe::narrow_klass_shift() == 0);
  5307   constraint(ALLOC_IN_RC(p_reg));
  5308   op_cost(10);
  5309   match(DecodeNKlass reg);
  5311   format %{ "[$reg] @ indirectNarrowKlass" %}
  5312   interface(MEMORY_INTER) %{
  5313     base($reg);
  5314     index(0x0);
  5315     scale(0x0);
  5316     disp(0x0);
  5317   %}
  5318 %}
  5320 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
  5321 %{
  5322   predicate(Universe::narrow_klass_shift() == 0);
  5323   constraint(ALLOC_IN_RC(p_reg));
  5324   op_cost(10);
  5325   match(AddP (DecodeNKlass reg) off);
  5327   format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
  5328   interface(MEMORY_INTER) %{
  5329     base($reg);
  5330     index(0x0);
  5331     scale(0x0);
  5332     disp($off);
  5333   %}
  5334 %}
  5336 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
  5337 %{
  5338   predicate(Universe::narrow_klass_shift() == 0);
  5339   constraint(ALLOC_IN_RC(p_reg));
  5340   op_cost(10);
  5341   match(AddP (DecodeNKlass reg) off);
  5343   format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
  5344   interface(MEMORY_INTER) %{
  5345     base($reg);
  5346     index(0x0);
  5347     scale(0x0);
  5348     disp($off);
  5349   %}
  5350 %}
  5352 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
  5353 %{
  5354   predicate(Universe::narrow_klass_shift() == 0);
  5355   constraint(ALLOC_IN_RC(p_reg));
  5356   match(AddP (AddP (DecodeNKlass reg) lreg) off);
  5358   op_cost(10);
  5359   format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
  5360   interface(MEMORY_INTER) %{
  5361     base($reg);
  5362     index($lreg);
  5363     scale(0x0);
  5364     disp($off);
  5365   %}
  5366 %}
  5368 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
  5369 %{
  5370   predicate(Universe::narrow_klass_shift() == 0);
  5371   constraint(ALLOC_IN_RC(p_reg));
  5372   match(AddP (DecodeNKlass reg) lreg);
  5374   op_cost(10);
  5375   format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
  5376   interface(MEMORY_INTER) %{
  5377     base($reg);
  5378     index($lreg);
  5379     scale(0x0);
  5380     disp(0x0);
  5381   %}
  5382 %}
  5384 // Indirect Memory Operand
  5385 operand indirectNarrow(mRegN reg)
  5386 %{
  5387   predicate(Universe::narrow_oop_shift() == 0);
  5388   constraint(ALLOC_IN_RC(p_reg));
  5389   op_cost(10);
  5390   match(DecodeN reg);
  5392   format %{ "[$reg] @ indirectNarrow" %}
  5393   interface(MEMORY_INTER) %{
  5394     base($reg);
  5395     index(0x0);
  5396     scale(0x0);
  5397     disp(0x0);
  5398   %}
  5399 %}
  5401 // Indirect Memory Plus Short Offset Operand
  5402 operand indOffset8Narrow(mRegN reg, immL8 off)
  5403 %{
  5404   predicate(Universe::narrow_oop_shift() == 0);
  5405   constraint(ALLOC_IN_RC(p_reg));
  5406   op_cost(10);
  5407   match(AddP (DecodeN reg) off);
  5409   format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
  5410   interface(MEMORY_INTER) %{
  5411     base($reg);
  5412     index(0x0);
  5413     scale(0x0);
  5414     disp($off);
  5415   %}
  5416 %}
  5418 // Indirect Memory Plus Index Register Plus Offset Operand
  5419 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
  5420 %{
  5421   predicate(Universe::narrow_oop_shift() == 0);
  5422   constraint(ALLOC_IN_RC(p_reg));
  5423   match(AddP (AddP (DecodeN reg) lreg) off);
  5425   op_cost(10);
  5426   format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
  5427   interface(MEMORY_INTER) %{
  5428     base($reg);
  5429     index($lreg);
  5430     scale(0x0);
  5431     disp($off);
  5432   %}
  5433 %}
  5435 //----------Load Long Memory Operands------------------------------------------
  5436 // The load-long idiom will use it's address expression again after loading
  5437 // the first word of the long.  If the load-long destination overlaps with
  5438 // registers used in the addressing expression, the 2nd half will be loaded
  5439 // from a clobbered address.  Fix this by requiring that load-long use
  5440 // address registers that do not overlap with the load-long target.
  5442 // load-long support
  5443 operand load_long_RegP() %{
  5444   constraint(ALLOC_IN_RC(p_reg));
  5445   match(RegP);
  5446   match(mRegP);
  5447   op_cost(100);
  5448   format %{  %}
  5449   interface(REG_INTER);
  5450 %}
  5452 // Indirect Memory Operand Long
  5453 operand load_long_indirect(load_long_RegP reg) %{
  5454   constraint(ALLOC_IN_RC(p_reg));
  5455   match(reg);
  5457   format %{ "[$reg]" %}
  5458   interface(MEMORY_INTER) %{
  5459     base($reg);
  5460     index(0x0);
  5461     scale(0x0);
  5462     disp(0x0);
  5463   %}
  5464 %}
  5466 // Indirect Memory Plus Long Offset Operand
  5467 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
  5468   match(AddP reg off);
  5470   format %{ "[$reg + $off]" %}
  5471   interface(MEMORY_INTER) %{
  5472     base($reg);
  5473     index(0x0);
  5474     scale(0x0);
  5475     disp($off);
  5476   %}
  5477 %}
  5479 //----------Conditional Branch Operands----------------------------------------
  5480 // Comparison Op  - This is the operation of the comparison, and is limited to
  5481 //                  the following set of codes:
  5482 //                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
  5483 //
  5484 // Other attributes of the comparison, such as unsignedness, are specified
  5485 // by the comparison instruction that sets a condition code flags register.
  5486 // That result is represented by a flags operand whose subtype is appropriate
  5487 // to the unsignedness (etc.) of the comparison.
  5488 //
  5489 // Later, the instruction which matches both the Comparison Op (a Bool) and
  5490 // the flags (produced by the Cmp) specifies the coding of the comparison op
  5491 // by matching a specific subtype of Bool operand below, such as cmpOpU.
  5493 // Comparision Code
  5494 operand cmpOp() %{
  5495   match(Bool);
  5497   format %{ "" %}
  5498   interface(COND_INTER) %{
  5499     equal(0x01);
  5500     not_equal(0x02);
  5501     greater(0x03);
  5502     greater_equal(0x04);
  5503     less(0x05);
  5504     less_equal(0x06);
  5505     overflow(0x7);
  5506     no_overflow(0x8);
  5507   %}
  5508 %}
  5511 // Comparision Code
  5512 // Comparison Code, unsigned compare.  Used by FP also, with
  5513 // C2 (unordered) turned into GT or LT already.  The other bits
  5514 // C0 and C3 are turned into Carry & Zero flags.
  5515 operand cmpOpU() %{
  5516   match(Bool);
  5518   format %{ "" %}
  5519   interface(COND_INTER) %{
  5520     equal(0x01);
  5521     not_equal(0x02);
  5522     greater(0x03);
  5523     greater_equal(0x04);
  5524     less(0x05);
  5525     less_equal(0x06);
  5526     overflow(0x7);
  5527     no_overflow(0x8);
  5528   %}
  5529 %}
  5532 //----------Special Memory Operands--------------------------------------------
  5533 // Stack Slot Operand - This operand is used for loading and storing temporary
  5534 //                      values on the stack where a match requires a value to
  5535 //                      flow through memory.
  5536 operand stackSlotP(sRegP reg) %{
  5537   constraint(ALLOC_IN_RC(stack_slots));
  5538   // No match rule because this operand is only generated in matching
  5539   op_cost(50);
  5540   format %{ "[$reg]" %}
  5541   interface(MEMORY_INTER) %{
  5542     base(0x1d);  // SP
  5543     index(0x0);  // No Index
  5544     scale(0x0);  // No Scale
  5545     disp($reg);  // Stack Offset
  5546   %}
  5547 %}
  5549 operand stackSlotI(sRegI reg) %{
  5550   constraint(ALLOC_IN_RC(stack_slots));
  5551   // No match rule because this operand is only generated in matching
  5552   op_cost(50);
  5553   format %{ "[$reg]" %}
  5554   interface(MEMORY_INTER) %{
  5555     base(0x1d);  // SP
  5556     index(0x0);  // No Index
  5557     scale(0x0);  // No Scale
  5558     disp($reg);  // Stack Offset
  5559   %}
  5560 %}
  5562 operand stackSlotF(sRegF reg) %{
  5563   constraint(ALLOC_IN_RC(stack_slots));
  5564   // No match rule because this operand is only generated in matching
  5565   op_cost(50);
  5566   format %{ "[$reg]" %}
  5567   interface(MEMORY_INTER) %{
  5568     base(0x1d);  // SP
  5569     index(0x0);  // No Index
  5570     scale(0x0);  // No Scale
  5571     disp($reg);  // Stack Offset
  5572   %}
  5573 %}
  5575 operand stackSlotD(sRegD reg) %{
  5576   constraint(ALLOC_IN_RC(stack_slots));
  5577   // No match rule because this operand is only generated in matching
  5578   op_cost(50);
  5579   format %{ "[$reg]" %}
  5580   interface(MEMORY_INTER) %{
  5581     base(0x1d);  // SP
  5582     index(0x0);  // No Index
  5583     scale(0x0);  // No Scale
  5584     disp($reg);  // Stack Offset
  5585   %}
  5586 %}
  5588 operand stackSlotL(sRegL reg) %{
  5589   constraint(ALLOC_IN_RC(stack_slots));
  5590   // No match rule because this operand is only generated in matching
  5591   op_cost(50);
  5592   format %{ "[$reg]" %}
  5593   interface(MEMORY_INTER) %{
  5594     base(0x1d);  // SP
  5595     index(0x0);  // No Index
  5596     scale(0x0);  // No Scale
  5597     disp($reg);  // Stack Offset
  5598   %}
  5599 %}
  5602 //------------------------OPERAND CLASSES--------------------------------------
  5603 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
  5604 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);
  5607 //----------PIPELINE-----------------------------------------------------------
  5608 // Rules which define the behavior of the target architectures pipeline.
  5610 pipeline %{
  5612   //----------ATTRIBUTES---------------------------------------------------------
  5613   attributes %{
  5614     fixed_size_instructions;          // Fixed size instructions
  5615     branch_has_delay_slot;      // branch have delay slot in gs2
  5616     max_instructions_per_bundle = 1;     // 1 instruction per bundle
  5617     max_bundles_per_cycle = 4;         // Up to 4 bundles per cycle
  5618          bundle_unit_size=4;
  5619     instruction_unit_size = 4;           // An instruction is 4 bytes long
  5620     instruction_fetch_unit_size = 16;    // The processor fetches one line
  5621     instruction_fetch_units = 1;         // of 16 bytes
  5623     // List of nop instructions
  5624     nops( MachNop );
  5625   %}
  5627   //----------RESOURCES----------------------------------------------------------
  5628   // Resources are the functional units available to the machine
  5630   resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4,  ALU1, ALU2,  ALU = ALU1 | ALU2,  FPU1, FPU2, FPU = FPU1 | FPU2,  MEM,  BR);
  5632   //----------PIPELINE DESCRIPTION-----------------------------------------------
  5633   // Pipeline Description specifies the stages in the machine's pipeline
  5635   // IF: fetch
  5636   // ID: decode
  5637   // RD: read
  5638   // CA: caculate
  5639   // WB: write back
  5640   // CM: commit
  5642   pipe_desc(IF, ID, RD, CA, WB, CM);
  5645   //----------PIPELINE CLASSES---------------------------------------------------
  5646   // Pipeline Classes describe the stages in which input and output are
  5647   // referenced by the hardware pipeline.
  5649   //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
  5650   pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
  5651     single_instruction;
  5652     src1   : RD(read);
  5653     src2   : RD(read);
  5654     dst    : WB(write)+1;
  5655     DECODE : ID;
  5656     ALU    : CA;
  5657   %}
  5659   //No.19 Integer mult operation : dst <-- reg1 mult reg2
  5660   pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
  5661     src1   : RD(read);
  5662     src2   : RD(read);
  5663     dst    : WB(write)+5;
  5664     DECODE : ID;
  5665     ALU2   : CA;
  5666   %}
  5668   pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  5669     src1   : RD(read);
  5670     src2   : RD(read);
  5671     dst    : WB(write)+10;
  5672     DECODE : ID;
  5673     ALU2   : CA;
  5674   %}
  5676   //No.19 Integer div operation : dst <-- reg1 div reg2
  5677   pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
  5678     src1   : RD(read);
  5679     src2   : RD(read);
  5680     dst    : WB(write)+10;
  5681     DECODE : ID;
  5682     ALU2   : CA;
  5683   %}
  5685   //No.19 Integer mod operation : dst <-- reg1 mod reg2
  5686   pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
  5687     instruction_count(2);
  5688     src1   : RD(read);
  5689     src2   : RD(read);
  5690     dst    : WB(write)+10;
  5691     DECODE : ID;
  5692     ALU2   : CA;
  5693   %}
  5695   //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
  5696   pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
  5697     instruction_count(2);
  5698     src1   : RD(read);
  5699     src2   : RD(read);
  5700     dst    : WB(write);
  5701     DECODE : ID;
  5702     ALU    : CA;
  5703   %}
  5705   //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
  5706   pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
  5707     instruction_count(2);
  5708     src    : RD(read);
  5709     dst    : WB(write);
  5710     DECODE : ID;
  5711     ALU    : CA;
  5712   %}
  5714   //no.16 load Long from memory :
  5715   pipe_class ialu_loadL(mRegL dst, memory mem) %{
  5716     instruction_count(2);
  5717     mem    : RD(read);
  5718     dst    : WB(write)+5;
  5719     DECODE : ID;
  5720     MEM    : RD;
  5721   %}
  5723   //No.17 Store Long to Memory :
  5724   pipe_class ialu_storeL(mRegL src, memory mem) %{
  5725     instruction_count(2);
  5726     mem    : RD(read);
  5727     src    : RD(read);
  5728     DECODE : ID;
  5729     MEM    : RD;
  5730   %}
  5732   //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
  5733   pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
  5734          single_instruction;
  5735     src    : RD(read);
  5736     dst    : WB(write);
  5737     DECODE : ID;
  5738     ALU    : CA;
  5739   %}
  5741   //No.3 Integer move operation : dst <-- reg
  5742   pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
  5743     src    : RD(read);
  5744     dst    : WB(write);
  5745     DECODE : ID;
  5746     ALU    : CA;
  5747   %}
  5749   //No.4 No instructions : do nothing
  5750   pipe_class empty( ) %{
  5751     instruction_count(0);
  5752   %}
  5754   //No.5 UnConditional branch :
  5755   pipe_class pipe_jump( label labl ) %{
  5756     multiple_bundles;
  5757     DECODE : ID;
  5758     BR     : RD;
  5759   %}
  5761   //No.6 ALU Conditional branch :
  5762   pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
  5763     multiple_bundles;
  5764     src1   : RD(read);
  5765     src2   : RD(read);
  5766     DECODE : ID;
  5767     BR     : RD;
  5768   %}
  5770   //no.7 load integer from memory :
  5771   pipe_class ialu_loadI(mRegI dst, memory mem) %{
  5772     mem    : RD(read);
  5773     dst    : WB(write)+3;
  5774     DECODE : ID;
  5775     MEM    : RD;
  5776   %}
  5778   //No.8 Store Integer to Memory :
  5779   pipe_class ialu_storeI(mRegI src, memory mem) %{
  5780     mem    : RD(read);
  5781     src    : RD(read);
  5782     DECODE : ID;
  5783     MEM    : RD;
  5784   %}
  5787   //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
  5788   pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
  5789     src1   : RD(read);
  5790     src2   : RD(read);
  5791     dst    : WB(write);
  5792     DECODE : ID;
  5793     FPU    : CA;
  5794   %}
  5796   //No.22 Floating div operation : dst <-- reg1 div reg2
  5797   pipe_class fpu_div(regF dst, regF src1, regF src2) %{
  5798     src1   : RD(read);
  5799     src2   : RD(read);
  5800     dst    : WB(write);
  5801     DECODE : ID;
  5802     FPU2   : CA;
  5803   %}
  5805   pipe_class fcvt_I2D(regD dst, mRegI src) %{
  5806     src    : RD(read);
  5807     dst    : WB(write);
  5808     DECODE : ID;
  5809     FPU1   : CA;
  5810   %}
  5812   pipe_class fcvt_D2I(mRegI dst, regD src) %{
  5813     src    : RD(read);
  5814     dst    : WB(write);
  5815     DECODE : ID;
  5816     FPU1   : CA;
  5817   %}
  5819   pipe_class pipe_mfc1(mRegI dst, regD src) %{
  5820     src    : RD(read);
  5821     dst    : WB(write);
  5822     DECODE : ID;
  5823     MEM    : RD;
  5824   %}
  5826   pipe_class pipe_mtc1(regD dst, mRegI src) %{
  5827     src    : RD(read);
  5828     dst    : WB(write);
  5829     DECODE : ID;
  5830     MEM    : RD(5);
  5831   %}
  5833   //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
  5834   pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
  5835     multiple_bundles;
  5836     src1   : RD(read);
  5837     src2   : RD(read);
  5838     dst    : WB(write);
  5839     DECODE : ID;
  5840     FPU2   : CA;
  5841   %}
  5843   //No.11 Load Floating from Memory :
  5844   pipe_class fpu_loadF(regF dst, memory mem) %{
  5845     instruction_count(1);
  5846     mem    : RD(read);
  5847     dst    : WB(write)+3;
  5848     DECODE : ID;
  5849     MEM    : RD;
  5850   %}
  5852   //No.12 Store Floating to Memory :
  5853   pipe_class fpu_storeF(regF src, memory mem) %{
  5854     instruction_count(1);
  5855     mem    : RD(read);
  5856     src    : RD(read);
  5857     DECODE : ID;
  5858     MEM    : RD;
  5859   %}
  5861   //No.13 FPU Conditional branch :
  5862   pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
  5863     multiple_bundles;
  5864     src1   : RD(read);
  5865     src2   : RD(read);
  5866     DECODE : ID;
  5867     BR     : RD;
  5868   %}
  5870 //No.14 Floating FPU reg operation : dst <-- op reg
  5871   pipe_class fpu1_regF(regF dst, regF src) %{
  5872     src    : RD(read);
  5873     dst    : WB(write);
  5874     DECODE : ID;
  5875     FPU    : CA;
  5876   %}
  5878   pipe_class long_memory_op() %{
  5879     instruction_count(10); multiple_bundles; force_serialization;
  5880     fixed_latency(30);
  5881   %}
  5883   pipe_class simple_call() %{
  5884    instruction_count(10); multiple_bundles; force_serialization;
  5885    fixed_latency(200);
  5886    BR     : RD;
  5887   %}
  5889   pipe_class call() %{
  5890     instruction_count(10); multiple_bundles; force_serialization;
  5891     fixed_latency(200);
  5892   %}
  5894   //FIXME:
  5895   //No.9 Piple slow : for multi-instructions
  5896   pipe_class pipe_slow(  ) %{
  5897     instruction_count(20);
  5898     force_serialization;
  5899     multiple_bundles;
  5900     fixed_latency(50);
  5901   %}
  5903 %}
  5907 //----------INSTRUCTIONS-------------------------------------------------------
  5908 //
  5909 // match      -- States which machine-independent subtree may be replaced
  5910 //               by this instruction.
  5911 // ins_cost   -- The estimated cost of this instruction is used by instruction
  5912 //               selection to identify a minimum cost tree of machine
  5913 //               instructions that matches a tree of machine-independent
  5914 //               instructions.
  5915 // format     -- A string providing the disassembly for this instruction.
  5916 //               The value of an instruction's operand may be inserted
  5917 //               by referring to it with a '$' prefix.
  5918 // opcode     -- Three instruction opcodes may be provided.  These are referred
  5919 //               to within an encode class as $primary, $secondary, and $tertiary
  5920 //               respectively.  The primary opcode is commonly used to
  5921 //               indicate the type of machine instruction, while secondary
  5922 //               and tertiary are often used for prefix options or addressing
  5923 //               modes.
  5924 // ins_encode -- A list of encode classes with parameters. The encode class
  5925 //               name must have been defined in an 'enc_class' specification
  5926 //               in the encode section of the architecture description.
  5929 // Load Integer
  5930 instruct loadI(mRegI dst, memory mem) %{
  5931   match(Set dst (LoadI mem));
  5933   ins_cost(125);
  5934   format %{ "lw    $dst, $mem   #@loadI" %}
  5935   ins_encode (load_I_enc(dst, mem));
  5936   ins_pipe( ialu_loadI );
  5937 %}
  5939 instruct loadI_convI2L(mRegL dst, memory mem) %{
  5940   match(Set dst (ConvI2L (LoadI mem)));
  5942   ins_cost(125);
  5943   format %{ "lw    $dst, $mem   #@loadI_convI2L" %}
  5944   ins_encode (load_I_enc(dst, mem));
  5945   ins_pipe( ialu_loadI );
  5946 %}
  5948 // Load Integer (32 bit signed) to Byte (8 bit signed)
  5949 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  5950   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
  5952   ins_cost(125);
  5953   format %{ "lb  $dst, $mem\t# int -> byte #@loadI2B" %}
  5954   ins_encode(load_B_enc(dst, mem));
  5955   ins_pipe(ialu_loadI);
  5956 %}
  5958 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
  5959 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
  5960   match(Set dst (AndI (LoadI mem) mask));
  5962   ins_cost(125);
  5963   format %{ "lbu  $dst, $mem\t# int -> ubyte #@loadI2UB" %}
  5964   ins_encode(load_UB_enc(dst, mem));
  5965   ins_pipe(ialu_loadI);
  5966 %}
  5968 // Load Integer (32 bit signed) to Short (16 bit signed)
  5969 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
  5970   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
  5972   ins_cost(125);
  5973   format %{ "lh  $dst, $mem\t# int -> short #@loadI2S" %}
  5974   ins_encode(load_S_enc(dst, mem));
  5975   ins_pipe(ialu_loadI);
  5976 %}
  5978 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
  5979 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
  5980   match(Set dst (AndI (LoadI mem) mask));
  5982   ins_cost(125);
  5983   format %{ "lhu  $dst, $mem\t# int -> ushort/char #@loadI2US" %}
  5984   ins_encode(load_C_enc(dst, mem));
  5985   ins_pipe(ialu_loadI);
  5986 %}
  5988 // Load Long.
  5989 instruct loadL(mRegL dst, memory mem) %{
  5990 //  predicate(!((LoadLNode*)n)->require_atomic_access());
  5991   match(Set dst (LoadL mem));
  5993   ins_cost(250);
  5994   format %{ "ld    $dst, $mem   #@loadL" %}
  5995   ins_encode(load_L_enc(dst, mem));
  5996   ins_pipe( ialu_loadL );
  5997 %}
  5999 // Load Long - UNaligned
  6000 instruct loadL_unaligned(mRegL dst, memory mem) %{
  6001   match(Set dst (LoadL_unaligned mem));
  6003   // FIXME: Jin: Need more effective ldl/ldr
  6004   ins_cost(450);
  6005   format %{ "ld    $dst, $mem   #@loadL_unaligned\n\t" %}
  6006   ins_encode(load_L_enc(dst, mem));
  6007   ins_pipe( ialu_loadL );
  6008 %}
  6010 // Store Long
  6011 instruct storeL_reg(memory mem, mRegL src) %{
  6012   match(Set mem (StoreL mem src));
  6014   ins_cost(200);
  6015   format %{ "sd    $mem,   $src #@storeL_reg\n" %}
  6016   ins_encode(store_L_reg_enc(mem, src));
  6017   ins_pipe( ialu_storeL );
  6018 %}
  6020 instruct storeL_immL0(memory mem, immL0 zero) %{
  6021   match(Set mem (StoreL mem zero));
  6023   ins_cost(180);
  6024   format %{ "sd    zero, $mem #@storeL_immL0" %}
  6025   ins_encode(store_L_immL0_enc(mem, zero));
  6026   ins_pipe( ialu_storeL );
  6027 %}
  6029 instruct storeL_imm(memory mem, immL src) %{
  6030   match(Set mem (StoreL mem src));
  6032   ins_cost(200);
  6033   format %{ "sd    $src, $mem #@storeL_imm" %}
  6034   ins_encode(store_L_immL_enc(mem, src));
  6035   ins_pipe( ialu_storeL );
  6036 %}
  6038 // Load Compressed Pointer
  6039 instruct loadN(mRegN dst, memory mem)
  6040 %{
  6041    match(Set dst (LoadN mem));
  6043    ins_cost(125); // XXX
  6044    format %{ "lwu    $dst, $mem\t# compressed ptr @ loadN" %}
  6045    ins_encode (load_N_enc(dst, mem));
  6046    ins_pipe( ialu_loadI ); // XXX
  6047 %}
  6049 instruct loadN2P(mRegP dst, memory mem)
  6050 %{
  6051    match(Set dst (DecodeN (LoadN mem)));
  6052    predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6054    ins_cost(125); // XXX
  6055    format %{ "lwu    $dst, $mem\t# @ loadN2P" %}
  6056    ins_encode (load_N_enc(dst, mem));
  6057    ins_pipe( ialu_loadI ); // XXX
  6058 %}
  6060 // Load Pointer
  6061 instruct loadP(mRegP dst, memory mem) %{
  6062   match(Set dst (LoadP mem));
  6064   ins_cost(125);
  6065   format %{ "ld    $dst, $mem #@loadP" %}
  6066   ins_encode (load_P_enc(dst, mem));
  6067   ins_pipe( ialu_loadI );
  6068 %}
  6070 // Load Klass Pointer
  6071 instruct loadKlass(mRegP dst, memory mem) %{
  6072   match(Set dst (LoadKlass mem));
  6074   ins_cost(125);
  6075   format %{ "MOV    $dst,$mem @ loadKlass" %}
  6076   ins_encode (load_P_enc(dst, mem));
  6077   ins_pipe( ialu_loadI );
  6078 %}
  6080 // Load narrow Klass Pointer
  6081 instruct loadNKlass(mRegN dst, memory mem)
  6082 %{
  6083   match(Set dst (LoadNKlass mem));
  6085   ins_cost(125); // XXX
  6086   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
  6087   ins_encode (load_N_enc(dst, mem));
  6088   ins_pipe( ialu_loadI ); // XXX
  6089 %}
  6091 instruct loadN2PKlass(mRegP dst, memory mem)
  6092 %{
  6093   match(Set dst (DecodeNKlass (LoadNKlass mem)));
  6094   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6096   ins_cost(125); // XXX
  6097   format %{ "lwu    $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
  6098   ins_encode (load_N_enc(dst, mem));
  6099   ins_pipe( ialu_loadI ); // XXX
  6100 %}
  6102 // Load Constant
  6103 instruct loadConI(mRegI dst, immI src) %{
  6104   match(Set dst src);
  6106   ins_cost(150);
  6107   format %{ "mov    $dst, $src #@loadConI" %}
  6108   ins_encode %{
  6109     Register dst = $dst$$Register;
  6110     int    value = $src$$constant;
  6111     __ move(dst, value);
  6112   %}
  6113   ins_pipe( ialu_regI_regI );
  6114 %}
  6117 instruct loadConL_set64(mRegL dst, immL src) %{
  6118   match(Set dst src);
  6119   ins_cost(120);
  6120   format %{ "li   $dst, $src @ loadConL_set64" %}
  6121   ins_encode %{
  6122     __ set64($dst$$Register, $src$$constant);
  6123   %}
  6124   ins_pipe(ialu_regL_regL);
  6125 %}
  6127 /*
  6128 // Load long value from constant table (predicated by immL_expensive).
  6129 instruct loadConL_load(mRegL dst, immL_expensive src) %{
  6130   match(Set dst src);
  6131   ins_cost(150);
  6132   format %{ "ld  $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
  6133   ins_encode %{
  6134     int con_offset = $constantoffset($src);
  6136     if (Assembler::is_simm16(con_offset)) {
  6137        __ ld($dst$$Register, $constanttablebase, con_offset);
  6138     } else {
  6139        __ set64(AT, con_offset);
  6140        if (UseLoongsonISA) {
  6141           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6142        } else {
  6143           __ daddu(AT, $constanttablebase, AT);
  6144           __ ld($dst$$Register, AT, 0);
  6147   %}
  6148   ins_pipe(ialu_loadI);
  6149 %}
  6150 */
  6152 instruct loadConL16(mRegL dst, immL16 src) %{
  6153   match(Set dst src);
  6154   ins_cost(105);
  6155   format %{ "mov    $dst, $src #@loadConL16" %}
  6156   ins_encode %{
  6157     Register dst_reg = as_Register($dst$$reg);
  6158     int      value   = $src$$constant;
  6159     __ daddiu(dst_reg, R0, value);
  6160   %}
  6161   ins_pipe( ialu_regL_regL );
  6162 %}
  6165 instruct loadConL0(mRegL dst, immL0 src) %{
  6166   match(Set dst src);
  6167   ins_cost(100);
  6168   format %{ "mov    $dst, zero #@loadConL0" %}
  6169   ins_encode %{
  6170     Register dst_reg = as_Register($dst$$reg);
  6171     __ daddu(dst_reg, R0, R0);
  6172   %}
  6173   ins_pipe( ialu_regL_regL );
  6174 %}
  6176 // Load Range
  6177 instruct loadRange(mRegI dst, memory mem) %{
  6178   match(Set dst (LoadRange mem));
  6180   ins_cost(125);
  6181   format %{ "MOV    $dst,$mem @ loadRange" %}
  6182   ins_encode(load_I_enc(dst, mem));
  6183   ins_pipe( ialu_loadI );
  6184 %}
  6187 instruct storeP(memory mem, mRegP src ) %{
  6188   match(Set mem (StoreP mem src));
  6190   ins_cost(125);
  6191   format %{ "sd    $src, $mem #@storeP" %}
  6192   ins_encode(store_P_reg_enc(mem, src));
  6193   ins_pipe( ialu_storeI );
  6194 %}
  6196 // Store NULL Pointer, mark word, or other simple pointer constant.
  6197 instruct storeImmP0(memory mem, immP0 zero) %{
  6198   match(Set mem (StoreP mem zero));
  6200   ins_cost(125);
  6201   format %{ "mov    $mem, $zero #@storeImmP0" %}
  6202   ins_encode(store_P_immP0_enc(mem));
  6203   ins_pipe( ialu_storeI );
  6204 %}
  6206 // Store Byte Immediate
  6207 instruct storeImmB(memory mem, immI8 src) %{
  6208   match(Set mem (StoreB mem src));
  6210   ins_cost(150);
  6211   format %{ "movb   $mem, $src #@storeImmB" %}
  6212   ins_encode(store_B_immI_enc(mem, src));
  6213   ins_pipe( ialu_storeI );
  6214 %}
  6216 // Store Compressed Pointer
  6217 instruct storeN(memory mem, mRegN src)
  6218 %{
  6219   match(Set mem (StoreN mem src));
  6221   ins_cost(125); // XXX
  6222   format %{ "sw    $mem, $src\t# compressed ptr @ storeN" %}
  6223   ins_encode(store_N_reg_enc(mem, src));
  6224   ins_pipe( ialu_storeI );
  6225 %}
  6227 instruct storeP2N(memory mem, mRegP src)
  6228 %{
  6229   match(Set mem (StoreN mem (EncodeP src)));
  6230   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6232   ins_cost(125); // XXX
  6233   format %{ "sw    $mem, $src\t# @ storeP2N" %}
  6234   ins_encode(store_N_reg_enc(mem, src));
  6235   ins_pipe( ialu_storeI );
  6236 %}
  6238 instruct storeNKlass(memory mem, mRegN src)
  6239 %{
  6240   match(Set mem (StoreNKlass mem src));
  6242   ins_cost(125); // XXX
  6243   format %{ "sw    $mem, $src\t# compressed klass ptr @ storeNKlass" %}
  6244   ins_encode(store_N_reg_enc(mem, src));
  6245   ins_pipe( ialu_storeI );
  6246 %}
  6248 instruct storeP2NKlass(memory mem, mRegP src)
  6249 %{
  6250   match(Set mem (StoreNKlass mem (EncodePKlass src)));
  6251   predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
  6253   ins_cost(125); // XXX
  6254   format %{ "sw    $mem, $src\t# @ storeP2NKlass" %}
  6255   ins_encode(store_N_reg_enc(mem, src));
  6256   ins_pipe( ialu_storeI );
  6257 %}
  6259 instruct storeImmN0(memory mem, immN0 zero)
  6260 %{
  6261   match(Set mem (StoreN mem zero));
  6263   ins_cost(125); // XXX
  6264   format %{ "storeN0    zero, $mem\t# compressed ptr" %}
  6265   ins_encode(storeImmN0_enc(mem, zero));
  6266   ins_pipe( ialu_storeI );
  6267 %}
  6269 // Store Byte
  6270 instruct storeB(memory mem, mRegI src) %{
  6271   match(Set mem (StoreB mem src));
  6273   ins_cost(125);
  6274   format %{ "sb    $src, $mem #@storeB" %}
  6275   ins_encode(store_B_reg_enc(mem, src));
  6276   ins_pipe( ialu_storeI );
  6277 %}
  6279 instruct storeB_convL2I(memory mem, mRegL src) %{
  6280   match(Set mem (StoreB mem (ConvL2I src)));
  6282   ins_cost(125);
  6283   format %{ "sb    $src, $mem #@storeB_convL2I" %}
  6284   ins_encode(store_B_reg_enc(mem, src));
  6285   ins_pipe( ialu_storeI );
  6286 %}
  6288 // Load Byte (8bit signed)
  6289 instruct loadB(mRegI dst, memory mem) %{
  6290   match(Set dst (LoadB mem));
  6292   ins_cost(125);
  6293   format %{ "lb   $dst, $mem #@loadB" %}
  6294   ins_encode(load_B_enc(dst, mem));
  6295   ins_pipe( ialu_loadI );
  6296 %}
  6298 instruct loadB_convI2L(mRegL dst, memory mem) %{
  6299   match(Set dst (ConvI2L (LoadB mem)));
  6301   ins_cost(125);
  6302   format %{ "lb   $dst, $mem #@loadB_convI2L" %}
  6303   ins_encode(load_B_enc(dst, mem));
  6304   ins_pipe( ialu_loadI );
  6305 %}
  6307 // Load Byte (8bit UNsigned)
  6308 instruct loadUB(mRegI dst, memory mem) %{
  6309   match(Set dst (LoadUB mem));
  6311   ins_cost(125);
  6312   format %{ "lbu   $dst, $mem #@loadUB" %}
  6313   ins_encode(load_UB_enc(dst, mem));
  6314   ins_pipe( ialu_loadI );
  6315 %}
  6317 instruct loadUB_convI2L(mRegL dst, memory mem) %{
  6318   match(Set dst (ConvI2L (LoadUB mem)));
  6320   ins_cost(125);
  6321   format %{ "lbu   $dst, $mem #@loadUB_convI2L" %}
  6322   ins_encode(load_UB_enc(dst, mem));
  6323   ins_pipe( ialu_loadI );
  6324 %}
  6326 // Load Short (16bit signed)
  6327 instruct loadS(mRegI dst, memory mem) %{
  6328   match(Set dst (LoadS mem));
  6330   ins_cost(125);
  6331   format %{ "lh   $dst, $mem #@loadS" %}
  6332   ins_encode(load_S_enc(dst, mem));
  6333   ins_pipe( ialu_loadI );
  6334 %}
  6336 // Load Short (16 bit signed) to Byte (8 bit signed)
  6337 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
  6338   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
  6340   ins_cost(125);
  6341   format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
  6342   ins_encode(load_B_enc(dst, mem));
  6343   ins_pipe(ialu_loadI);
  6344 %}
  6346 instruct loadS_convI2L(mRegL dst, memory mem) %{
  6347   match(Set dst (ConvI2L (LoadS mem)));
  6349   ins_cost(125);
  6350   format %{ "lh   $dst, $mem #@loadS_convI2L" %}
  6351   ins_encode(load_S_enc(dst, mem));
  6352   ins_pipe( ialu_loadI );
  6353 %}
  6355 // Store Integer Immediate
  6356 instruct storeImmI(memory mem, immI src) %{
  6357   match(Set mem (StoreI mem src));
  6359   ins_cost(150);
  6360   format %{ "mov    $mem, $src #@storeImmI" %}
  6361   ins_encode(store_I_immI_enc(mem, src));
  6362   ins_pipe( ialu_storeI );
  6363 %}
  6365 // Store Integer
  6366 instruct storeI(memory mem, mRegI src) %{
  6367   match(Set mem (StoreI mem src));
  6369   ins_cost(125);
  6370   format %{ "sw    $mem, $src #@storeI" %}
  6371   ins_encode(store_I_reg_enc(mem, src));
  6372   ins_pipe( ialu_storeI );
  6373 %}
  6375 instruct storeI_convL2I(memory mem, mRegL src) %{
  6376   match(Set mem (StoreI mem (ConvL2I src)));
  6378   ins_cost(125);
  6379   format %{ "sw    $mem, $src #@storeI_convL2I" %}
  6380   ins_encode(store_I_reg_enc(mem, src));
  6381   ins_pipe( ialu_storeI );
  6382 %}
  6384 // Load Float
  6385 instruct loadF(regF dst, memory mem) %{
  6386   match(Set dst (LoadF mem));
  6388   ins_cost(150);
  6389   format %{ "loadF $dst, $mem #@loadF" %}
  6390   ins_encode(load_F_enc(dst, mem));
  6391   ins_pipe( ialu_loadI );
  6392 %}
  6394 instruct loadConP_general(mRegP dst, immP src) %{
  6395   match(Set dst src);
  6397   ins_cost(120);
  6398   format %{ "li   $dst, $src #@loadConP_general" %}
  6400   ins_encode %{
  6401     Register dst = $dst$$Register;
  6402     long* value = (long*)$src$$constant;
  6404     if($src->constant_reloc() == relocInfo::metadata_type){
  6405       int klass_index = __ oop_recorder()->find_index((Klass*)value);
  6406       RelocationHolder rspec = metadata_Relocation::spec(klass_index);
  6408       __ relocate(rspec);
  6409       __ patchable_set48(dst, (long)value);
  6410     }else if($src->constant_reloc() == relocInfo::oop_type){
  6411       int oop_index = __ oop_recorder()->find_index((jobject)value);
  6412       RelocationHolder rspec = oop_Relocation::spec(oop_index);
  6414       __ relocate(rspec);
  6415       __ patchable_set48(dst, (long)value);
  6416     } else if ($src->constant_reloc() == relocInfo::none) {
  6417         __ set64(dst, (long)value);
  6419   %}
  6421   ins_pipe( ialu_regI_regI );
  6422 %}
  6424 /*
  6425 instruct loadConP_load(mRegP dst, immP_load src) %{
  6426   match(Set dst src);
  6428   ins_cost(100);
  6429   format %{ "ld     $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
  6431   ins_encode %{
  6433     int con_offset = $constantoffset($src);
  6435     if (Assembler::is_simm16(con_offset)) {
  6436        __ ld($dst$$Register, $constanttablebase, con_offset);
  6437     } else {
  6438        __ set64(AT, con_offset);
  6439        if (UseLoongsonISA) {
  6440           __ gsldx($dst$$Register, $constanttablebase, AT, 0);
  6441        } else {
  6442           __ daddu(AT, $constanttablebase, AT);
  6443           __ ld($dst$$Register, AT, 0);
  6446   %}
  6448   ins_pipe(ialu_loadI);
  6449 %}
  6450 */
  6452 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
  6453   match(Set dst src);
  6455   ins_cost(80);
  6456   format %{ "li    $dst, $src @ loadConP_no_oop_cheap" %}
  6458   ins_encode %{
  6459     __ set64($dst$$Register, $src$$constant);
  6460   %}
  6462   ins_pipe(ialu_regI_regI);
  6463 %}
  6466 instruct loadConP_poll(mRegP dst, immP_poll src) %{
  6467   match(Set dst src);
  6469   ins_cost(50);
  6470   format %{ "li   $dst, $src #@loadConP_poll" %}
  6472   ins_encode %{
  6473     Register dst = $dst$$Register;
  6474     intptr_t value = (intptr_t)$src$$constant;
  6476     __ set64(dst, (jlong)value);
  6477   %}
  6479   ins_pipe( ialu_regI_regI );
  6480 %}
  6482 instruct loadConP0(mRegP dst, immP0 src)
  6483 %{
  6484   match(Set dst src);
  6486   ins_cost(50);
  6487   format %{ "mov    $dst, R0\t# ptr" %}
  6488   ins_encode %{
  6489      Register dst_reg = $dst$$Register;
  6490      __ daddu(dst_reg, R0, R0);
  6491   %}
  6492   ins_pipe( ialu_regI_regI );
  6493 %}
  6495 instruct loadConN0(mRegN dst, immN0 src) %{
  6496   match(Set dst src);
  6497   format %{ "move    $dst, R0\t# compressed NULL ptr" %}
  6498   ins_encode %{
  6499     __ move($dst$$Register, R0);
  6500   %}
  6501   ins_pipe( ialu_regI_regI );
  6502 %}
  6504 instruct loadConN(mRegN dst, immN src) %{
  6505   match(Set dst src);
  6507   ins_cost(125);
  6508   format %{ "li    $dst, $src\t# compressed ptr @ loadConN" %}
  6509   ins_encode %{
  6510     Register dst = $dst$$Register;
  6511     __ set_narrow_oop(dst, (jobject)$src$$constant);
  6512   %}
  6513   ins_pipe( ialu_regI_regI ); // XXX
  6514 %}
  6516 instruct loadConNKlass(mRegN dst, immNKlass src) %{
  6517   match(Set dst src);
  6519   ins_cost(125);
  6520   format %{ "li    $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
  6521   ins_encode %{
  6522     Register dst = $dst$$Register;
  6523     __ set_narrow_klass(dst, (Klass*)$src$$constant);
  6524   %}
  6525   ins_pipe( ialu_regI_regI ); // XXX
  6526 %}
  6528 //FIXME
  6529 // Tail Call; Jump from runtime stub to Java code.
  6530 // Also known as an 'interprocedural jump'.
  6531 // Target of jump will eventually return to caller.
  6532 // TailJump below removes the return address.
  6533 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
  6534   match(TailCall jump_target method_oop );
  6535   ins_cost(300);
  6536   format %{ "JMP    $jump_target \t# @TailCalljmpInd" %}
  6538   ins_encode %{
  6539     Register target = $jump_target$$Register;
  6540     Register    oop = $method_oop$$Register;
  6542     /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
  6543     __ push(RA);
  6545     __ move(S3, oop);
  6546     __ jr(target);
  6547     __ nop();
  6548   %}
  6550   ins_pipe( pipe_jump );
  6551 %}
  6553 // Create exception oop: created by stack-crawling runtime code.
  6554 // Created exception is now available to this handler, and is setup
  6555 // just prior to jumping to this handler.  No code emitted.
  6556 instruct CreateException( a0_RegP ex_oop )
  6557 %{
  6558   match(Set ex_oop (CreateEx));
  6560   // use the following format syntax
  6561   format %{ "# exception oop is in A0; no code emitted @CreateException" %}
  6562   ins_encode %{
  6563     /* Jin: X86 leaves this function empty */
  6564     __ block_comment("CreateException is empty in X86/MIPS");
  6565   %}
  6566   ins_pipe( empty );
  6567 //  ins_pipe( pipe_jump );
  6568 %}
  6571 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
  6573 - Common try/catch:
  6574  2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
  6575                     |- V0, V1 are created
  6576                     |- T9 <= SharedRuntime::exception_handler_for_return_address
  6577                     `- jr T9
  6578                          `- the caller's exception_handler
  6579                                `- jr OptoRuntime::exception_blob
  6580                                       `- here
  6581 - Rethrow(e.g. 'unwind'):
  6582   * The callee:
  6583      |- an exception is triggered during execution
  6584      `- exits the callee method through RethrowException node
  6585           |- The callee pushes exception_oop(T0) and exception_pc(RA)
  6586           `- The callee jumps to OptoRuntime::rethrow_stub()
  6587   * In OptoRuntime::rethrow_stub:
  6588      |- The VM calls _rethrow_Java to determine the return address in the caller method
  6589      `- exits the stub with tailjmpInd
  6590           |- pops exception_oop(V0) and exception_pc(V1)
  6591           `- jumps to the return address(usually an exception_handler)
  6592   * The caller:
  6593      `- continues processing the exception_blob with V0/V1
  6594 */
  6596 /*
  6597 Disassembling OptoRuntime::rethrow_stub()
  6599 ; locals
  6600    0x2d3bf320: addiu sp, sp, 0xfffffff8
  6601    0x2d3bf324: sw ra, 0x4(sp)
  6602    0x2d3bf328: sw fp, 0x0(sp)
  6603    0x2d3bf32c: addu fp, sp, zero
  6604    0x2d3bf330: addiu sp, sp, 0xfffffff0
  6605    0x2d3bf334: sw ra, 0x8(sp)
  6606    0x2d3bf338: sw t0, 0x4(sp)
  6607    0x2d3bf33c: sw sp, 0x0(sp)
  6609 ; get_thread(S2)
  6610    0x2d3bf340: addu s2, sp, zero
  6611    0x2d3bf344: srl s2, s2, 12
  6612    0x2d3bf348: sll s2, s2, 2
  6613    0x2d3bf34c: lui at, 0x2c85
  6614    0x2d3bf350: addu at, at, s2
  6615    0x2d3bf354: lw s2, 0xffffcc80(at)
  6617    0x2d3bf358: lw s0, 0x0(sp)
  6618    0x2d3bf35c: sw s0, 0x118(s2)    // last_sp -> threa
  6619    0x2d3bf360: sw s2, 0xc(sp)
  6621 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
  6622    0x2d3bf364: lw a0, 0x4(sp)
  6623    0x2d3bf368: lw a1, 0xc(sp)
  6624    0x2d3bf36c: lw a2, 0x8(sp)
  6625   ;; Java_To_Runtime
  6626    0x2d3bf370: lui t9, 0x2c34
  6627    0x2d3bf374: addiu t9, t9, 0xffff8a48
  6628    0x2d3bf378: jalr t9
  6629    0x2d3bf37c: nop
  6631    0x2d3bf380: addu s3, v0, zero     ; S3: SharedRuntime::raw_exception_handler_for_return_address()
  6633    0x2d3bf384: lw s0, 0xc(sp)
  6634    0x2d3bf388: sw zero, 0x118(s0)
  6635    0x2d3bf38c: sw zero, 0x11c(s0)
  6636    0x2d3bf390: lw s1, 0x144(s0)      ; ex_oop: S1
  6637    0x2d3bf394: addu s2, s0, zero
  6638    0x2d3bf398: sw zero, 0x144(s2)
  6639    0x2d3bf39c: lw s0, 0x4(s2)
  6640    0x2d3bf3a0: addiu s4, zero, 0x0
  6641    0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
  6642    0x2d3bf3a8: nop
  6643    0x2d3bf3ac: addiu sp, sp, 0x10
  6644    0x2d3bf3b0: addiu sp, sp, 0x8
  6645    0x2d3bf3b4: lw ra, 0xfffffffc(sp)
  6646    0x2d3bf3b8: lw fp, 0xfffffff8(sp)
  6647    0x2d3bf3bc: lui at, 0x2b48
  6648    0x2d3bf3c0: lw at, 0x100(at)
  6650 ; tailjmpInd: Restores exception_oop & exception_pc
  6651    0x2d3bf3c4: addu v1, ra, zero
  6652    0x2d3bf3c8: addu v0, s1, zero
  6653    0x2d3bf3cc: jr s3
  6654    0x2d3bf3d0: nop
  6655 ; Exception:
  6656    0x2d3bf3d4: lui s1, 0x2cc8    ; generate_forward_exception()
  6657    0x2d3bf3d8: addiu s1, s1, 0x40
  6658    0x2d3bf3dc: addiu s2, zero, 0x0
  6659    0x2d3bf3e0: addiu sp, sp, 0x10
  6660    0x2d3bf3e4: addiu sp, sp, 0x8
  6661    0x2d3bf3e8: lw ra, 0xfffffffc(sp)
  6662    0x2d3bf3ec: lw fp, 0xfffffff8(sp)
  6663    0x2d3bf3f0: lui at, 0x2b48
  6664    0x2d3bf3f4: lw at, 0x100(at)
  6665 ; TailCalljmpInd
  6666               __ push(RA);    ; to be used in generate_forward_exception()
  6667    0x2d3bf3f8: addu t7, s2, zero
  6668    0x2d3bf3fc: jr s1
  6669    0x2d3bf400: nop
  6670 */
  6671 // Rethrow exception:
  6672 // The exception oop will come in the first argument position.
  6673 // Then JUMP (not call) to the rethrow stub code.
  6674 instruct RethrowException()
  6675 %{
  6676   match(Rethrow);
  6678   // use the following format syntax
  6679   format %{ "JMP    rethrow_stub #@RethrowException" %}
  6680   ins_encode %{
  6681     __ block_comment("@ RethrowException");
  6683     cbuf.set_insts_mark();
  6684     cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
  6686     // call OptoRuntime::rethrow_stub to get the exception handler in parent method
  6687     __ patchable_jump((address)OptoRuntime::rethrow_stub());
  6688   %}
  6689   ins_pipe( pipe_jump );
  6690 %}
  6692 instruct branchConP_zero(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
  6693   match(If cmp (CmpP op1 zero));
  6694   effect(USE labl);
  6696   ins_cost(180);
  6697   format %{ "b$cmp   $op1, R0, $labl #@branchConP_zero" %}
  6699   ins_encode %{
  6700     Register op1 = $op1$$Register;
  6701     Register op2 = R0;
  6702     Label    &L  = *($labl$$label);
  6703     int     flag = $cmp$$cmpcode;
  6705     switch(flag) {
  6706       case 0x01: //equal
  6707         if (&L)
  6708           __ beq(op1, op2, L);
  6709         else
  6710           __ beq(op1, op2, (int)0);
  6711         break;
  6712       case 0x02: //not_equal
  6713         if (&L)
  6714           __ bne(op1, op2, L);
  6715         else
  6716           __ bne(op1, op2, (int)0);
  6717         break;
  6718       default:
  6719         Unimplemented();
  6721     __ nop();
  6722   %}
  6724   ins_pc_relative(1);
  6725   ins_pipe( pipe_alu_branch );
  6726 %}
  6728 instruct branchConN2P_zero(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
  6729   match(If cmp (CmpP (DecodeN op1) zero));
  6730   predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
  6731   effect(USE labl);
  6733   ins_cost(180);
  6734   format %{ "b$cmp   $op1, R0, $labl #@branchConN2P_zero" %}
  6736   ins_encode %{
  6737     Register op1 = $op1$$Register;
  6738     Register op2 = R0;
  6739     Label    &L  = *($labl$$label);
  6740     int     flag = $cmp$$cmpcode;
  6742     switch(flag)
  6744       case 0x01: //equal
  6745         if (&L)
  6746           __ beq(op1, op2, L);
  6747         else
  6748           __ beq(op1, op2, (int)0);
  6749         break;
  6750       case 0x02: //not_equal
  6751         if (&L)
  6752           __ bne(op1, op2, L);
  6753         else
  6754           __ bne(op1, op2, (int)0);
  6755         break;
  6756       default:
  6757         Unimplemented();
  6759     __ nop();
  6760   %}
  6762   ins_pc_relative(1);
  6763   ins_pipe( pipe_alu_branch );
  6764 %}
  6767 instruct branchConP(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
  6768   match(If cmp (CmpP op1 op2));
  6769 //  predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
  6770   effect(USE labl);
  6772   ins_cost(200);
  6773   format %{ "b$cmp   $op1, $op2, $labl #@branchConP" %}
  6775   ins_encode %{
  6776     Register op1 = $op1$$Register;
  6777     Register op2 = $op2$$Register;
  6778     Label    &L  = *($labl$$label);
  6779     int     flag = $cmp$$cmpcode;
  6781     switch(flag) {
  6782       case 0x01: //equal
  6783         if (&L)
  6784           __ beq(op1, op2, L);
  6785         else
  6786           __ beq(op1, op2, (int)0);
  6787         break;
  6788       case 0x02: //not_equal
  6789         if (&L)
  6790           __ bne(op1, op2, L);
  6791         else
  6792           __ bne(op1, op2, (int)0);
  6793         break;
  6794       case 0x03: //above
  6795         __ sltu(AT, op2, op1);
  6796         if(&L)
  6797           __ bne(R0, AT, L);
  6798         else
  6799                 __ bne(R0, AT, (int)0);
  6800         break;
  6801       case 0x04: //above_equal
  6802         __ sltu(AT, op1, op2);
  6803         if(&L)
  6804                  __ beq(AT, R0, L);
  6805         else
  6806                  __ beq(AT, R0, (int)0);
  6807         break;
  6808       case 0x05: //below
  6809         __ sltu(AT, op1, op2);
  6810         if(&L)
  6811            __ bne(R0, AT, L);
  6812         else
  6813            __ bne(R0, AT, (int)0);
  6814         break;
  6815       case 0x06: //below_equal
  6816         __ sltu(AT, op2, op1);
  6817         if(&L)
  6818           __ beq(AT, R0, L);
  6819         else
  6820           __ beq(AT, R0, (int)0);
  6821        break;
  6822       default:
  6823           Unimplemented();
  6825     __ nop();
  6826   %}
  6828   ins_pc_relative(1);
  6829   ins_pipe( pipe_alu_branch );
  6830 %}
  6832 instruct cmpN_null_branch(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
  6833   match(If cmp (CmpN op1 null));
  6834   effect(USE labl);
  6836   ins_cost(180);
  6837   format %{ "CMP    $op1,0\t! compressed ptr\n\t"
  6838             "BP$cmp   $labl @ cmpN_null_branch" %}
  6839   ins_encode %{
  6840     Register op1 = $op1$$Register;
  6841     Register op2 = R0;
  6842     Label    &L  = *($labl$$label);
  6843     int     flag = $cmp$$cmpcode;
  6845     switch(flag) {
  6846     case 0x01: //equal
  6847       if (&L)
  6848         __ beq(op1, op2, L);
  6849       else
  6850         __ beq(op1, op2, (int)0);
  6851       break;
  6852     case 0x02: //not_equal
  6853       if (&L)
  6854         __ bne(op1, op2, L);
  6855       else
  6856         __ bne(op1, op2, (int)0);
  6857       break;
  6858     default:
  6859           Unimplemented();
  6861     __ nop();
  6862   %}
  6863 //TODO: pipe_branchP or create pipe_branchN LEE
  6864   ins_pc_relative(1);
  6865   ins_pipe( pipe_alu_branch );
  6866 %}
  6868 instruct cmpN_reg_branch(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
  6869   match(If cmp (CmpN op1 op2));
  6870   effect(USE labl);
  6872   ins_cost(180);
  6873   format %{ "CMP    $op1,$op2\t! compressed ptr\n\t"
  6874             "BP$cmp   $labl" %}
  6875   ins_encode %{
  6876     Register op1_reg = $op1$$Register;
  6877     Register op2_reg = $op2$$Register;
  6878     Label    &L  = *($labl$$label);
  6879     int     flag = $cmp$$cmpcode;
  6881     switch(flag) {
  6882     case 0x01: //equal
  6883       if (&L)
  6884         __ beq(op1_reg, op2_reg, L);
  6885       else
  6886         __ beq(op1_reg, op2_reg, (int)0);
  6887       break;
  6888     case 0x02: //not_equal
  6889       if (&L)
  6890         __ bne(op1_reg, op2_reg, L);
  6891       else
  6892         __ bne(op1_reg, op2_reg, (int)0);
  6893       break;
  6894     case 0x03: //above
  6895       __ sltu(AT, op2_reg, op1_reg);
  6896       if(&L)
  6897         __ bne(R0, AT, L);
  6898       else
  6899         __ bne(R0, AT, (int)0);
  6900       break;
  6901     case 0x04: //above_equal
  6902       __ sltu(AT, op1_reg, op2_reg);
  6903       if(&L)
  6904         __ beq(AT, R0, L);
  6905       else
  6906         __ beq(AT, R0, (int)0);
  6907       break;
  6908     case 0x05: //below
  6909       __ sltu(AT, op1_reg, op2_reg);
  6910       if(&L)
  6911         __ bne(R0, AT, L);
  6912       else
  6913         __ bne(R0, AT, (int)0);
  6914       break;
  6915     case 0x06: //below_equal
  6916       __ sltu(AT, op2_reg, op1_reg);
  6917       if(&L)
  6918         __ beq(AT, R0, L);
  6919       else
  6920         __ beq(AT, R0, (int)0);
  6921       break;
  6922     default:
  6923       Unimplemented();
  6925     __ nop();
  6926   %}
  6927   ins_pc_relative(1);
  6928   ins_pipe( pipe_alu_branch );
  6929 %}
  6931 instruct branchConIU_reg_reg(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
  6932   match( If cmp (CmpU src1 src2) );
  6933   effect(USE labl);
  6934   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_reg" %}
  6936   ins_encode %{
  6937     Register op1 = $src1$$Register;
  6938     Register op2 = $src2$$Register;
  6939     Label     &L = *($labl$$label);
  6940     int     flag = $cmp$$cmpcode;
  6942     switch(flag) {
  6943       case 0x01: //equal
  6944         if (&L)
  6945           __ beq(op1, op2, L);
  6946         else
  6947           __ beq(op1, op2, (int)0);
  6948         break;
  6949       case 0x02: //not_equal
  6950         if (&L)
  6951           __ bne(op1, op2, L);
  6952         else
  6953           __ bne(op1, op2, (int)0);
  6954         break;
  6955       case 0x03: //above
  6956         __ sltu(AT, op2, op1);
  6957         if(&L)
  6958           __ bne(AT, R0, L);
  6959         else
  6960                 __ bne(AT, R0, (int)0);
  6961         break;
  6962       case 0x04: //above_equal
  6963         __ sltu(AT, op1, op2);
  6964         if(&L)
  6965           __ beq(AT, R0, L);
  6966         else
  6967                 __ beq(AT, R0, (int)0);
  6968         break;
  6969       case 0x05: //below
  6970         __ sltu(AT, op1, op2);
  6971         if(&L)
  6972            __ bne(AT, R0, L);
  6973         else
  6974            __ bne(AT, R0, (int)0);
  6975         break;
  6976       case 0x06: //below_equal
  6977         __ sltu(AT, op2, op1);
  6978         if(&L)
  6979           __ beq(AT, R0, L);
  6980         else
  6981           __ beq(AT, R0, (int)0);
  6982         break;
  6983       default:
  6984         Unimplemented();
  6986     __ nop();
  6987   %}
  6989   ins_pc_relative(1);
  6990   ins_pipe( pipe_alu_branch );
  6991 %}
  6994 instruct branchConIU_reg_imm(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
  6995   match( If cmp (CmpU src1 src2) );
  6996   effect(USE labl);
  6997   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_imm" %}
  6999   ins_encode %{
  7000     Register op1 = $src1$$Register;
  7001     int      val = $src2$$constant;
  7002     Label     &L = *($labl$$label);
  7003     int     flag = $cmp$$cmpcode;
  7005     __ move(AT, val);
  7006     switch(flag) {
  7007       case 0x01: //equal
  7008         if (&L)
  7009           __ beq(op1, AT, L);
  7010         else
  7011           __ beq(op1, AT, (int)0);
  7012         break;
  7013       case 0x02: //not_equal
  7014         if (&L)
  7015           __ bne(op1, AT, L);
  7016         else
  7017           __ bne(op1, AT, (int)0);
  7018         break;
  7019       case 0x03: //above
  7020         __ sltu(AT, AT, op1);
  7021         if(&L)
  7022           __ bne(R0, AT, L);
  7023         else
  7024                 __ bne(R0, AT, (int)0);
  7025         break;
  7026       case 0x04: //above_equal
  7027         __ sltu(AT, op1, AT);
  7028         if(&L)
  7029           __ beq(AT, R0, L);
  7030         else
  7031                 __ beq(AT, R0, (int)0);
  7032         break;
  7033       case 0x05: //below
  7034         __ sltu(AT, op1, AT);
  7035         if(&L)
  7036            __ bne(R0, AT, L);
  7037         else
  7038            __ bne(R0, AT, (int)0);
  7039         break;
  7040       case 0x06: //below_equal
  7041         __ sltu(AT, AT, op1);
  7042         if(&L)
  7043           __ beq(AT, R0, L);
  7044         else
  7045           __ beq(AT, R0, (int)0);
  7046        break;
  7047       default:
  7048         Unimplemented();
  7050     __ nop();
  7051   %}
  7053   ins_pc_relative(1);
  7054   ins_pipe( pipe_alu_branch );
  7055 %}
  7057 instruct branchConI_reg_reg(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
  7058   match( If cmp (CmpI src1 src2) );
  7059   effect(USE labl);
  7060   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_reg" %}
  7062   ins_encode %{
  7063     Register op1 = $src1$$Register;
  7064     Register op2 = $src2$$Register;
  7065     Label     &L = *($labl$$label);
  7066     int     flag = $cmp$$cmpcode;
  7068     switch(flag) {
  7069       case 0x01: //equal
  7070         if (&L)
  7071           __ beq(op1, op2, L);
  7072         else
  7073           __ beq(op1, op2, (int)0);
  7074         break;
  7075       case 0x02: //not_equal
  7076         if (&L)
  7077           __ bne(op1, op2, L);
  7078         else
  7079           __ bne(op1, op2, (int)0);
  7080         break;
  7081       case 0x03: //above
  7082         __ slt(AT, op2, op1);
  7083         if(&L)
  7084           __ bne(R0, AT, L);
  7085         else
  7086                 __ bne(R0, AT, (int)0);
  7087         break;
  7088       case 0x04: //above_equal
  7089         __ slt(AT, op1, op2);
  7090         if(&L)
  7091           __ beq(AT, R0, L);
  7092         else
  7093                 __ beq(AT, R0, (int)0);
  7094         break;
  7095       case 0x05: //below
  7096         __ slt(AT, op1, op2);
  7097         if(&L)
  7098            __ bne(R0, AT, L);
  7099         else
  7100            __ bne(R0, AT, (int)0);
  7101         break;
  7102       case 0x06: //below_equal
  7103         __ slt(AT, op2, op1);
  7104         if(&L)
  7105           __ beq(AT, R0, L);
  7106         else
  7107           __ beq(AT, R0, (int)0);
  7108        break;
  7109       default:
  7110         Unimplemented();
  7112     __ nop();
  7113   %}
  7115   ins_pc_relative(1);
  7116   ins_pipe( pipe_alu_branch );
  7117 %}
  7119 instruct branchConI_reg_imm0(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
  7120   match( If cmp (CmpI src1 src2) );
  7121   effect(USE labl);
  7122   ins_cost(170);
  7123   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm0" %}
  7125   ins_encode %{
  7126     Register op1 = $src1$$Register;
  7127     Label     &L =  *($labl$$label);
  7128     int     flag = $cmp$$cmpcode;
  7130     switch(flag) {
  7131       case 0x01: //equal
  7132         if (&L)
  7133           __ beq(op1, R0, L);
  7134         else
  7135           __ beq(op1, R0, (int)0);
  7136         break;
  7137       case 0x02: //not_equal
  7138         if (&L)
  7139           __ bne(op1, R0, L);
  7140         else
  7141           __ bne(op1, R0, (int)0);
  7142         break;
  7143       case 0x03: //greater
  7144         if(&L)
  7145                __ bgtz(op1, L);
  7146         else
  7147                __ bgtz(op1, (int)0);
  7148         break;
  7149       case 0x04: //greater_equal
  7150         if(&L)
  7151                __ bgez(op1, L);
  7152         else
  7153                __ bgez(op1, (int)0);
  7154         break;
  7155       case 0x05: //less
  7156         if(&L)
  7157                 __ bltz(op1, L);
  7158         else
  7159                 __ bltz(op1, (int)0);
  7160         break;
  7161       case 0x06: //less_equal
  7162         if(&L)
  7163                __ blez(op1, L);
  7164         else
  7165                __ blez(op1, (int)0);
  7166        break;
  7167       default:
  7168         Unimplemented();
  7170     __ nop();
  7171   %}
  7173   ins_pc_relative(1);
  7174   ins_pipe( pipe_alu_branch );
  7175 %}
  7178 instruct branchConI_reg_imm(cmpOp cmp, mRegI src1, immI src2, label labl) %{
  7179   match( If cmp (CmpI src1 src2) );
  7180   effect(USE labl);
  7181   ins_cost(200);
  7182   format %{ "BR$cmp   $src1, $src2, $labl #@branchConI_reg_imm" %}
  7184   ins_encode %{
  7185     Register op1 = $src1$$Register;
  7186     int      val = $src2$$constant;
  7187     Label     &L =  *($labl$$label);
  7188     int     flag = $cmp$$cmpcode;
  7190     __ move(AT, val);
  7191     switch(flag) {
  7192       case 0x01: //equal
  7193         if (&L)
  7194           __ beq(op1, AT, L);
  7195         else
  7196           __ beq(op1, AT, (int)0);
  7197         break;
  7198       case 0x02: //not_equal
  7199         if (&L)
  7200           __ bne(op1, AT, L);
  7201         else
  7202           __ bne(op1, AT, (int)0);
  7203         break;
  7204       case 0x03: //greater
  7205         __ slt(AT, AT, op1);
  7206         if(&L)
  7207           __ bne(R0, AT, L);
  7208         else
  7209                 __ bne(R0, AT, (int)0);
  7210         break;
  7211       case 0x04: //greater_equal
  7212         __ slt(AT, op1, AT);
  7213         if(&L)
  7214           __ beq(AT, R0, L);
  7215         else
  7216                 __ beq(AT, R0, (int)0);
  7217         break;
  7218       case 0x05: //less
  7219         __ slt(AT, op1, AT);
  7220         if(&L)
  7221            __ bne(R0, AT, L);
  7222         else
  7223            __ bne(R0, AT, (int)0);
  7224         break;
  7225       case 0x06: //less_equal
  7226         __ slt(AT, AT, op1);
  7227         if(&L)
  7228           __ beq(AT, R0, L);
  7229         else
  7230           __ beq(AT, R0, (int)0);
  7231        break;
  7232       default:
  7233           Unimplemented();
  7235     __ nop();
  7236   %}
  7238   ins_pc_relative(1);
  7239   ins_pipe( pipe_alu_branch );
  7240 %}
  7242 instruct branchConIU_reg_imm0(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
  7243   match( If cmp (CmpU src1 zero) );
  7244   effect(USE labl);
  7245   format %{ "BR$cmp   $src1, zero, $labl #@branchConIU_reg_imm0" %}
  7247   ins_encode %{
  7248     Register op1 = $src1$$Register;
  7249     Label     &L = *($labl$$label);
  7250     int     flag = $cmp$$cmpcode;
  7252     switch(flag) {
  7253       case 0x01: //equal
  7254         if (&L)
  7255           __ beq(op1, R0, L);
  7256         else
  7257           __ beq(op1, R0, (int)0);
  7258         break;
  7259       case 0x02: //not_equal
  7260         if (&L)
  7261           __ bne(op1, R0, L);
  7262         else
  7263           __ bne(op1, R0, (int)0);
  7264         break;
  7265       case 0x03: //above
  7266         if(&L)
  7267           __ bne(R0, op1, L);
  7268         else
  7269           __ bne(R0, op1, (int)0);
  7270         break;
  7271       case 0x04: //above_equal
  7272         if(&L)
  7273           __ beq(R0, R0, L);
  7274         else
  7275           __ beq(R0, R0, (int)0);
  7276         break;
  7277       case 0x05: //below
  7278         return;
  7279         break;
  7280       case 0x06: //below_equal
  7281         if(&L)
  7282           __ beq(op1, R0, L);
  7283         else
  7284           __ beq(op1, R0, (int)0);
  7285         break;
  7286       default:
  7287         Unimplemented();
  7289     __ nop();
  7290     %}
  7292   ins_pc_relative(1);
  7293   ins_pipe( pipe_alu_branch );
  7294 %}
  7297 instruct branchConIU_reg_immI16(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
  7298   match( If cmp (CmpU src1 src2) );
  7299   effect(USE labl);
  7300   ins_cost(180);
  7301   format %{ "BR$cmp   $src1, $src2, $labl #@branchConIU_reg_immI16" %}
  7303   ins_encode %{
  7304     Register op1 = $src1$$Register;
  7305     int      val = $src2$$constant;
  7306     Label     &L = *($labl$$label);
  7307     int     flag = $cmp$$cmpcode;
  7309     switch(flag) {
  7310       case 0x01: //equal
  7311         __ move(AT, val);
  7312         if (&L)
  7313           __ beq(op1, AT, L);
  7314         else
  7315           __ beq(op1, AT, (int)0);
  7316         break;
  7317       case 0x02: //not_equal
  7318         __ move(AT, val);
  7319         if (&L)
  7320           __ bne(op1, AT, L);
  7321         else
  7322           __ bne(op1, AT, (int)0);
  7323         break;
  7324       case 0x03: //above
  7325         __ move(AT, val);
  7326         __ sltu(AT, AT, op1);
  7327         if(&L)
  7328           __ bne(R0, AT, L);
  7329         else
  7330           __ bne(R0, AT, (int)0);
  7331         break;
  7332       case 0x04: //above_equal
  7333         __ sltiu(AT, op1, val);
  7334         if(&L)
  7335           __ beq(AT, R0, L);
  7336         else
  7337           __ beq(AT, R0, (int)0);
  7338         break;
  7339       case 0x05: //below
  7340         __ sltiu(AT, op1, val);
  7341         if(&L)
  7342           __ bne(R0, AT, L);
  7343         else
  7344           __ bne(R0, AT, (int)0);
  7345         break;
  7346       case 0x06: //below_equal
  7347         __ move(AT, val);
  7348         __ sltu(AT, AT, op1);
  7349         if(&L)
  7350           __ beq(AT, R0, L);
  7351         else
  7352           __ beq(AT, R0, (int)0);
  7353         break;
  7354       default:
  7355         Unimplemented();
  7357     __ nop();
  7358   %}
  7360   ins_pc_relative(1);
  7361   ins_pipe( pipe_alu_branch );
  7362 %}
  7365 instruct branchConL_regL_regL(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
  7366   match( If cmp (CmpL src1 src2) );
  7367   effect(USE labl);
  7368   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_regL" %}
  7369   ins_cost(250);
  7371   ins_encode %{
  7372     Register opr1_reg = as_Register($src1$$reg);
  7373     Register opr2_reg = as_Register($src2$$reg);
  7375     Label   &target = *($labl$$label);
  7376     int     flag = $cmp$$cmpcode;
  7378     switch(flag) {
  7379       case 0x01: //equal
  7380         if (&target)
  7381           __ beq(opr1_reg, opr2_reg, target);
  7382         else
  7383           __ beq(opr1_reg, opr2_reg, (int)0);
  7384         __ delayed()->nop();
  7385         break;
  7387       case 0x02: //not_equal
  7388         if(&target)
  7389           __ bne(opr1_reg, opr2_reg, target);
  7390         else
  7391           __ bne(opr1_reg, opr2_reg, (int)0);
  7392         __ delayed()->nop();
  7393         break;
  7395       case 0x03: //greater
  7396         __ slt(AT, opr2_reg, opr1_reg);
  7397         if(&target)
  7398           __ bne(AT, R0, target);
  7399         else
  7400           __ bne(AT, R0, (int)0);
  7401         __ delayed()->nop();
  7402         break;
  7404       case 0x04: //greater_equal
  7405         __ slt(AT, opr1_reg, opr2_reg);
  7406         if(&target)
  7407           __ beq(AT, R0, target);
  7408         else
  7409           __ beq(AT, R0, (int)0);
  7410         __ delayed()->nop();
  7412         break;
  7414       case 0x05: //less
  7415         __ slt(AT, opr1_reg, opr2_reg);
  7416         if(&target)
  7417           __ bne(AT, R0, target);
  7418         else
  7419           __ bne(AT, R0, (int)0);
  7420         __ delayed()->nop();
  7422         break;
  7424       case 0x06: //less_equal
  7425         __ slt(AT, opr2_reg, opr1_reg);
  7427         if(&target)
  7428           __ beq(AT, R0, target);
  7429         else
  7430           __ beq(AT, R0, (int)0);
  7431         __ delayed()->nop();
  7433         break;
  7435       default:
  7436         Unimplemented();
  7438   %}
  7441   ins_pc_relative(1);
  7442   ins_pipe( pipe_alu_branch );
  7443 %}
  7446 instruct branchConL_regL_immL0(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
  7447   match( If cmp (CmpL src1 zero) );
  7448   effect(USE labl);
  7449   format %{ "BR$cmp   $src1, zero, $labl #@branchConL_regL_immL0" %}
  7450   ins_cost(150);
  7452   ins_encode %{
  7453     Register opr1_reg = as_Register($src1$$reg);
  7454     Label   &target = *($labl$$label);
  7455     int     flag = $cmp$$cmpcode;
  7457     switch(flag) {
  7458       case 0x01: //equal
  7459         if (&target)
  7460            __ beq(opr1_reg, R0, target);
  7461         else
  7462            __ beq(opr1_reg, R0, int(0));
  7463         break;
  7465       case 0x02: //not_equal
  7466         if(&target)
  7467            __ bne(opr1_reg, R0, target);
  7468         else
  7469            __ bne(opr1_reg, R0, (int)0);
  7470         break;
  7472       case 0x03: //greater
  7473         if(&target)
  7474            __ bgtz(opr1_reg, target);
  7475         else
  7476            __ bgtz(opr1_reg, (int)0);
  7477        break;
  7479       case 0x04: //greater_equal
  7480         if(&target)
  7481            __ bgez(opr1_reg, target);
  7482         else
  7483            __ bgez(opr1_reg, (int)0);
  7484         break;
  7486       case 0x05: //less
  7487         __ slt(AT, opr1_reg, R0);
  7488         if(&target)
  7489            __ bne(AT, R0, target);
  7490         else
  7491            __ bne(AT, R0, (int)0);
  7492         break;
  7494       case 0x06: //less_equal
  7495         if (&target)
  7496            __ blez(opr1_reg, target);
  7497         else
  7498            __ blez(opr1_reg, int(0));
  7499         break;
  7501       default:
  7502           Unimplemented();
  7504     __ delayed()->nop();
  7505   %}
  7508   ins_pc_relative(1);
  7509   ins_pipe( pipe_alu_branch );
  7510 %}
  7512 instruct branchConL_regL_immL(cmpOp cmp, mRegL src1, immL src2, label labl) %{
  7513   match( If cmp (CmpL src1 src2) );
  7514   effect(USE labl);
  7515   format %{ "BR$cmp   $src1, $src2, $labl #@branchConL_regL_immL" %}
  7516   ins_cost(180);
  7518   ins_encode %{
  7519     Register opr1_reg = as_Register($src1$$reg);
  7520     Register opr2_reg = AT;
  7522     Label   &target = *($labl$$label);
  7523     int     flag = $cmp$$cmpcode;
  7525     __ set64(opr2_reg, $src2$$constant);
  7527     switch(flag) {
  7528       case 0x01: //equal
  7529         if (&target)
  7530           __ beq(opr1_reg, opr2_reg, target);
  7531         else
  7532           __ beq(opr1_reg, opr2_reg, (int)0);
  7533         break;
  7535       case 0x02: //not_equal
  7536         if(&target)
  7537           __ bne(opr1_reg, opr2_reg, target);
  7538         else
  7539           __ bne(opr1_reg, opr2_reg, (int)0);
  7540         break;
  7542       case 0x03: //greater
  7543         __ slt(AT, opr2_reg, opr1_reg);
  7544         if(&target)
  7545           __ bne(AT, R0, target);
  7546         else
  7547           __ bne(AT, R0, (int)0);
  7548         break;
  7550       case 0x04: //greater_equal
  7551         __ slt(AT, opr1_reg, opr2_reg);
  7552         if(&target)
  7553           __ beq(AT, R0, target);
  7554         else
  7555           __ beq(AT, R0, (int)0);
  7556         break;
  7558       case 0x05: //less
  7559         __ slt(AT, opr1_reg, opr2_reg);
  7560         if(&target)
  7561           __ bne(AT, R0, target);
  7562         else
  7563           __ bne(AT, R0, (int)0);
  7564         break;
  7566       case 0x06: //less_equal
  7567         __ slt(AT, opr2_reg, opr1_reg);
  7568         if(&target)
  7569           __ beq(AT, R0, target);
  7570         else
  7571           __ beq(AT, R0, (int)0);
  7572         break;
  7574       default:
  7575         Unimplemented();
  7577     __ nop();
  7578   %}
  7581   ins_pc_relative(1);
  7582   ins_pipe( pipe_alu_branch );
  7583 %}
  7586 //FIXME
  7587 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{
  7588   match( If cmp (CmpF src1 src2) );
  7589   effect(USE labl);
  7590   format %{ "BR$cmp   $src1, $src2, $labl #@branchConF_reg_reg" %}
  7592   ins_encode %{
  7593     FloatRegister reg_op1 = $src1$$FloatRegister;
  7594     FloatRegister reg_op2 = $src2$$FloatRegister;
  7595     Label     &L =  *($labl$$label);
  7596     int     flag = $cmp$$cmpcode;
  7598     switch(flag) {
  7599       case 0x01: //equal
  7600         __ c_eq_s(reg_op1, reg_op2);
  7601         if (&L)
  7602           __ bc1t(L);
  7603         else
  7604           __ bc1t((int)0);
  7605         break;
  7606       case 0x02: //not_equal
  7607         __ c_eq_s(reg_op1, reg_op2);
  7608         if (&L)
  7609           __ bc1f(L);
  7610         else
  7611           __ bc1f((int)0);
  7612         break;
  7613       case 0x03: //greater
  7614         __ c_ule_s(reg_op1, reg_op2);
  7615         if(&L)
  7616           __ bc1f(L);
  7617         else
  7618           __ bc1f((int)0);
  7619         break;
  7620       case 0x04: //greater_equal
  7621         __ c_ult_s(reg_op1, reg_op2);
  7622         if(&L)
  7623           __ bc1f(L);
  7624         else
  7625           __ bc1f((int)0);
  7626         break;
  7627       case 0x05: //less
  7628         __ c_ult_s(reg_op1, reg_op2);
  7629         if(&L)
  7630           __ bc1t(L);
  7631         else
  7632           __ bc1t((int)0);
  7633         break;
  7634       case 0x06: //less_equal
  7635         __ c_ule_s(reg_op1, reg_op2);
  7636         if(&L)
  7637           __ bc1t(L);
  7638         else
  7639           __ bc1t((int)0);
  7640         break;
  7641       default:
  7642         Unimplemented();
  7644     __ nop();
  7645   %}
  7647   ins_pc_relative(1);
  7648   ins_pipe(pipe_slow);
  7649 %}
  7651 instruct branchConD_reg_reg(cmpOp cmp, regD src1, regD src2, label labl) %{
  7652   match( If cmp (CmpD src1 src2) );
  7653   effect(USE labl);
  7654   format %{ "BR$cmp   $src1, $src2, $labl #@branchConD_reg_reg" %}
  7656   ins_encode %{
  7657     FloatRegister reg_op1 = $src1$$FloatRegister;
  7658     FloatRegister reg_op2 = $src2$$FloatRegister;
  7659     Label     &L =  *($labl$$label);
  7660     int     flag = $cmp$$cmpcode;
  7662     switch(flag) {
  7663       case 0x01: //equal
  7664         __ c_eq_d(reg_op1, reg_op2);
  7665         if (&L)
  7666           __ bc1t(L);
  7667         else
  7668           __ bc1t((int)0);
  7669         break;
  7670       case 0x02: //not_equal
  7671         //2016/4/19 aoqi: c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
  7672         __ c_eq_d(reg_op1, reg_op2);
  7673         if (&L)
  7674           __ bc1f(L);
  7675         else
  7676           __ bc1f((int)0);
  7677         break;
  7678       case 0x03: //greater
  7679         __ c_ule_d(reg_op1, reg_op2);
  7680         if(&L)
  7681           __ bc1f(L);
  7682         else
  7683           __ bc1f((int)0);
  7684         break;
  7685       case 0x04: //greater_equal
  7686         __ c_ult_d(reg_op1, reg_op2);
  7687         if(&L)
  7688           __ bc1f(L);
  7689         else
  7690           __ bc1f((int)0);
  7691         break;
  7692       case 0x05: //less
  7693         __ c_ult_d(reg_op1, reg_op2);
  7694         if(&L)
  7695           __ bc1t(L);
  7696         else
  7697           __ bc1t((int)0);
  7698         break;
  7699       case 0x06: //less_equal
  7700         __ c_ule_d(reg_op1, reg_op2);
  7701         if(&L)
  7702           __ bc1t(L);
  7703         else
  7704           __ bc1t((int)0);
  7705         break;
  7706       default:
  7707         Unimplemented();
  7709     __ nop();
  7710   %}
  7712   ins_pc_relative(1);
  7713   ins_pipe(pipe_slow);
  7714 %}
  7717 // Call Runtime Instruction
  7718 instruct CallRuntimeDirect(method meth) %{
  7719   match(CallRuntime );
  7720   effect(USE meth);
  7722   ins_cost(300);
  7723   format %{ "CALL,runtime #@CallRuntimeDirect" %}
  7724   ins_encode( Java_To_Runtime( meth ) );
  7725   ins_pipe( pipe_slow );
  7726   ins_alignment(16);
  7727 %}
  7731 //------------------------MemBar Instructions-------------------------------
  7732 //Memory barrier flavors
  7734 instruct membar_acquire() %{
  7735   match(MemBarAcquire);
  7736   ins_cost(400);
  7738   format %{ "MEMBAR-acquire (empty) @ membar_acquire" %}
  7739   ins_encode %{
  7740     __ sync(); 
  7741   %}
  7742   ins_pipe(empty);
  7743 %}
  7745 instruct load_fence() %{
  7746   match(LoadFence);
  7747   ins_cost(400);
  7749   format %{ "MEMBAR @ load_fence" %}
  7750   ins_encode %{
  7751     __ sync();
  7752   %}
  7753   ins_pipe(pipe_slow);
  7754 %}
  7756 instruct membar_acquire_lock()
  7757 %{
  7758   match(MemBarAcquireLock);
  7759   ins_cost(0);
  7761   size(0);
  7762   format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
  7763   ins_encode();
  7764   ins_pipe(empty);
  7765 %}
  7767 instruct membar_release() %{
  7768   match(MemBarRelease);
  7769   ins_cost(400);
  7771   format %{ "MEMBAR-release @ membar_release" %}
  7773   ins_encode %{
  7774     // Attention: DO NOT DELETE THIS GUY!
  7775     __ sync();
  7776   %}
  7778   ins_pipe(pipe_slow);
  7779 %}
  7781 instruct store_fence() %{
  7782   match(StoreFence);
  7783   ins_cost(400);
  7785   format %{ "MEMBAR @ store_fence" %}
  7787   ins_encode %{
  7788     __ sync();
  7789   %}
  7791   ins_pipe(pipe_slow);
  7792 %}
  7794 instruct membar_release_lock()
  7795 %{
  7796   match(MemBarReleaseLock);
  7797   ins_cost(0);
  7799   size(0);
  7800   format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
  7801   ins_encode();
  7802   ins_pipe(empty);
  7803 %}
  7806 instruct membar_volatile() %{
  7807   match(MemBarVolatile);
  7808   ins_cost(400);
  7810   format %{ "MEMBAR-volatile" %}
  7811   ins_encode %{
  7812     if( !os::is_MP() ) return;     // Not needed on single CPU
  7813     __ sync();
  7815   %}
  7816   ins_pipe(pipe_slow);
  7817 %}
  7819 instruct unnecessary_membar_volatile() %{
  7820   match(MemBarVolatile);
  7821   predicate(Matcher::post_store_load_barrier(n));
  7822   ins_cost(0);
  7824   size(0);
  7825   format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
  7826   ins_encode( );
  7827   ins_pipe(empty);
  7828 %}
  7830 instruct membar_storestore() %{
  7831   match(MemBarStoreStore);
  7833   ins_cost(400);
  7834   format %{ "MEMBAR-storestore (empty encoding) @ membar_storestore" %}
  7835   ins_encode %{
  7836     __ sync();
  7837   %}
  7838   ins_pipe(empty);
  7839 %}
  7841 //----------Move Instructions--------------------------------------------------
  7842 instruct castX2P(mRegP dst, mRegL src) %{
  7843   match(Set dst (CastX2P src));
  7844   format %{ "castX2P  $dst, $src @ castX2P" %}
  7845   ins_encode %{
  7846     Register src = $src$$Register;
  7847     Register dst = $dst$$Register;
  7849   if(src != dst)
  7850     __ move(dst, src);
  7851   %}
  7852   ins_cost(10);
  7853   ins_pipe( ialu_regI_mov );
  7854 %}
  7856 instruct castP2X(mRegL dst, mRegP src ) %{
  7857   match(Set dst (CastP2X src));
  7859   format %{ "mov    $dst, $src\t  #@castP2X" %}
  7860   ins_encode %{
  7861     Register src = $src$$Register;
  7862     Register dst = $dst$$Register;
  7864   if(src != dst)
  7865     __ move(dst, src);
  7866   %}
  7867   ins_pipe( ialu_regI_mov );
  7868 %}
  7870 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
  7871   match(Set dst (MoveF2I src));
  7872   effect(DEF dst, USE src);
  7873   ins_cost(85);
  7874   format %{ "MoveF2I   $dst, $src @ MoveF2I_reg_reg" %}
  7875   ins_encode %{
  7876     Register dst = as_Register($dst$$reg);
  7877     FloatRegister src = as_FloatRegister($src$$reg);
  7879     __ mfc1(dst, src);
  7880   %}
  7881   ins_pipe( pipe_slow );
  7882 %}
  7884 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
  7885   match(Set dst (MoveI2F src));
  7886   effect(DEF dst, USE src);
  7887   ins_cost(85);
  7888   format %{ "MoveI2F   $dst, $src @ MoveI2F_reg_reg" %}
  7889   ins_encode %{
  7890     Register src = as_Register($src$$reg);
  7891     FloatRegister dst = as_FloatRegister($dst$$reg);
  7893     __ mtc1(src, dst);
  7894   %}
  7895   ins_pipe( pipe_slow );
  7896 %}
  7898 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
  7899   match(Set dst (MoveD2L src));
  7900   effect(DEF dst, USE src);
  7901   ins_cost(85);
  7902   format %{ "MoveD2L   $dst, $src @ MoveD2L_reg_reg" %}
  7903   ins_encode %{
  7904     Register dst = as_Register($dst$$reg);
  7905     FloatRegister src = as_FloatRegister($src$$reg);
  7907     __ dmfc1(dst, src);
  7908   %}
  7909   ins_pipe( pipe_slow );
  7910 %}
  7912 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
  7913   match(Set dst (MoveL2D src));
  7914   effect(DEF dst, USE src);
  7915   ins_cost(85);
  7916   format %{ "MoveL2D   $dst, $src @ MoveL2D_reg_reg" %}
  7917   ins_encode %{
  7918     FloatRegister dst = as_FloatRegister($dst$$reg);
  7919     Register src = as_Register($src$$reg);
  7921     __ dmtc1(src, dst);
  7922   %}
  7923   ins_pipe( pipe_slow );
  7924 %}
  7926 //----------Conditional Move---------------------------------------------------
  7927 // Conditional move
  7928 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  7929   match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  7930   ins_cost(80);
  7931   format %{
  7932              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpI_reg_reg\n"
  7933              "\tCMOV  $dst,$src \t @cmovI_cmpI_reg_reg"
  7934          %}
  7936   ins_encode %{
  7937     Register op1 = $tmp1$$Register;
  7938     Register op2 = $tmp2$$Register;
  7939     Register dst = $dst$$Register;
  7940     Register src = $src$$Register;
  7941     int     flag = $cop$$cmpcode;
  7943     switch(flag) {
  7944       case 0x01: //equal
  7945         __ subu32(AT, op1, op2);
  7946         __ movz(dst, src, AT);
  7947         break;
  7949       case 0x02: //not_equal
  7950         __ subu32(AT, op1, op2);
  7951         __ movn(dst, src, AT);
  7952         break;
  7954       case 0x03: //great
  7955         __ slt(AT, op2, op1);
  7956         __ movn(dst, src, AT);
  7957         break;
  7959       case 0x04: //great_equal
  7960         __ slt(AT, op1, op2);
  7961         __ movz(dst, src, AT);
  7962         break;
  7964       case 0x05: //less
  7965         __ slt(AT, op1, op2);
  7966         __ movn(dst, src, AT);
  7967         break;
  7969       case 0x06: //less_equal
  7970         __ slt(AT, op2, op1);
  7971         __ movz(dst, src, AT);
  7972        break;
  7974       default:
  7975         Unimplemented();
  7977   %}
  7979   ins_pipe( pipe_slow );
  7980 %}
  7982 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  7983   match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  7984   ins_cost(80);
  7985   format %{
  7986              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
  7987              "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
  7988          %}
  7989   ins_encode %{
  7990     Register op1 = $tmp1$$Register;
  7991     Register op2 = $tmp2$$Register;
  7992     Register dst = $dst$$Register;
  7993     Register src = $src$$Register;
  7994     int     flag = $cop$$cmpcode;
  7996     switch(flag) {
  7997       case 0x01: //equal
  7998         __ subu(AT, op1, op2);
  7999         __ movz(dst, src, AT);
  8000         break;
  8002       case 0x02: //not_equal
  8003         __ subu(AT, op1, op2);
  8004         __ movn(dst, src, AT);
  8005         break;
  8007       case 0x03: //above
  8008         __ sltu(AT, op2, op1);
  8009         __ movn(dst, src, AT);
  8010         break;
  8012       case 0x04: //above_equal
  8013         __ sltu(AT, op1, op2);
  8014         __ movz(dst, src, AT);
  8015         break;
  8017       case 0x05: //below
  8018         __ sltu(AT, op1, op2);
  8019         __ movn(dst, src, AT);
  8020         break;
  8022       case 0x06: //below_equal
  8023         __ sltu(AT, op2, op1);
  8024         __ movz(dst, src, AT);
  8025        break;
  8027       default:
  8028         Unimplemented();
  8030   %}
  8032   ins_pipe( pipe_slow );
  8033 %}
  8035 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  8036   match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  8037   ins_cost(80);
  8038   format %{
  8039              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
  8040              "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
  8041          %}
  8042   ins_encode %{
  8043     Register op1 = $tmp1$$Register;
  8044     Register op2 = $tmp2$$Register;
  8045     Register dst = $dst$$Register;
  8046     Register src = $src$$Register;
  8047     int     flag = $cop$$cmpcode;
  8049     switch(flag) {
  8050       case 0x01: //equal
  8051         __ subu32(AT, op1, op2);
  8052         __ movz(dst, src, AT);
  8053         break;
  8055       case 0x02: //not_equal
  8056         __ subu32(AT, op1, op2);
  8057         __ movn(dst, src, AT);
  8058         break;
  8060       case 0x03: //above
  8061         __ sltu(AT, op2, op1);
  8062         __ movn(dst, src, AT);
  8063         break;
  8065       case 0x04: //above_equal
  8066         __ sltu(AT, op1, op2);
  8067         __ movz(dst, src, AT);
  8068         break;
  8070       case 0x05: //below
  8071         __ sltu(AT, op1, op2);
  8072         __ movn(dst, src, AT);
  8073         break;
  8075       case 0x06: //below_equal
  8076         __ sltu(AT, op2, op1);
  8077         __ movz(dst, src, AT);
  8078        break;
  8080       default:
  8081           Unimplemented();
  8083   %}
  8085   ins_pipe( pipe_slow );
  8086 %}
  8088 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  8089   match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  8090   ins_cost(80);
  8091   format %{
  8092              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
  8093              "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
  8094          %}
  8095   ins_encode %{
  8096     Register op1 = $tmp1$$Register;
  8097     Register op2 = $tmp2$$Register;
  8098     Register dst = $dst$$Register;
  8099     Register src = $src$$Register;
  8100     int     flag = $cop$$cmpcode;
  8102     switch(flag) {
  8103       case 0x01: //equal
  8104         __ subu32(AT, op1, op2);
  8105         __ movz(dst, src, AT);
  8106         break;
  8108       case 0x02: //not_equal
  8109         __ subu32(AT, op1, op2);
  8110         __ movn(dst, src, AT);
  8111         break;
  8113       case 0x03: //above
  8114         __ sltu(AT, op2, op1);
  8115         __ movn(dst, src, AT);
  8116         break;
  8118       case 0x04: //above_equal
  8119         __ sltu(AT, op1, op2);
  8120         __ movz(dst, src, AT);
  8121         break;
  8123       case 0x05: //below
  8124         __ sltu(AT, op1, op2);
  8125         __ movn(dst, src, AT);
  8126         break;
  8128       case 0x06: //below_equal
  8129         __ sltu(AT, op2, op1);
  8130         __ movz(dst, src, AT);
  8131        break;
  8133       default:
  8134           Unimplemented();
  8136   %}
  8138   ins_pipe( pipe_slow );
  8139 %}
  8141 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
  8142   match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  8143   ins_cost(80);
  8144   format %{
  8145              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpF_reg_reg\n"
  8146              "\tCMOV  $dst,$src \t @cmovP_cmpF_reg_reg"
  8147          %}
  8149   ins_encode %{
  8150     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  8151     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  8152     Register dst = $dst$$Register;
  8153     Register src = $src$$Register;
  8154     int     flag = $cop$$cmpcode;
  8156     switch(flag) {
  8157       case 0x01: //equal
  8158         __ c_eq_s(reg_op1, reg_op2);
  8159         __ movt(dst, src);
  8160         break;
  8161       case 0x02: //not_equal
  8162         __ c_eq_s(reg_op1, reg_op2);
  8163         __ movf(dst, src);
  8164         break;
  8165       case 0x03: //greater
  8166         __ c_ole_s(reg_op1, reg_op2);
  8167         __ movf(dst, src);
  8168         break;
  8169       case 0x04: //greater_equal
  8170         __ c_olt_s(reg_op1, reg_op2);
  8171         __ movf(dst, src);
  8172         break;
  8173       case 0x05: //less
  8174         __ c_ult_s(reg_op1, reg_op2);
  8175         __ movt(dst, src);
  8176         break;
  8177       case 0x06: //less_equal
  8178         __ c_ule_s(reg_op1, reg_op2);
  8179         __ movt(dst, src);
  8180         break;
  8181       default:
  8182         Unimplemented();
  8184   %}
  8185   ins_pipe( pipe_slow );
  8186 %}
  8188 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  8189   match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  8190   ins_cost(80);
  8191   format %{
  8192              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
  8193              "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
  8194          %}
  8195   ins_encode %{
  8196     Register op1 = $tmp1$$Register;
  8197     Register op2 = $tmp2$$Register;
  8198     Register dst = $dst$$Register;
  8199     Register src = $src$$Register;
  8200     int     flag = $cop$$cmpcode;
  8202     switch(flag) {
  8203       case 0x01: //equal
  8204         __ subu32(AT, op1, op2);
  8205         __ movz(dst, src, AT);
  8206         break;
  8208       case 0x02: //not_equal
  8209         __ subu32(AT, op1, op2);
  8210         __ movn(dst, src, AT);
  8211         break;
  8213       case 0x03: //above
  8214         __ sltu(AT, op2, op1);
  8215         __ movn(dst, src, AT);
  8216         break;
  8218       case 0x04: //above_equal
  8219         __ sltu(AT, op1, op2);
  8220         __ movz(dst, src, AT);
  8221         break;
  8223       case 0x05: //below
  8224         __ sltu(AT, op1, op2);
  8225         __ movn(dst, src, AT);
  8226         break;
  8228       case 0x06: //below_equal
  8229         __ sltu(AT, op2, op1);
  8230         __ movz(dst, src, AT);
  8231        break;
  8233       default:
  8234         Unimplemented();
  8236   %}
  8238   ins_pipe( pipe_slow );
  8239 %}
  8241 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  8242   match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  8243   ins_cost(80);
  8244   format %{
  8245              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
  8246              "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
  8247          %}
  8248   ins_encode %{
  8249     Register op1 = $tmp1$$Register;
  8250     Register op2 = $tmp2$$Register;
  8251     Register dst = $dst$$Register;
  8252     Register src = $src$$Register;
  8253     int     flag = $cop$$cmpcode;
  8255     switch(flag) {
  8256       case 0x01: //equal
  8257         __ subu(AT, op1, op2);
  8258         __ movz(dst, src, AT);
  8259         break;
  8261       case 0x02: //not_equal
  8262         __ subu(AT, op1, op2);
  8263         __ movn(dst, src, AT);
  8264         break;
  8266       case 0x03: //above
  8267         __ sltu(AT, op2, op1);
  8268         __ movn(dst, src, AT);
  8269         break;
  8271       case 0x04: //above_equal
  8272         __ sltu(AT, op1, op2);
  8273         __ movz(dst, src, AT);
  8274         break;
  8276       case 0x05: //below
  8277         __ sltu(AT, op1, op2);
  8278         __ movn(dst, src, AT);
  8279         break;
  8281       case 0x06: //below_equal
  8282         __ sltu(AT, op2, op1);
  8283         __ movz(dst, src, AT);
  8284         break;
  8286       default:
  8287         Unimplemented();
  8289   %}
  8291   ins_pipe( pipe_slow );
  8292 %}
  8294 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
  8295   match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  8296   ins_cost(80);
  8297   format %{
  8298              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpD_reg_reg\n"
  8299              "\tCMOV  $dst,$src \t @cmovP_cmpD_reg_reg"
  8300          %}
  8301   ins_encode %{
  8302     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  8303     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  8304     Register dst = as_Register($dst$$reg);
  8305     Register src = as_Register($src$$reg);
  8307     int     flag = $cop$$cmpcode;
  8309     switch(flag) {
  8310       case 0x01: //equal
  8311         __ c_eq_d(reg_op1, reg_op2);
  8312         __ movt(dst, src);
  8313         break;
  8314       case 0x02: //not_equal
  8315         __ c_eq_d(reg_op1, reg_op2);
  8316         __ movf(dst, src);
  8317         break;
  8318       case 0x03: //greater
  8319         __ c_ole_d(reg_op1, reg_op2);
  8320         __ movf(dst, src);
  8321         break;
  8322       case 0x04: //greater_equal
  8323         __ c_olt_d(reg_op1, reg_op2);
  8324         __ movf(dst, src);
  8325         break;
  8326       case 0x05: //less
  8327         __ c_ult_d(reg_op1, reg_op2);
  8328         __ movt(dst, src);
  8329         break;
  8330       case 0x06: //less_equal
  8331         __ c_ule_d(reg_op1, reg_op2);
  8332         __ movt(dst, src);
  8333         break;
  8334       default:
  8335         Unimplemented();
  8337   %}
  8339   ins_pipe( pipe_slow );
  8340 %}
  8343 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  8344   match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  8345   ins_cost(80);
  8346   format %{
  8347              "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
  8348              "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
  8349          %}
  8350   ins_encode %{
  8351     Register op1 = $tmp1$$Register;
  8352     Register op2 = $tmp2$$Register;
  8353     Register dst = $dst$$Register;
  8354     Register src = $src$$Register;
  8355     int     flag = $cop$$cmpcode;
  8357     switch(flag) {
  8358       case 0x01: //equal
  8359         __ subu32(AT, op1, op2);
  8360         __ movz(dst, src, AT);
  8361         break;
  8363       case 0x02: //not_equal
  8364         __ subu32(AT, op1, op2);
  8365         __ movn(dst, src, AT);
  8366         break;
  8368       case 0x03: //above
  8369         __ sltu(AT, op2, op1);
  8370         __ movn(dst, src, AT);
  8371         break;
  8373       case 0x04: //above_equal
  8374         __ sltu(AT, op1, op2);
  8375         __ movz(dst, src, AT);
  8376         break;
  8378       case 0x05: //below
  8379         __ sltu(AT, op1, op2);
  8380         __ movn(dst, src, AT);
  8381         break;
  8383       case 0x06: //below_equal
  8384         __ sltu(AT, op2, op1);
  8385         __ movz(dst, src, AT);
  8386         break;
  8388       default:
  8389         Unimplemented();
  8391   %}
  8393   ins_pipe( pipe_slow );
  8394 %}
  8397 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  8398   match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  8399   ins_cost(80);
  8400   format %{
  8401              "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
  8402              "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
  8403          %}
  8404   ins_encode %{
  8405     Register op1 = $tmp1$$Register;
  8406     Register op2 = $tmp2$$Register;
  8407     Register dst = $dst$$Register;
  8408     Register src = $src$$Register;
  8409     int     flag = $cop$$cmpcode;
  8411     switch(flag) {
  8412       case 0x01: //equal
  8413         __ subu(AT, op1, op2);
  8414         __ movz(dst, src, AT);
  8415         break;
  8417       case 0x02: //not_equal
  8418         __ subu(AT, op1, op2);
  8419         __ movn(dst, src, AT);
  8420         break;
  8422       case 0x03: //above
  8423         __ sltu(AT, op2, op1);
  8424         __ movn(dst, src, AT);
  8425         break;
  8427       case 0x04: //above_equal
  8428         __ sltu(AT, op1, op2);
  8429         __ movz(dst, src, AT);
  8430         break;
  8432       case 0x05: //below
  8433         __ sltu(AT, op1, op2);
  8434         __ movn(dst, src, AT);
  8435         break;
  8437       case 0x06: //below_equal
  8438         __ sltu(AT, op2, op1);
  8439         __ movz(dst, src, AT);
  8440         break;
  8442       default:
  8443         Unimplemented();
  8445   %}
  8447   ins_pipe( pipe_slow );
  8448 %}
  8450 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  8451   match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  8452   ins_cost(80);
  8453   format %{
  8454              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpL_reg_reg\n"
  8455              "\tCMOV  $dst,$src \t @cmovI_cmpL_reg_reg"
  8456          %}
  8457   ins_encode %{
  8458     Register opr1 = as_Register($tmp1$$reg);
  8459     Register opr2 = as_Register($tmp2$$reg);
  8460     Register dst     = $dst$$Register;
  8461     Register src     = $src$$Register;
  8462     int     flag = $cop$$cmpcode;
  8464     switch(flag) {
  8465       case 0x01: //equal
  8466         __ subu(AT, opr1, opr2);
  8467         __ movz(dst, src, AT);
  8468         break;
  8470       case 0x02: //not_equal
  8471         __ subu(AT, opr1, opr2);
  8472         __ movn(dst, src, AT);
  8473         break;
  8475       case 0x03: //greater
  8476         __ slt(AT, opr2, opr1);
  8477         __ movn(dst, src, AT);
  8478         break;
  8480       case 0x04: //greater_equal
  8481         __ slt(AT, opr1, opr2);
  8482         __ movz(dst, src, AT);
  8483         break;
  8485       case 0x05: //less
  8486         __ slt(AT, opr1, opr2);
  8487         __ movn(dst, src, AT);
  8488         break;
  8490       case 0x06: //less_equal
  8491         __ slt(AT, opr2, opr1);
  8492         __ movz(dst, src, AT);
  8493         break;
  8495       default:
  8496         Unimplemented();
  8498   %}
  8500   ins_pipe( pipe_slow );
  8501 %}
  8503 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  8504   match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  8505   ins_cost(80);
  8506   format %{
  8507              "CMP$cop  $tmp1, $tmp2\t  @cmovP_cmpL_reg_reg\n"
  8508              "\tCMOV  $dst,$src \t @cmovP_cmpL_reg_reg"
  8509          %}
  8510   ins_encode %{
  8511     Register opr1 = as_Register($tmp1$$reg);
  8512     Register opr2 = as_Register($tmp2$$reg);
  8513     Register dst     = $dst$$Register;
  8514     Register src     = $src$$Register;
  8515     int     flag = $cop$$cmpcode;
  8517     switch(flag) {
  8518       case 0x01: //equal
  8519         __ subu(AT, opr1, opr2);
  8520         __ movz(dst, src, AT);
  8521         break;
  8523       case 0x02: //not_equal
  8524         __ subu(AT, opr1, opr2);
  8525         __ movn(dst, src, AT);
  8526         break;
  8528       case 0x03: //greater
  8529         __ slt(AT, opr2, opr1);
  8530         __ movn(dst, src, AT);
  8531         break;
  8533       case 0x04: //greater_equal
  8534         __ slt(AT, opr1, opr2);
  8535         __ movz(dst, src, AT);
  8536         break;
  8538       case 0x05: //less
  8539         __ slt(AT, opr1, opr2);
  8540         __ movn(dst, src, AT);
  8541         break;
  8543       case 0x06: //less_equal
  8544         __ slt(AT, opr2, opr1);
  8545         __ movz(dst, src, AT);
  8546         break;
  8548       default:
  8549         Unimplemented();
  8551   %}
  8553   ins_pipe( pipe_slow );
  8554 %}
  8556 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
  8557   match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  8558   ins_cost(80);
  8559   format %{
  8560              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpD_reg_reg\n"
  8561              "\tCMOV  $dst,$src \t @cmovI_cmpD_reg_reg"
  8562          %}
  8563   ins_encode %{
  8564     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  8565     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  8566     Register dst = as_Register($dst$$reg);
  8567     Register src = as_Register($src$$reg);
  8569     int     flag = $cop$$cmpcode;
  8571     switch(flag) {
  8572       case 0x01: //equal
  8573         __ c_eq_d(reg_op1, reg_op2);
  8574         __ movt(dst, src);
  8575         break;
  8576       case 0x02: //not_equal
  8577 //2016/4/19 aoqi: See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
  8578         __ c_eq_d(reg_op1, reg_op2);
  8579         __ movf(dst, src);
  8580         break;
  8581       case 0x03: //greater
  8582         __ c_ole_d(reg_op1, reg_op2);
  8583         __ movf(dst, src);
  8584         break;
  8585       case 0x04: //greater_equal
  8586         __ c_olt_d(reg_op1, reg_op2);
  8587         __ movf(dst, src);
  8588         break;
  8589       case 0x05: //less
  8590         __ c_ult_d(reg_op1, reg_op2);
  8591         __ movt(dst, src);
  8592         break;
  8593       case 0x06: //less_equal
  8594         __ c_ule_d(reg_op1, reg_op2);
  8595         __ movt(dst, src);
  8596         break;
  8597       default:
  8598         Unimplemented();
  8600   %}
  8602   ins_pipe( pipe_slow );
  8603 %}
  8606 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
  8607   match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  8608   ins_cost(80);
  8609   format %{
  8610              "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
  8611              "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
  8612          %}
  8613   ins_encode %{
  8614     Register op1 = $tmp1$$Register;
  8615     Register op2 = $tmp2$$Register;
  8616     Register dst = $dst$$Register;
  8617     Register src = $src$$Register;
  8618     int     flag = $cop$$cmpcode;
  8620     switch(flag) {
  8621       case 0x01: //equal
  8622         __ subu(AT, op1, op2);
  8623         __ movz(dst, src, AT);
  8624         break;
  8626       case 0x02: //not_equal
  8627         __ subu(AT, op1, op2);
  8628         __ movn(dst, src, AT);
  8629         break;
  8631       case 0x03: //above
  8632         __ sltu(AT, op2, op1);
  8633         __ movn(dst, src, AT);
  8634         break;
  8636       case 0x04: //above_equal
  8637         __ sltu(AT, op1, op2);
  8638         __ movz(dst, src, AT);
  8639         break;
  8641       case 0x05: //below
  8642         __ sltu(AT, op1, op2);
  8643         __ movn(dst, src, AT);
  8644         break;
  8646       case 0x06: //below_equal
  8647         __ sltu(AT, op2, op1);
  8648         __ movz(dst, src, AT);
  8649        break;
  8651       default:
  8652         Unimplemented();
  8654   %}
  8656   ins_pipe( pipe_slow );
  8657 %}
  8659 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  8660   match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  8661   ins_cost(80);
  8662   format %{
  8663              "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
  8664              "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
  8665          %}
  8666   ins_encode %{
  8667     Register op1 = $tmp1$$Register;
  8668     Register op2 = $tmp2$$Register;
  8669     Register dst = $dst$$Register;
  8670     Register src = $src$$Register;
  8671     int     flag = $cop$$cmpcode;
  8673     switch(flag) {
  8674       case 0x01: //equal
  8675         __ subu32(AT, op1, op2);
  8676         __ movz(dst, src, AT);
  8677         break;
  8679       case 0x02: //not_equal
  8680         __ subu32(AT, op1, op2);
  8681         __ movn(dst, src, AT);
  8682         break;
  8684       case 0x03: //above
  8685         __ slt(AT, op2, op1);
  8686         __ movn(dst, src, AT);
  8687         break;
  8689       case 0x04: //above_equal
  8690         __ slt(AT, op1, op2);
  8691         __ movz(dst, src, AT);
  8692         break;
  8694       case 0x05: //below
  8695         __ slt(AT, op1, op2);
  8696         __ movn(dst, src, AT);
  8697         break;
  8699       case 0x06: //below_equal
  8700         __ slt(AT, op2, op1);
  8701         __ movz(dst, src, AT);
  8702         break;
  8704       default:
  8705         Unimplemented();
  8707   %}
  8709   ins_pipe( pipe_slow );
  8710 %}
  8712 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
  8713   match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  8714   ins_cost(80);
  8715   format %{
  8716              "CMP$cop  $tmp1, $tmp2\t  @cmovN_cmpL_reg_reg\n"
  8717              "\tCMOV  $dst,$src \t @cmovN_cmpL_reg_reg"
  8718          %}
  8719   ins_encode %{
  8720     Register opr1 = as_Register($tmp1$$reg);
  8721     Register opr2 = as_Register($tmp2$$reg);
  8722     Register dst  = $dst$$Register;
  8723     Register src  = $src$$Register;
  8724     int     flag  = $cop$$cmpcode;
  8726     switch(flag) {
  8727       case 0x01: //equal
  8728         __ subu(AT, opr1, opr2);
  8729         __ movz(dst, src, AT);
  8730         break;
  8732       case 0x02: //not_equal
  8733         __ subu(AT, opr1, opr2);
  8734         __ movn(dst, src, AT);
  8735         break;
  8737       case 0x03: //greater
  8738         __ slt(AT, opr2, opr1);
  8739         __ movn(dst, src, AT);
  8740         break;
  8742       case 0x04: //greater_equal
  8743         __ slt(AT, opr1, opr2);
  8744         __ movz(dst, src, AT);
  8745         break;
  8747       case 0x05: //less
  8748         __ slt(AT, opr1, opr2);
  8749         __ movn(dst, src, AT);
  8750         break;
  8752       case 0x06: //less_equal
  8753         __ slt(AT, opr2, opr1);
  8754         __ movz(dst, src, AT);
  8755         break;
  8757       default:
  8758         Unimplemented();
  8760   %}
  8762   ins_pipe( pipe_slow );
  8763 %}
  8765 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  8766   match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  8767   ins_cost(80);
  8768   format %{
  8769              "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
  8770              "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
  8771          %}
  8772   ins_encode %{
  8773     Register op1 = $tmp1$$Register;
  8774     Register op2 = $tmp2$$Register;
  8775     Register dst = $dst$$Register;
  8776     Register src = $src$$Register;
  8777     int     flag = $cop$$cmpcode;
  8779     switch(flag) {
  8780       case 0x01: //equal
  8781         __ subu32(AT, op1, op2);
  8782         __ movz(dst, src, AT);
  8783         break;
  8785       case 0x02: //not_equal
  8786         __ subu32(AT, op1, op2);
  8787         __ movn(dst, src, AT);
  8788         break;
  8790       case 0x03: //above
  8791         __ slt(AT, op2, op1);
  8792         __ movn(dst, src, AT);
  8793         break;
  8795       case 0x04: //above_equal
  8796         __ slt(AT, op1, op2);
  8797         __ movz(dst, src, AT);
  8798         break;
  8800       case 0x05: //below
  8801         __ slt(AT, op1, op2);
  8802         __ movn(dst, src, AT);
  8803         break;
  8805       case 0x06: //below_equal
  8806         __ slt(AT, op2, op1);
  8807         __ movz(dst, src, AT);
  8808        break;
  8810       default:
  8811         Unimplemented();
  8813   %}
  8815   ins_pipe( pipe_slow );
  8816 %}
  8818 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
  8819   match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
  8820   ins_cost(80);
  8821   format %{
  8822              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
  8823              "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
  8824          %}
  8825   ins_encode %{
  8826     Register op1 = $tmp1$$Register;
  8827     Register op2 = $tmp2$$Register;
  8828     Register dst = $dst$$Register;
  8829     Register src = $src$$Register;
  8830     int     flag = $cop$$cmpcode;
  8832     switch(flag) {
  8833       case 0x01: //equal
  8834         __ subu32(AT, op1, op2);
  8835         __ movz(dst, src, AT);
  8836         break;
  8838       case 0x02: //not_equal
  8839         __ subu32(AT, op1, op2);
  8840         __ movn(dst, src, AT);
  8841         break;
  8843       case 0x03: //above
  8844         __ sltu(AT, op2, op1);
  8845         __ movn(dst, src, AT);
  8846         break;
  8848       case 0x04: //above_equal
  8849         __ sltu(AT, op1, op2);
  8850         __ movz(dst, src, AT);
  8851         break;
  8853       case 0x05: //below
  8854         __ sltu(AT, op1, op2);
  8855         __ movn(dst, src, AT);
  8856         break;
  8858       case 0x06: //below_equal
  8859         __ sltu(AT, op2, op1);
  8860         __ movz(dst, src, AT);
  8861         break;
  8863       default:
  8864         Unimplemented();
  8866   %}
  8868   ins_pipe( pipe_slow );
  8869 %}
  8871 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
  8872   match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  8873   ins_cost(80);
  8874   format %{
  8875              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpF_reg_reg\n"
  8876              "\tCMOV  $dst,$src \t @cmovL_cmpF_reg_reg"
  8877          %}
  8879   ins_encode %{
  8880     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  8881     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  8882     Register dst = $dst$$Register;
  8883     Register src = $src$$Register;
  8884     int     flag = $cop$$cmpcode;
  8886     switch(flag) {
  8887       case 0x01: //equal
  8888         __ c_eq_s(reg_op1, reg_op2);
  8889         __ movt(dst, src);
  8890         break;
  8891       case 0x02: //not_equal
  8892         __ c_eq_s(reg_op1, reg_op2);
  8893         __ movf(dst, src);
  8894         break;
  8895       case 0x03: //greater
  8896         __ c_ole_s(reg_op1, reg_op2);
  8897         __ movf(dst, src);
  8898         break;
  8899       case 0x04: //greater_equal
  8900         __ c_olt_s(reg_op1, reg_op2);
  8901         __ movf(dst, src);
  8902         break;
  8903       case 0x05: //less
  8904         __ c_ult_s(reg_op1, reg_op2);
  8905         __ movt(dst, src);
  8906         break;
  8907       case 0x06: //less_equal
  8908         __ c_ule_s(reg_op1, reg_op2);
  8909         __ movt(dst, src);
  8910        break;
  8911       default:
  8912         Unimplemented();
  8914   %}
  8915   ins_pipe( pipe_slow );
  8916 %}
  8918 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  8919   match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  8920   ins_cost(80);
  8921   format %{
  8922              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpI_reg_reg\n"
  8923              "\tCMOV  $dst,$src \t @cmovL_cmpI_reg_reg"
  8924          %}
  8926   ins_encode %{
  8927     Register op1 = $tmp1$$Register;
  8928     Register op2 = $tmp2$$Register;
  8929     Register dst = as_Register($dst$$reg);
  8930     Register src = as_Register($src$$reg);
  8931     int     flag = $cop$$cmpcode;
  8933     switch(flag)
  8935       case 0x01: //equal
  8936         __ subu32(AT, op1, op2);
  8937         __ movz(dst, src, AT);
  8938         break;
  8940       case 0x02: //not_equal
  8941         __ subu32(AT, op1, op2);
  8942         __ movn(dst, src, AT);
  8943         break;
  8945       case 0x03: //great
  8946         __ slt(AT, op2, op1);
  8947         __ movn(dst, src, AT);
  8948         break;
  8950       case 0x04: //great_equal
  8951         __ slt(AT, op1, op2);
  8952         __ movz(dst, src, AT);
  8953         break;
  8955       case 0x05: //less
  8956         __ slt(AT, op1, op2);
  8957         __ movn(dst, src, AT);
  8958         break;
  8960       case 0x06: //less_equal
  8961         __ slt(AT, op2, op1);
  8962         __ movz(dst, src, AT);
  8963        break;
  8965       default:
  8966         Unimplemented();
  8968   %}
  8970   ins_pipe( pipe_slow );
  8971 %}
  8973 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
  8974   match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
  8975   ins_cost(80);
  8976   format %{
  8977              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpL_reg_reg\n"
  8978              "\tCMOV  $dst,$src \t @cmovL_cmpL_reg_reg"
  8979          %}
  8980   ins_encode %{
  8981     Register opr1 = as_Register($tmp1$$reg);
  8982     Register opr2 = as_Register($tmp2$$reg);
  8983     Register dst  = as_Register($dst$$reg);
  8984     Register src  = as_Register($src$$reg);
  8985     int     flag = $cop$$cmpcode;
  8987     switch(flag) {
  8988       case 0x01: //equal
  8989         __ subu(AT, opr1, opr2);
  8990         __ movz(dst, src, AT);
  8991         break;
  8993       case 0x02: //not_equal
  8994         __ subu(AT, opr1, opr2);
  8995         __ movn(dst, src, AT);
  8996         break;
  8998       case 0x03: //greater
  8999         __ slt(AT, opr2, opr1);
  9000         __ movn(dst, src, AT);
  9001         break;
  9003       case 0x04: //greater_equal
  9004         __ slt(AT, opr1, opr2);
  9005         __ movz(dst, src, AT);
  9006         break;
  9008       case 0x05: //less
  9009         __ slt(AT, opr1, opr2);
  9010         __ movn(dst, src, AT);
  9011         break;
  9013       case 0x06: //less_equal
  9014        __ slt(AT, opr2, opr1);
  9015        __ movz(dst, src, AT);
  9016        break;
  9018       default:
  9019         Unimplemented();
  9021   %}
  9023   ins_pipe( pipe_slow );
  9024 %}
  9026 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
  9027   match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
  9028   ins_cost(80);
  9029   format %{
  9030              "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
  9031              "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
  9032          %}
  9033   ins_encode %{
  9034     Register op1 = $tmp1$$Register;
  9035     Register op2 = $tmp2$$Register;
  9036     Register dst = $dst$$Register;
  9037     Register src = $src$$Register;
  9038     int     flag = $cop$$cmpcode;
  9040     switch(flag) {
  9041       case 0x01: //equal
  9042         __ subu32(AT, op1, op2);
  9043         __ movz(dst, src, AT);
  9044         break;
  9046       case 0x02: //not_equal
  9047         __ subu32(AT, op1, op2);
  9048         __ movn(dst, src, AT);
  9049         break;
  9051       case 0x03: //above
  9052         __ sltu(AT, op2, op1);
  9053         __ movn(dst, src, AT);
  9054         break;
  9056       case 0x04: //above_equal
  9057         __ sltu(AT, op1, op2);
  9058         __ movz(dst, src, AT);
  9059         break;
  9061       case 0x05: //below
  9062         __ sltu(AT, op1, op2);
  9063         __ movn(dst, src, AT);
  9064         break;
  9066       case 0x06: //below_equal
  9067         __ sltu(AT, op2, op1);
  9068         __ movz(dst, src, AT);
  9069         break;
  9071       default:
  9072         Unimplemented();
  9074   %}
  9076   ins_pipe( pipe_slow );
  9077 %}
  9080 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9081   match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9082   ins_cost(80);
  9083   format %{
  9084              "CMP$cop  $tmp1, $tmp2\t  @cmovL_cmpD_reg_reg\n"
  9085              "\tCMOV  $dst,$src \t @cmovL_cmpD_reg_reg"
  9086          %}
  9087   ins_encode %{
  9088     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9089     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9090     Register dst = as_Register($dst$$reg);
  9091     Register src = as_Register($src$$reg);
  9093     int     flag = $cop$$cmpcode;
  9095     switch(flag) {
  9096       case 0x01: //equal
  9097         __ c_eq_d(reg_op1, reg_op2);
  9098         __ movt(dst, src);
  9099         break;
  9100       case 0x02: //not_equal
  9101         __ c_eq_d(reg_op1, reg_op2);
  9102         __ movf(dst, src);
  9103         break;
  9104       case 0x03: //greater
  9105         __ c_ole_d(reg_op1, reg_op2);
  9106         __ movf(dst, src);
  9107         break;
  9108       case 0x04: //greater_equal
  9109         __ c_olt_d(reg_op1, reg_op2);
  9110         __ movf(dst, src);
  9111         break;
  9112       case 0x05: //less
  9113         __ c_ult_d(reg_op1, reg_op2);
  9114         __ movt(dst, src);
  9115         break;
  9116       case 0x06: //less_equal
  9117         __ c_ule_d(reg_op1, reg_op2);
  9118         __ movt(dst, src);
  9119         break;
  9120       default:
  9121         Unimplemented();
  9123   %}
  9125   ins_pipe( pipe_slow );
  9126 %}
  9128 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
  9129   match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
  9130   ins_cost(200);
  9131   format %{
  9132              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpD_reg_reg\n"
  9133              "\tCMOV  $dst,$src \t @cmovD_cmpD_reg_reg"
  9134          %}
  9135   ins_encode %{
  9136     FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
  9137     FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
  9138     FloatRegister dst = as_FloatRegister($dst$$reg);
  9139     FloatRegister src = as_FloatRegister($src$$reg);
  9141     int     flag = $cop$$cmpcode;
  9143     switch(flag) {
  9144       case 0x01: //equal
  9145         __ c_eq_d(reg_op1, reg_op2);
  9146         __ movt_d(dst, src);
  9147         break;
  9148       case 0x02: //not_equal
  9149         __ c_eq_d(reg_op1, reg_op2);
  9150         __ movf_d(dst, src);
  9151         break;
  9152       case 0x03: //greater
  9153         __ c_ole_d(reg_op1, reg_op2);
  9154         __ movf_d(dst, src);
  9155         break;
  9156       case 0x04: //greater_equal
  9157         __ c_olt_d(reg_op1, reg_op2);
  9158         __ movf_d(dst, src);
  9159         break;
  9160       case 0x05: //less
  9161         __ c_ult_d(reg_op1, reg_op2);
  9162         __ movt_d(dst, src);
  9163         break;
  9164       case 0x06: //less_equal
  9165         __ c_ule_d(reg_op1, reg_op2);
  9166         __ movt_d(dst, src);
  9167         break;
  9168       default:
  9169         Unimplemented();
  9171   %}
  9173   ins_pipe( pipe_slow );
  9174 %}
  9176 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9177   match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9178   ins_cost(200);
  9179   format %{
  9180              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpI_reg_reg\n"
  9181              "\tCMOV  $dst, $src \t @cmovF_cmpI_reg_reg"
  9182          %}
  9184   ins_encode %{
  9185     Register op1 = $tmp1$$Register;
  9186     Register op2 = $tmp2$$Register;
  9187     FloatRegister dst = as_FloatRegister($dst$$reg);
  9188     FloatRegister src = as_FloatRegister($src$$reg);
  9189     int     flag = $cop$$cmpcode;
  9190     Label      L;
  9192     switch(flag) {
  9193       case 0x01: //equal
  9194         __ bne(op1, op2, L);
  9195         __ nop();
  9196         __ mov_s(dst, src);
  9197         __ bind(L);
  9198         break;
  9199       case 0x02: //not_equal
  9200         __ beq(op1, op2, L);
  9201         __ nop();
  9202         __ mov_s(dst, src);
  9203         __ bind(L);
  9204         break;
  9205       case 0x03: //great
  9206         __ slt(AT, op2, op1);
  9207         __ beq(AT, R0, L);
  9208         __ nop();
  9209         __ mov_s(dst, src);
  9210         __ bind(L);
  9211         break;
  9212       case 0x04: //great_equal
  9213         __ slt(AT, op1, op2);
  9214         __ bne(AT, R0, L);
  9215         __ nop();
  9216         __ mov_s(dst, src);
  9217         __ bind(L);
  9218         break;
  9219       case 0x05: //less
  9220         __ slt(AT, op1, op2);
  9221         __ beq(AT, R0, L);
  9222         __ nop();
  9223         __ mov_s(dst, src);
  9224         __ bind(L);
  9225         break;
  9226       case 0x06: //less_equal
  9227         __ slt(AT, op2, op1);
  9228         __ bne(AT, R0, L);
  9229         __ nop();
  9230         __ mov_s(dst, src);
  9231         __ bind(L);
  9232        break;
  9233       default:
  9234         Unimplemented();
  9236   %}
  9238   ins_pipe( pipe_slow );
  9239 %}
  9241 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
  9242   match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
  9243   ins_cost(200);
  9244   format %{
  9245              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpI_reg_reg\n"
  9246              "\tCMOV  $dst, $src \t @cmovD_cmpI_reg_reg"
  9247          %}
  9249   ins_encode %{
  9250     Register op1 = $tmp1$$Register;
  9251     Register op2 = $tmp2$$Register;
  9252     FloatRegister dst = as_FloatRegister($dst$$reg);
  9253     FloatRegister src = as_FloatRegister($src$$reg);
  9254     int     flag = $cop$$cmpcode;
  9255     Label      L;
  9257     switch(flag) {
  9258       case 0x01: //equal
  9259         __ bne(op1, op2, L);
  9260         __ nop();
  9261         __ mov_d(dst, src);
  9262         __ bind(L);
  9263         break;
  9264       case 0x02: //not_equal
  9265         __ beq(op1, op2, L);
  9266         __ nop();
  9267         __ mov_d(dst, src);
  9268         __ bind(L);
  9269         break;
  9270       case 0x03: //great
  9271         __ slt(AT, op2, op1);
  9272         __ beq(AT, R0, L);
  9273         __ nop();
  9274         __ mov_d(dst, src);
  9275         __ bind(L);
  9276         break;
  9277       case 0x04: //great_equal
  9278         __ slt(AT, op1, op2);
  9279         __ bne(AT, R0, L);
  9280         __ nop();
  9281         __ mov_d(dst, src);
  9282         __ bind(L);
  9283         break;
  9284       case 0x05: //less
  9285         __ slt(AT, op1, op2);
  9286         __ beq(AT, R0, L);
  9287         __ nop();
  9288         __ mov_d(dst, src);
  9289         __ bind(L);
  9290         break;
  9291       case 0x06: //less_equal
  9292         __ slt(AT, op2, op1);
  9293         __ bne(AT, R0, L);
  9294         __ nop();
  9295         __ mov_d(dst, src);
  9296         __ bind(L);
  9297         break;
  9298       default:
  9299         Unimplemented();
  9301   %}
  9303   ins_pipe( pipe_slow );
  9304 %}
  9306 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
  9307   match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
  9308   ins_cost(200);
  9309   format %{
  9310              "CMP$cop  $tmp1, $tmp2\t  @cmovD_cmpP_reg_reg\n"
  9311              "\tCMOV  $dst, $src \t @cmovD_cmpP_reg_reg"
  9312          %}
  9314   ins_encode %{
  9315     Register op1 = $tmp1$$Register;
  9316     Register op2 = $tmp2$$Register;
  9317     FloatRegister dst = as_FloatRegister($dst$$reg);
  9318     FloatRegister src = as_FloatRegister($src$$reg);
  9319     int     flag = $cop$$cmpcode;
  9320     Label      L;
  9322     switch(flag) {
  9323       case 0x01: //equal
  9324         __ bne(op1, op2, L);
  9325         __ nop();
  9326         __ mov_d(dst, src);
  9327         __ bind(L);
  9328         break;
  9329       case 0x02: //not_equal
  9330         __ beq(op1, op2, L);
  9331         __ nop();
  9332         __ mov_d(dst, src);
  9333         __ bind(L);
  9334         break;
  9335       case 0x03: //great
  9336         __ slt(AT, op2, op1);
  9337         __ beq(AT, R0, L);
  9338         __ nop();
  9339         __ mov_d(dst, src);
  9340         __ bind(L);
  9341         break;
  9342       case 0x04: //great_equal
  9343         __ slt(AT, op1, op2);
  9344         __ bne(AT, R0, L);
  9345         __ nop();
  9346         __ mov_d(dst, src);
  9347         __ bind(L);
  9348         break;
  9349       case 0x05: //less
  9350         __ slt(AT, op1, op2);
  9351         __ beq(AT, R0, L);
  9352         __ nop();
  9353         __ mov_d(dst, src);
  9354         __ bind(L);
  9355         break;
  9356       case 0x06: //less_equal
  9357         __ slt(AT, op2, op1);
  9358         __ bne(AT, R0, L);
  9359         __ nop();
  9360         __ mov_d(dst, src);
  9361         __ bind(L);
  9362         break;
  9363       default:
  9364         Unimplemented();
  9366   %}
  9368   ins_pipe( pipe_slow );
  9369 %}
  9371 //FIXME
  9372 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9373   match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9374   ins_cost(80);
  9375   format %{
  9376              "CMP$cop  $tmp1, $tmp2\t  @cmovI_cmpF_reg_reg\n"
  9377              "\tCMOV  $dst,$src \t @cmovI_cmpF_reg_reg"
  9378          %}
  9380   ins_encode %{
  9381     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9382     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9383     Register dst = $dst$$Register;
  9384     Register src = $src$$Register;
  9385     int     flag = $cop$$cmpcode;
  9387     switch(flag) {
  9388       case 0x01: //equal
  9389         __ c_eq_s(reg_op1, reg_op2);
  9390         __ movt(dst, src);
  9391         break;
  9392       case 0x02: //not_equal
  9393         __ c_eq_s(reg_op1, reg_op2);
  9394         __ movf(dst, src);
  9395         break;
  9396       case 0x03: //greater
  9397         __ c_ole_s(reg_op1, reg_op2);
  9398         __ movf(dst, src);
  9399         break;
  9400       case 0x04: //greater_equal
  9401         __ c_olt_s(reg_op1, reg_op2);
  9402         __ movf(dst, src);
  9403         break;
  9404       case 0x05: //less
  9405         __ c_ult_s(reg_op1, reg_op2);
  9406         __ movt(dst, src);
  9407         break;
  9408       case 0x06: //less_equal
  9409         __ c_ule_s(reg_op1, reg_op2);
  9410         __ movt(dst, src);
  9411         break;
  9412       default:
  9413         Unimplemented();
  9415   %}
  9416   ins_pipe( pipe_slow );
  9417 %}
  9419 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
  9420   match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
  9421   ins_cost(200);
  9422   format %{
  9423              "CMP$cop  $tmp1, $tmp2\t  @cmovF_cmpF_reg_reg\n"
  9424              "\tCMOV  $dst,$src \t @cmovF_cmpF_reg_reg"
  9425          %}
  9427   ins_encode %{
  9428     FloatRegister reg_op1 = $tmp1$$FloatRegister;
  9429     FloatRegister reg_op2 = $tmp2$$FloatRegister;
  9430     FloatRegister dst = $dst$$FloatRegister;
  9431     FloatRegister src = $src$$FloatRegister;
  9432     int    flag = $cop$$cmpcode;
  9434     switch(flag) {
  9435       case 0x01: //equal
  9436         __ c_eq_s(reg_op1, reg_op2);
  9437         __ movt_s(dst, src);
  9438         break;
  9439       case 0x02: //not_equal
  9440         __ c_eq_s(reg_op1, reg_op2);
  9441         __ movf_s(dst, src);
  9442         break;
  9443       case 0x03: //greater
  9444         __ c_ole_s(reg_op1, reg_op2);
  9445         __ movf_s(dst, src);
  9446         break;
  9447       case 0x04: //greater_equal
  9448         __ c_olt_s(reg_op1, reg_op2);
  9449         __ movf_s(dst, src);
  9450         break;
  9451       case 0x05: //less
  9452         __ c_ult_s(reg_op1, reg_op2);
  9453         __ movt_s(dst, src);
  9454         break;
  9455       case 0x06: //less_equal
  9456         __ c_ule_s(reg_op1, reg_op2);
  9457         __ movt_s(dst, src);
  9458         break;
  9459       default:
  9460         Unimplemented();
  9462   %}
  9463   ins_pipe( pipe_slow );
  9464 %}
  9466 // Manifest a CmpL result in an integer register.  Very painful.
  9467 // This is the test to avoid.
  9468 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
  9469   match(Set dst (CmpL3 src1 src2));
  9470   ins_cost(1000);
  9471   format %{ "cmpL3  $dst, $src1, $src2 @ cmpL3_reg_reg" %}
  9472   ins_encode %{
  9473     Register opr1 = as_Register($src1$$reg);
  9474     Register opr2 = as_Register($src2$$reg);
  9475     Register dst  = as_Register($dst$$reg);
  9477     Label Done;
  9479     __ subu(AT, opr1, opr2);
  9480     __ bltz(AT, Done);
  9481     __ delayed()->daddiu(dst, R0, -1);
  9483     __ move(dst, 1);
  9484     __ movz(dst, R0, AT);
  9486     __ bind(Done);
  9487   %}
  9488   ins_pipe( pipe_slow );
  9489 %}
  9491 //
  9492 // less_rsult     = -1
  9493 // greater_result =  1
  9494 // equal_result   =  0
  9495 // nan_result     = -1
  9496 //
  9497 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
  9498   match(Set dst (CmpF3 src1 src2));
  9499   ins_cost(1000);
  9500   format %{ "cmpF3  $dst, $src1, $src2 @ cmpF3_reg_reg" %}
  9501   ins_encode %{
  9502     FloatRegister src1 = as_FloatRegister($src1$$reg);
  9503     FloatRegister src2 = as_FloatRegister($src2$$reg);
  9504     Register dst = as_Register($dst$$reg);
  9506     Label Done;
  9508     __ c_ult_s(src1, src2);
  9509     __ bc1t(Done);
  9510     __ delayed()->daddiu(dst, R0, -1);
  9512     __ c_eq_s(src1, src2);
  9513     __ move(dst, 1);
  9514     __ movt(dst, R0);
  9516     __ bind(Done);
  9517   %}
  9518   ins_pipe( pipe_slow );
  9519 %}
  9521 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
  9522   match(Set dst (CmpD3 src1 src2));
  9523   ins_cost(1000);
  9524   format %{ "cmpD3  $dst, $src1, $src2 @ cmpD3_reg_reg" %}
  9525   ins_encode %{
  9526     FloatRegister src1 = as_FloatRegister($src1$$reg);
  9527     FloatRegister src2 = as_FloatRegister($src2$$reg);
  9528     Register dst = as_Register($dst$$reg);
  9530     Label Done;
  9532     __ c_ult_d(src1, src2);
  9533     __ bc1t(Done);
  9534     __ delayed()->daddiu(dst, R0, -1);
  9536     __ c_eq_d(src1, src2);
  9537     __ move(dst, 1);
  9538     __ movt(dst, R0);
  9540     __ bind(Done);
  9541   %}
  9542   ins_pipe( pipe_slow );
  9543 %}
  9545 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
  9546   match(Set dummy (ClearArray cnt base));
  9547   format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
  9548   ins_encode %{
  9549     //Assume cnt is the number of bytes in an array to be cleared,
  9550     //and base points to the starting address of the array.
  9551     Register base = $base$$Register;
  9552     Register num  = $cnt$$Register;
  9553     Label Loop, done;
  9555     __ beq(num, R0, done);
  9556     __ delayed()->daddu(AT, base, R0);
  9558     __ move(T9, num);  /* T9 = words */
  9560     __ bind(Loop);
  9561     __ sd(R0, AT, 0);
  9562     __ daddi(T9, T9, -1);
  9563     __ bne(T9, R0, Loop);
  9564     __ delayed()->daddi(AT, AT, wordSize);
  9566     __ bind(done);
  9567   %}
  9568   ins_pipe( pipe_slow );
  9569 %}
  9571 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2,  mA7RegI cnt2, no_Ax_mRegI result) %{
  9572   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
  9573   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
  9575   format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
  9576   ins_encode %{
  9577     // Get the first character position in both strings
  9578     //         [8] char array, [12] offset, [16] count
  9579     Register str1   = $str1$$Register;
  9580     Register str2   = $str2$$Register;
  9581     Register cnt1   = $cnt1$$Register;
  9582     Register cnt2   = $cnt2$$Register;
  9583     Register result = $result$$Register;
  9585     Label L, Loop, haveResult, done;
  9587    // compute the and difference of lengths (in result)
  9588    __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
  9590    // compute the shorter length (in cnt1)
  9591    __ slt(AT, cnt2, cnt1);
  9592    __ movn(cnt1, cnt2, AT);
  9594    // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
  9595    __ bind(Loop);                        // Loop begin
  9596    __ beq(cnt1, R0, done);
  9597    __ delayed()->lhu(AT, str1, 0);;
  9599    // compare current character
  9600    __ lhu(cnt2, str2, 0);
  9601    __ bne(AT, cnt2, haveResult);
  9602    __ delayed()->addi(str1, str1, 2);
  9603    __ addi(str2, str2, 2);
  9604    __ b(Loop);
  9605    __ delayed()->addi(cnt1, cnt1, -1);   // Loop end
  9607    __ bind(haveResult);
  9608    __ subu(result, AT, cnt2);
  9610    __ bind(done);
  9611   %}
  9613   ins_pipe( pipe_slow );
  9614 %}
  9616 // intrinsic optimization
  9617 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
  9618   match(Set result (StrEquals (Binary str1 str2) cnt));
  9619   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
  9621   format %{ "String Equal $str1, $str2, len:$cnt  tmp:$temp -> $result @ string_equals" %}
  9622   ins_encode %{
  9623     // Get the first character position in both strings
  9624     //         [8] char array, [12] offset, [16] count
  9625     Register str1   = $str1$$Register;
  9626     Register str2   = $str2$$Register;
  9627     Register cnt    = $cnt$$Register;
  9628     Register tmp    = $temp$$Register;
  9629     Register result = $result$$Register;
  9631     Label    Loop, done;
  9634    __ beq(str1, str2, done);  // same char[] ?
  9635    __ daddiu(result, R0, 1);
  9637    __ bind(Loop);             // Loop begin
  9638    __ beq(cnt, R0, done);
  9639    __ daddiu(result, R0, 1); // count == 0
  9641    // compare current character
  9642    __ lhu(AT, str1, 0);;
  9643    __ lhu(tmp, str2, 0);
  9644    __ bne(AT, tmp, done);
  9645    __ delayed()->daddi(result, R0, 0);
  9646    __ addi(str1, str1, 2);
  9647    __ addi(str2, str2, 2);
  9648    __ b(Loop);
  9649    __ delayed()->addi(cnt, cnt, -1);  // Loop end
  9651    __ bind(done);
  9652   %}
  9654   ins_pipe( pipe_slow );
  9655 %}
  9657 //----------Arithmetic Instructions-------------------------------------------
  9658 //----------Addition Instructions---------------------------------------------
  9659 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  9660   match(Set dst (AddI src1 src2));
  9662   format %{ "add   $dst, $src1, $src2 #@addI_Reg_Reg" %}
  9663   ins_encode %{
  9664     Register  dst = $dst$$Register;
  9665     Register src1 = $src1$$Register;
  9666     Register src2 = $src2$$Register;
  9667     __ addu32(dst, src1, src2);
  9668   %}
  9669   ins_pipe( ialu_regI_regI );
  9670 %}
  9672 instruct addI_Reg_imm(mRegI dst, mRegI src1,  immI src2) %{
  9673   match(Set dst (AddI src1 src2));
  9675   format %{ "add    $dst, $src1, $src2 #@addI_Reg_imm" %}
  9676   ins_encode %{
  9677     Register  dst = $dst$$Register;
  9678     Register src1 = $src1$$Register;
  9679     int       imm = $src2$$constant;
  9681     if(Assembler::is_simm16(imm)) {
  9682        __ addiu32(dst, src1, imm);
  9683     } else {
  9684        __ move(AT, imm);
  9685        __ addu32(dst, src1, AT);
  9687   %}
  9688   ins_pipe( ialu_regI_regI );
  9689 %}
  9691 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
  9692   match(Set dst (AddP src1 src2));
  9694   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg" %}
  9696   ins_encode %{
  9697     Register  dst = $dst$$Register;
  9698     Register src1 = $src1$$Register;
  9699     Register src2 = $src2$$Register;
  9700     __ daddu(dst, src1, src2);
  9701   %}
  9703   ins_pipe( ialu_regI_regI );
  9704 %}
  9706 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
  9707   match(Set dst (AddP src1 (ConvI2L src2)));
  9709   format %{ "dadd    $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
  9711   ins_encode %{
  9712     Register  dst = $dst$$Register;
  9713     Register src1 = $src1$$Register;
  9714     Register src2 = $src2$$Register;
  9715     __ daddu(dst, src1, src2);
  9716   %}
  9718   ins_pipe( ialu_regI_regI );
  9719 %}
  9721 instruct addP_reg_imm(mRegP dst, mRegP src1,  immL src2) %{
  9722   match(Set dst (AddP src1 src2));
  9724   format %{ "daddi   $dst, $src1, $src2 #@addP_reg_imm" %}
  9725   ins_encode %{
  9726     Register src1 = $src1$$Register;
  9727     long      src2 = $src2$$constant;
  9728     Register  dst = $dst$$Register;
  9730     if(Assembler::is_simm16(src2)) {
  9731        __ daddiu(dst, src1, src2);
  9732     } else {
  9733        __ set64(AT, src2);
  9734        __ daddu(dst, src1, AT);
  9736   %}
  9737   ins_pipe( ialu_regI_imm16 );
  9738 %}
  9740 // Add Long Register with Register
  9741 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  9742   match(Set dst (AddL src1 src2));
  9743   ins_cost(200);
  9744   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
  9746   ins_encode %{
  9747     Register dst_reg = as_Register($dst$$reg);
  9748     Register src1_reg = as_Register($src1$$reg);
  9749     Register src2_reg = as_Register($src2$$reg);
  9751     __ daddu(dst_reg, src1_reg, src2_reg);
  9752   %}
  9754   ins_pipe( ialu_regL_regL );
  9755 %}
  9757 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
  9758 %{
  9759   match(Set dst (AddL src1 src2));
  9761   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_imm " %}
  9762   ins_encode %{
  9763     Register dst_reg  = as_Register($dst$$reg);
  9764     Register src1_reg = as_Register($src1$$reg);
  9765     int      src2_imm = $src2$$constant;
  9767     __ daddiu(dst_reg, src1_reg, src2_imm);
  9768   %}
  9770   ins_pipe( ialu_regL_regL );
  9771 %}
  9773 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
  9774 %{
  9775   match(Set dst (AddL (ConvI2L src1) src2));
  9777   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_imm " %}
  9778   ins_encode %{
  9779     Register dst_reg  = as_Register($dst$$reg);
  9780     Register src1_reg = as_Register($src1$$reg);
  9781     int      src2_imm = $src2$$constant;
  9783     __ daddiu(dst_reg, src1_reg, src2_imm);
  9784   %}
  9786   ins_pipe( ialu_regL_regL );
  9787 %}
  9789 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
  9790   match(Set dst (AddL (ConvI2L src1) src2));
  9791   ins_cost(200);
  9792   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
  9794   ins_encode %{
  9795     Register dst_reg = as_Register($dst$$reg);
  9796     Register src1_reg = as_Register($src1$$reg);
  9797     Register src2_reg = as_Register($src2$$reg);
  9799     __ daddu(dst_reg, src1_reg, src2_reg);
  9800   %}
  9802   ins_pipe( ialu_regL_regL );
  9803 %}
  9805 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
  9806   match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
  9807   ins_cost(200);
  9808   format %{ "ADD    $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
  9810   ins_encode %{
  9811     Register dst_reg = as_Register($dst$$reg);
  9812     Register src1_reg = as_Register($src1$$reg);
  9813     Register src2_reg = as_Register($src2$$reg);
  9815     __ daddu(dst_reg, src1_reg, src2_reg);
  9816   %}
  9818   ins_pipe( ialu_regL_regL );
  9819 %}
  9821 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
  9822   match(Set dst (AddL src1 (ConvI2L src2)));
  9823   ins_cost(200);
  9824   format %{ "ADD    $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
  9826   ins_encode %{
  9827     Register dst_reg = as_Register($dst$$reg);
  9828     Register src1_reg = as_Register($src1$$reg);
  9829     Register src2_reg = as_Register($src2$$reg);
  9831     __ daddu(dst_reg, src1_reg, src2_reg);
  9832   %}
  9834   ins_pipe( ialu_regL_regL );
  9835 %}
  9837 //----------Subtraction Instructions-------------------------------------------
  9838 // Integer Subtraction Instructions
  9839 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  9840   match(Set dst (SubI src1 src2));
  9841   ins_cost(100);
  9843   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_Reg" %}
  9844   ins_encode %{
  9845     Register  dst = $dst$$Register;
  9846     Register src1 = $src1$$Register;
  9847     Register src2 = $src2$$Register;
  9848     __ subu32(dst, src1, src2);
  9849   %}
  9850   ins_pipe( ialu_regI_regI );
  9851 %}
  9853 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1,  immI16_sub src2) %{
  9854   match(Set dst (SubI src1 src2));
  9855   ins_cost(80);
  9857   format %{ "sub    $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
  9858   ins_encode %{
  9859     Register  dst = $dst$$Register;
  9860     Register src1 = $src1$$Register;
  9861     __ addiu32(dst, src1, -1 * $src2$$constant);
  9862   %}
  9863   ins_pipe( ialu_regI_regI );
  9864 %}
  9866 instruct negI_Reg(mRegI dst, immI0 zero,  mRegI src) %{
  9867   match(Set dst (SubI zero src));
  9868   ins_cost(80);
  9870   format %{ "neg    $dst, $src #@negI_Reg" %}
  9871   ins_encode %{
  9872     Register  dst = $dst$$Register;
  9873     Register  src = $src$$Register;
  9874     __ subu32(dst, R0, src);
  9875   %}
  9876   ins_pipe( ialu_regI_regI );
  9877 %}
  9879 instruct negL_Reg(mRegL dst, immL0 zero,  mRegL src) %{
  9880   match(Set dst (SubL zero src));
  9881   ins_cost(80);
  9883   format %{ "neg    $dst, $src #@negL_Reg" %}
  9884   ins_encode %{
  9885     Register  dst = $dst$$Register;
  9886     Register  src = $src$$Register;
  9887     __ subu(dst, R0, src);
  9888   %}
  9889   ins_pipe( ialu_regI_regI );
  9890 %}
  9892 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1,  immL16_sub src2) %{
  9893   match(Set dst (SubL src1 src2));
  9894   ins_cost(80);
  9896   format %{ "sub    $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
  9897   ins_encode %{
  9898     Register  dst = $dst$$Register;
  9899     Register src1 = $src1$$Register;
  9900     __ daddiu(dst, src1, -1 * $src2$$constant);
  9901   %}
  9902   ins_pipe( ialu_regI_regI );
  9903 %}
  9905 // Subtract Long Register with Register.
  9906 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
  9907   match(Set dst (SubL src1 src2));
  9908   ins_cost(100);
  9909   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_Reg" %}
  9910   ins_encode %{
  9911     Register dst  = as_Register($dst$$reg);
  9912     Register src1 = as_Register($src1$$reg);
  9913     Register src2 = as_Register($src2$$reg);
  9915     __ subu(dst, src1, src2);
  9916   %}
  9917   ins_pipe( ialu_regL_regL );
  9918 %}
  9920 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
  9921   match(Set dst (SubL src1 (ConvI2L src2)));
  9922   ins_cost(100);
  9923   format %{ "SubL    $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
  9924   ins_encode %{
  9925     Register dst  = as_Register($dst$$reg);
  9926     Register src1 = as_Register($src1$$reg);
  9927     Register src2 = as_Register($src2$$reg);
  9929     __ subu(dst, src1, src2);
  9930   %}
  9931   ins_pipe( ialu_regL_regL );
  9932 %}
  9934 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
  9935   match(Set dst (SubL (ConvI2L src1) src2));
  9936   ins_cost(200);
  9937   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
  9938   ins_encode %{
  9939     Register dst  = as_Register($dst$$reg);
  9940     Register src1 = as_Register($src1$$reg);
  9941     Register src2 = as_Register($src2$$reg);
  9943     __ subu(dst, src1, src2);
  9944   %}
  9945   ins_pipe( ialu_regL_regL );
  9946 %}
  9948 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
  9949   match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
  9950   ins_cost(200);
  9951   format %{ "SubL    $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
  9952   ins_encode %{
  9953     Register dst  = as_Register($dst$$reg);
  9954     Register src1 = as_Register($src1$$reg);
  9955     Register src2 = as_Register($src2$$reg);
  9957     __ subu(dst, src1, src2);
  9958   %}
  9959   ins_pipe( ialu_regL_regL );
  9960 %}
  9962 // Integer MOD with Register
  9963 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
  9964   match(Set dst (ModI src1 src2));
  9965   ins_cost(300);
  9966   format %{ "modi   $dst, $src1, $src2 @ modI_Reg_Reg" %}
  9967   ins_encode %{
  9968     Register  dst = $dst$$Register;
  9969     Register src1 = $src1$$Register;
  9970     Register src2 = $src2$$Register;
  9972     //if (UseLoongsonISA) {
  9973     if (0) {
  9974       // 2016.08.10
  9975       // Experiments show that gsmod is slower that div+mfhi.
  9976       // So I just disable it here.
  9977       __ gsmod(dst, src1, src2);
  9978     } else {
  9979       __ div(src1, src2);
  9980       __ mfhi(dst);
  9982   %}
  9984   //ins_pipe( ialu_mod );
  9985   ins_pipe( ialu_regI_regI );
  9986 %}
  9988 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
  9989   match(Set dst (ModL src1 src2));
  9990   format %{ "modL  $dst, $src1, $src2 @modL_reg_reg" %}
  9992   ins_encode %{
  9993     Register dst = as_Register($dst$$reg);
  9994     Register op1 = as_Register($src1$$reg);
  9995     Register op2 = as_Register($src2$$reg);
  9997     if (UseLoongsonISA) {
  9998       __ gsdmod(dst, op1, op2);
  9999     } else {
 10000       __ ddiv(op1, op2);
 10001       __ mfhi(dst);
 10003   %}
 10004   ins_pipe( pipe_slow );
 10005 %}
 10007 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10008   match(Set dst (MulI src1 src2));
 10010   ins_cost(300);
 10011   format %{ "mul   $dst, $src1, $src2 @ mulI_Reg_Reg" %}
 10012   ins_encode %{
 10013      Register src1 = $src1$$Register;
 10014      Register src2 = $src2$$Register;
 10015      Register dst  = $dst$$Register;
 10017      __ mul(dst, src1, src2);
 10018   %}
 10019   ins_pipe( ialu_mult );
 10020 %}
 10022 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
 10023   match(Set dst (AddI (MulI src1 src2) src3));
 10025   ins_cost(999);
 10026   format %{ "madd   $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
 10027   ins_encode %{
 10028      Register src1 = $src1$$Register;
 10029      Register src2 = $src2$$Register;
 10030      Register src3 = $src3$$Register;
 10031      Register dst  = $dst$$Register;
 10033      __ mtlo(src3);
 10034      __ madd(src1, src2);
 10035      __ mflo(dst);
 10036   %}
 10037   ins_pipe( ialu_mult );
 10038 %}
 10040 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 10041   match(Set dst (DivI src1 src2));
 10043   ins_cost(300);
 10044   format %{ "div   $dst, $src1, $src2 @ divI_Reg_Reg" %}
 10045   ins_encode %{
 10046      Register src1 = $src1$$Register;
 10047      Register src2 = $src2$$Register;
 10048      Register dst  = $dst$$Register;
 10050     /* 2012/4/21 Jin: In MIPS, div does not cause exception.
 10051        We must trap an exception manually. */
 10052     __ teq(R0, src2, 0x7);
 10054     if (UseLoongsonISA) {
 10055       __ gsdiv(dst, src1, src2);
 10056     } else {
 10057       __ div(src1, src2);
 10059       __ nop();
 10060       __ nop();
 10061       __ mflo(dst);
 10063   %}
 10064   ins_pipe( ialu_mod );
 10065 %}
 10067 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
 10068   match(Set dst (DivF src1 src2));
 10070   ins_cost(300);
 10071   format %{ "divF   $dst, $src1, $src2 @ divF_Reg_Reg" %}
 10072   ins_encode %{
 10073      FloatRegister src1 = $src1$$FloatRegister;
 10074      FloatRegister src2 = $src2$$FloatRegister;
 10075      FloatRegister dst  = $dst$$FloatRegister;
 10077     /* Here do we need to trap an exception manually ? */
 10078     __ div_s(dst, src1, src2);
 10079   %}
 10080   ins_pipe( pipe_slow );
 10081 %}
 10083 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
 10084   match(Set dst (DivD src1 src2));
 10086   ins_cost(300);
 10087   format %{ "divD   $dst, $src1, $src2 @ divD_Reg_Reg" %}
 10088   ins_encode %{
 10089      FloatRegister src1 = $src1$$FloatRegister;
 10090      FloatRegister src2 = $src2$$FloatRegister;
 10091      FloatRegister dst  = $dst$$FloatRegister;
 10093     /* Here do we need to trap an exception manually ? */
 10094     __ div_d(dst, src1, src2);
 10095   %}
 10096   ins_pipe( pipe_slow );
 10097 %}
 10099 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 10100   match(Set dst (MulL src1 src2));
 10101   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_reg" %}
 10102   ins_encode %{
 10103     Register dst = as_Register($dst$$reg);
 10104     Register op1 = as_Register($src1$$reg);
 10105     Register op2 = as_Register($src2$$reg);
 10107     if (UseLoongsonISA) {
 10108       __ gsdmult(dst, op1, op2);
 10109     } else {
 10110       __ dmult(op1, op2);
 10111       __ mflo(dst);
 10113   %}
 10114   ins_pipe( pipe_slow );
 10115 %}
 10117 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
 10118   match(Set dst (MulL src1 (ConvI2L src2)));
 10119   format %{ "mulL  $dst, $src1, $src2 @mulL_reg_regI2L" %}
 10120   ins_encode %{
 10121     Register dst = as_Register($dst$$reg);
 10122     Register op1 = as_Register($src1$$reg);
 10123     Register op2 = as_Register($src2$$reg);
 10125     if (UseLoongsonISA) {
 10126       __ gsdmult(dst, op1, op2);
 10127     } else {
 10128       __ dmult(op1, op2);
 10129       __ mflo(dst);
 10131   %}
 10132   ins_pipe( pipe_slow );
 10133 %}
 10135 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
 10136   match(Set dst (DivL src1 src2));
 10137   format %{ "divL  $dst, $src1, $src2 @divL_reg_reg" %}
 10139   ins_encode %{
 10140     Register dst = as_Register($dst$$reg);
 10141     Register op1 = as_Register($src1$$reg);
 10142     Register op2 = as_Register($src2$$reg);
 10144     if (UseLoongsonISA) {
 10145       __ gsddiv(dst, op1, op2);
 10146     } else {
 10147       __ ddiv(op1, op2);
 10148       __ mflo(dst);
 10150   %}
 10151   ins_pipe( pipe_slow );
 10152 %}
 10154 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
 10155   match(Set dst (AddF src1 src2));
 10156   format %{ "AddF  $dst, $src1, $src2 @addF_reg_reg" %}
 10157   ins_encode %{
 10158     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10159     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10160     FloatRegister dst  = as_FloatRegister($dst$$reg);
 10162     __ add_s(dst, src1, src2);
 10163   %}
 10164   ins_pipe( fpu_regF_regF );
 10165 %}
 10167 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
 10168   match(Set dst (SubF src1 src2));
 10169   format %{ "SubF  $dst, $src1, $src2 @subF_reg_reg" %}
 10170   ins_encode %{
 10171     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10172     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10173     FloatRegister dst  = as_FloatRegister($dst$$reg);
 10175     __ sub_s(dst, src1, src2);
 10176   %}
 10177   ins_pipe( fpu_regF_regF );
 10178 %}
 10179 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
 10180   match(Set dst (AddD src1 src2));
 10181   format %{ "AddD  $dst, $src1, $src2 @addD_reg_reg" %}
 10182   ins_encode %{
 10183     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10184     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10185     FloatRegister dst  = as_FloatRegister($dst$$reg);
 10187     __ add_d(dst, src1, src2);
 10188   %}
 10189   ins_pipe( fpu_regF_regF );
 10190 %}
 10192 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
 10193   match(Set dst (SubD src1 src2));
 10194   format %{ "SubD  $dst, $src1, $src2 @subD_reg_reg" %}
 10195   ins_encode %{
 10196     FloatRegister src1 = as_FloatRegister($src1$$reg);
 10197     FloatRegister src2 = as_FloatRegister($src2$$reg);
 10198     FloatRegister dst  = as_FloatRegister($dst$$reg);
 10200     __ sub_d(dst, src1, src2);
 10201   %}
 10202   ins_pipe( fpu_regF_regF );
 10203 %}
 10205 instruct negF_reg(regF dst, regF src) %{
 10206   match(Set dst (NegF src));
 10207   format %{ "negF  $dst, $src @negF_reg" %}
 10208   ins_encode %{
 10209     FloatRegister src = as_FloatRegister($src$$reg);
 10210     FloatRegister dst = as_FloatRegister($dst$$reg);
 10212     __ neg_s(dst, src);
 10213   %}
 10214   ins_pipe( fpu_regF_regF );
 10215 %}
 10217 instruct negD_reg(regD dst, regD src) %{
 10218   match(Set dst (NegD src));
 10219   format %{ "negD  $dst, $src @negD_reg" %}
 10220   ins_encode %{
 10221     FloatRegister src = as_FloatRegister($src$$reg);
 10222     FloatRegister dst = as_FloatRegister($dst$$reg);
 10224     __ neg_d(dst, src);
 10225   %}
 10226   ins_pipe( fpu_regF_regF );
 10227 %}
 10230 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
 10231   match(Set dst (MulF src1 src2));
 10232   format %{ "MULF  $dst, $src1, $src2 @mulF_reg_reg" %}
 10233   ins_encode %{
 10234     FloatRegister src1 = $src1$$FloatRegister;
 10235     FloatRegister src2 = $src2$$FloatRegister;
 10236     FloatRegister dst  = $dst$$FloatRegister;
 10238     __ mul_s(dst, src1, src2);
 10239   %}
 10240   ins_pipe( fpu_regF_regF );
 10241 %}
 10243 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
 10244   match(Set dst (AddF (MulF src1 src2) src3));
 10245   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 10246   ins_cost(44444);
 10247   format %{ "maddF  $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
 10248   ins_encode %{
 10249     FloatRegister src1 = $src1$$FloatRegister;
 10250     FloatRegister src2 = $src2$$FloatRegister;
 10251     FloatRegister src3 = $src3$$FloatRegister;
 10252     FloatRegister dst  = $dst$$FloatRegister;
 10254     __ madd_s(dst, src1, src2, src3);
 10255   %}
 10256   ins_pipe( fpu_regF_regF );
 10257 %}
 10259 // Mul two double precision floating piont number
 10260 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
 10261   match(Set dst (MulD src1 src2));
 10262   format %{ "MULD  $dst, $src1, $src2 @mulD_reg_reg" %}
 10263   ins_encode %{
 10264     FloatRegister src1 = $src1$$FloatRegister;
 10265     FloatRegister src2 = $src2$$FloatRegister;
 10266     FloatRegister dst  = $dst$$FloatRegister;
 10268     __ mul_d(dst, src1, src2);
 10269   %}
 10270   ins_pipe( fpu_regF_regF );
 10271 %}
 10273 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
 10274   match(Set dst (AddD (MulD src1 src2) src3));
 10275   // For compatibility reason (e.g. on the Loongson platform), disable this guy.
 10276   ins_cost(44444);
 10277   format %{ "maddD  $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
 10278   ins_encode %{
 10279     FloatRegister src1 = $src1$$FloatRegister;
 10280     FloatRegister src2 = $src2$$FloatRegister;
 10281     FloatRegister src3 = $src3$$FloatRegister;
 10282     FloatRegister dst  = $dst$$FloatRegister;
 10284     __ madd_d(dst, src1, src2, src3);
 10285   %}
 10286   ins_pipe( fpu_regF_regF );
 10287 %}
 10289 instruct absF_reg(regF dst, regF src) %{
 10290   match(Set dst (AbsF src));
 10291   ins_cost(100);
 10292   format %{ "absF  $dst, $src @absF_reg" %}
 10293   ins_encode %{
 10294     FloatRegister src = as_FloatRegister($src$$reg);
 10295     FloatRegister dst = as_FloatRegister($dst$$reg);
 10297     __ abs_s(dst, src);
 10298   %}
 10299   ins_pipe( fpu_regF_regF );
 10300 %}
 10303 // intrinsics for math_native.
 10304 // AbsD  SqrtD  CosD  SinD  TanD  LogD  Log10D
 10306 instruct absD_reg(regD dst, regD src) %{
 10307   match(Set dst (AbsD src));
 10308   ins_cost(100);
 10309   format %{ "absD  $dst, $src @absD_reg" %}
 10310   ins_encode %{
 10311     FloatRegister src = as_FloatRegister($src$$reg);
 10312     FloatRegister dst = as_FloatRegister($dst$$reg);
 10314     __ abs_d(dst, src);
 10315   %}
 10316   ins_pipe( fpu_regF_regF );
 10317 %}
 10319 instruct sqrtD_reg(regD dst, regD src) %{
 10320   match(Set dst (SqrtD src));
 10321   ins_cost(100);
 10322   format %{ "SqrtD  $dst, $src @sqrtD_reg" %}
 10323   ins_encode %{
 10324     FloatRegister src = as_FloatRegister($src$$reg);
 10325     FloatRegister dst = as_FloatRegister($dst$$reg);
 10327     __ sqrt_d(dst, src);
 10328   %}
 10329   ins_pipe( fpu_regF_regF );
 10330 %}
 10332 instruct sqrtF_reg(regF dst, regF src) %{
 10333   match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
 10334   ins_cost(100);
 10335   format %{ "SqrtF  $dst, $src @sqrtF_reg" %}
 10336   ins_encode %{
 10337     FloatRegister src = as_FloatRegister($src$$reg);
 10338     FloatRegister dst = as_FloatRegister($dst$$reg);
 10340     __ sqrt_s(dst, src);
 10341   %}
 10342   ins_pipe( fpu_regF_regF );
 10343 %}
 10344 //----------------------------------Logical Instructions----------------------
 10345 //__________________________________Integer Logical Instructions-------------
 10347 //And Instuctions
 10348 // And Register with Immediate
 10349 instruct andI_Reg_immI(mRegI dst, mRegI src1,  immI src2) %{
 10350   match(Set dst (AndI src1 src2));
 10352   format %{ "and  $dst, $src1, $src2 #@andI_Reg_immI" %}
 10353   ins_encode %{
 10354     Register dst = $dst$$Register;
 10355     Register src = $src1$$Register;
 10356     int      val = $src2$$constant;
 10358     __ move(AT, val);
 10359     __ andr(dst, src, AT);
 10360   %}
 10361   ins_pipe( ialu_regI_regI );
 10362 %}
 10364 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 10365   match(Set dst (AndI src1 src2));
 10366   ins_cost(60);
 10368   format %{ "and  $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
 10369   ins_encode %{
 10370     Register dst = $dst$$Register;
 10371     Register src = $src1$$Register;
 10372     int      val = $src2$$constant;
 10374     __ andi(dst, src, val);
 10375   %}
 10376   ins_pipe( ialu_regI_regI );
 10377 %}
 10379 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1,  immI_nonneg_mask mask) %{
 10380   match(Set dst (AndI src1 mask));
 10381   ins_cost(60);
 10383   format %{ "and  $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
 10384   ins_encode %{
 10385     Register dst = $dst$$Register;
 10386     Register src = $src1$$Register;
 10387     int     size = Assembler::is_int_mask($mask$$constant);
 10389     __ ext(dst, src, 0, size);
 10390   %}
 10391   ins_pipe( ialu_regI_regI );
 10392 %}
 10394 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1,  immL_nonneg_mask mask) %{
 10395   match(Set dst (AndL src1 mask));
 10396   ins_cost(60);
 10398   format %{ "and  $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
 10399   ins_encode %{
 10400     Register dst = $dst$$Register;
 10401     Register src = $src1$$Register;
 10402     int     size = Assembler::is_jlong_mask($mask$$constant);
 10404     __ dext(dst, src, 0, size);
 10405   %}
 10406   ins_pipe( ialu_regI_regI );
 10407 %}
 10409 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1,  immI_0_65535 src2) %{
 10410   match(Set dst (XorI src1 src2));
 10411   ins_cost(60);
 10413   format %{ "xori  $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
 10414   ins_encode %{
 10415     Register dst = $dst$$Register;
 10416     Register src = $src1$$Register;
 10417     int      val = $src2$$constant;
 10419        __ xori(dst, src, val);
 10420   %}
 10421   ins_pipe( ialu_regI_regI );
 10422 %}
 10424 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1,  immI_M1 M1) %{
 10425   match(Set dst (XorI src1 M1));
 10426   predicate(UseLoongsonISA && Use3A2000);
 10427   ins_cost(60);
 10429   format %{ "xor  $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
 10430   ins_encode %{
 10431     Register dst = $dst$$Register;
 10432     Register src = $src1$$Register;
 10434     __ gsorn(dst, R0, src);
 10435   %}
 10436   ins_pipe( ialu_regI_regI );
 10437 %}
 10439 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1,  immI_M1 M1) %{
 10440   match(Set dst (XorI (ConvL2I src1) M1));
 10441   predicate(UseLoongsonISA && Use3A2000);
 10442   ins_cost(60);
 10444   format %{ "xor  $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
 10445   ins_encode %{
 10446     Register dst = $dst$$Register;
 10447     Register src = $src1$$Register;
 10449     __ gsorn(dst, R0, src);
 10450   %}
 10451   ins_pipe( ialu_regI_regI );
 10452 %}
 10454 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 10455   match(Set dst (XorL src1 src2));
 10456   ins_cost(60);
 10458   format %{ "xori  $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
 10459   ins_encode %{
 10460     Register dst = $dst$$Register;
 10461     Register src = $src1$$Register;
 10462     int      val = $src2$$constant;
 10464        __ xori(dst, src, val);
 10465   %}
 10466   ins_pipe( ialu_regI_regI );
 10467 %}
 10469 /*
 10470 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1,  immL_M1 M1) %{
 10471   match(Set dst (XorL src1 M1));
 10472   predicate(UseLoongsonISA);
 10473   ins_cost(60);
 10475   format %{ "xor  $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
 10476   ins_encode %{
 10477     Register dst = $dst$$Register;
 10478     Register src = $src1$$Register;
 10480     __ gsorn(dst, R0, src);
 10481   %}
 10482   ins_pipe( ialu_regI_regI );
 10483 %}
 10484 */
 10486 instruct lbu_and_lmask(mRegI dst, memory mem,  immI_255 mask) %{
 10487   match(Set dst (AndI mask (LoadB mem)));
 10488   ins_cost(60);
 10490   format %{ "lhu  $dst, $mem #@lbu_and_lmask" %}
 10491   ins_encode(load_UB_enc(dst, mem));
 10492   ins_pipe( ialu_loadI );
 10493 %}
 10495 instruct lbu_and_rmask(mRegI dst, memory mem,  immI_255 mask) %{
 10496   match(Set dst (AndI (LoadB mem) mask));
 10497   ins_cost(60);
 10499   format %{ "lhu  $dst, $mem #@lbu_and_rmask" %}
 10500   ins_encode(load_UB_enc(dst, mem));
 10501   ins_pipe( ialu_loadI );
 10502 %}
 10504 instruct andI_Reg_Reg(mRegI dst, mRegI src1,  mRegI src2) %{
 10505   match(Set dst (AndI src1 src2));
 10507   format %{ "and    $dst, $src1, $src2 #@andI_Reg_Reg" %}
 10508   ins_encode %{
 10509     Register dst = $dst$$Register;
 10510     Register src1 = $src1$$Register;
 10511     Register src2 = $src2$$Register;
 10512     __ andr(dst, src1, src2);
 10513   %}
 10514   ins_pipe( ialu_regI_regI );
 10515 %}
 10517 instruct andnI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 10518   match(Set dst (AndI src1 (XorI src2 M1)));
 10519   predicate(UseLoongsonISA && Use3A2000);
 10521   format %{ "andn   $dst, $src1, $src2 #@andnI_Reg_nReg" %}
 10522   ins_encode %{
 10523     Register dst = $dst$$Register;
 10524     Register src1 = $src1$$Register;
 10525     Register src2 = $src2$$Register;
 10527     __ gsandn(dst, src1, src2);
 10528   %}
 10529   ins_pipe( ialu_regI_regI );
 10530 %}
 10532 instruct ornI_Reg_nReg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 10533   match(Set dst (OrI src1 (XorI src2 M1)));
 10534   predicate(UseLoongsonISA && Use3A2000);
 10536   format %{ "orn    $dst, $src1, $src2 #@ornI_Reg_nReg" %}
 10537   ins_encode %{
 10538     Register dst = $dst$$Register;
 10539     Register src1 = $src1$$Register;
 10540     Register src2 = $src2$$Register;
 10542     __ gsorn(dst, src1, src2);
 10543   %}
 10544   ins_pipe( ialu_regI_regI );
 10545 %}
 10547 instruct andnI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 10548   match(Set dst (AndI (XorI src1 M1) src2));
 10549   predicate(UseLoongsonISA && Use3A2000);
 10551   format %{ "andn   $dst, $src2, $src1 #@andnI_nReg_Reg" %}
 10552   ins_encode %{
 10553     Register dst = $dst$$Register;
 10554     Register src1 = $src1$$Register;
 10555     Register src2 = $src2$$Register;
 10557     __ gsandn(dst, src2, src1);
 10558   %}
 10559   ins_pipe( ialu_regI_regI );
 10560 %}
 10562 instruct ornI_nReg_Reg(mRegI dst, mRegI src1,  mRegI src2, immI_M1 M1) %{
 10563   match(Set dst (OrI (XorI src1 M1) src2));
 10564   predicate(UseLoongsonISA && Use3A2000);
 10566   format %{ "orn    $dst, $src2, $src1 #@ornI_nReg_Reg" %}
 10567   ins_encode %{
 10568     Register dst = $dst$$Register;
 10569     Register src1 = $src1$$Register;
 10570     Register src2 = $src2$$Register;
 10572     __ gsorn(dst, src2, src1);
 10573   %}
 10574   ins_pipe( ialu_regI_regI );
 10575 %}
 10577 // And Long Register with Register
 10578 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10579   match(Set dst (AndL src1 src2));
 10580   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
 10581   ins_encode %{
 10582     Register dst_reg = as_Register($dst$$reg);
 10583     Register src1_reg = as_Register($src1$$reg);
 10584     Register src2_reg = as_Register($src2$$reg);
 10586     __ andr(dst_reg, src1_reg, src2_reg);
 10587   %}
 10588   ins_pipe( ialu_regL_regL );
 10589 %}
 10591 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
 10592   match(Set dst (AndL src1 (ConvI2L src2)));
 10593   format %{ "AND    $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
 10594   ins_encode %{
 10595     Register dst_reg = as_Register($dst$$reg);
 10596     Register src1_reg = as_Register($src1$$reg);
 10597     Register src2_reg = as_Register($src2$$reg);
 10599     __ andr(dst_reg, src1_reg, src2_reg);
 10600   %}
 10601   ins_pipe( ialu_regL_regL );
 10602 %}
 10604 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1,  immL_0_65535 src2) %{
 10605   match(Set dst (AndL src1 src2));
 10606   ins_cost(60);
 10608   format %{ "and  $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
 10609   ins_encode %{
 10610     Register dst = $dst$$Register;
 10611     Register src = $src1$$Register;
 10612     long     val = $src2$$constant;
 10614        __ andi(dst, src, val);
 10615   %}
 10616   ins_pipe( ialu_regI_regI );
 10617 %}
 10619 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1,  immL_0_65535 src2) %{
 10620   match(Set dst (ConvL2I (AndL src1 src2)));
 10621   ins_cost(60);
 10623   format %{ "and  $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
 10624   ins_encode %{
 10625     Register dst = $dst$$Register;
 10626     Register src = $src1$$Register;
 10627     long     val = $src2$$constant;
 10629        __ andi(dst, src, val);
 10630   %}
 10631   ins_pipe( ialu_regI_regI );
 10632 %}
 10634 /*
 10635 instruct andnL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 10636   match(Set dst (AndL src1 (XorL src2 M1)));
 10637   predicate(UseLoongsonISA);
 10639   format %{ "andn   $dst, $src1, $src2 #@andnL_Reg_nReg" %}
 10640   ins_encode %{
 10641     Register dst = $dst$$Register;
 10642     Register src1 = $src1$$Register;
 10643     Register src2 = $src2$$Register;
 10645     __ gsandn(dst, src1, src2);
 10646   %}
 10647   ins_pipe( ialu_regI_regI );
 10648 %}
 10649 */
 10651 /*
 10652 instruct ornL_Reg_nReg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 10653   match(Set dst (OrL src1 (XorL src2 M1)));
 10654   predicate(UseLoongsonISA);
 10656   format %{ "orn    $dst, $src1, $src2 #@ornL_Reg_nReg" %}
 10657   ins_encode %{
 10658     Register dst = $dst$$Register;
 10659     Register src1 = $src1$$Register;
 10660     Register src2 = $src2$$Register;
 10662     __ gsorn(dst, src1, src2);
 10663   %}
 10664   ins_pipe( ialu_regI_regI );
 10665 %}
 10666 */
 10668 /*
 10669 instruct andnL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 10670   match(Set dst (AndL (XorL src1 M1) src2));
 10671   predicate(UseLoongsonISA);
 10673   format %{ "andn   $dst, $src2, $src1 #@andnL_nReg_Reg" %}
 10674   ins_encode %{
 10675     Register dst = $dst$$Register;
 10676     Register src1 = $src1$$Register;
 10677     Register src2 = $src2$$Register;
 10679     __ gsandn(dst, src2, src1);
 10680   %}
 10681   ins_pipe( ialu_regI_regI );
 10682 %}
 10683 */
 10685 /*
 10686 instruct ornL_nReg_Reg(mRegL dst, mRegL src1,  mRegL src2, immL_M1 M1) %{
 10687   match(Set dst (OrL (XorL src1 M1) src2));
 10688   predicate(UseLoongsonISA);
 10690   format %{ "orn    $dst, $src2, $src1 #@ornL_nReg_Reg" %}
 10691   ins_encode %{
 10692     Register dst = $dst$$Register;
 10693     Register src1 = $src1$$Register;
 10694     Register src2 = $src2$$Register;
 10696     __ gsorn(dst, src2, src1);
 10697   %}
 10698   ins_pipe( ialu_regI_regI );
 10699 %}
 10700 */
 10702 instruct andL_Reg_immL_M8(mRegL dst,  immL_M8 M8) %{
 10703   match(Set dst (AndL dst M8));
 10704   ins_cost(60);
 10706   format %{ "and  $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
 10707   ins_encode %{
 10708     Register dst = $dst$$Register;
 10710     __ dins(dst, R0, 0, 3);
 10711   %}
 10712   ins_pipe( ialu_regI_regI );
 10713 %}
 10715 instruct andL_Reg_immL_M5(mRegL dst,  immL_M5 M5) %{
 10716   match(Set dst (AndL dst M5));
 10717   ins_cost(60);
 10719   format %{ "and  $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
 10720   ins_encode %{
 10721     Register dst = $dst$$Register;
 10723     __ dins(dst, R0, 2, 1);
 10724   %}
 10725   ins_pipe( ialu_regI_regI );
 10726 %}
 10728 instruct andL_Reg_immL_M7(mRegL dst,  immL_M7 M7) %{
 10729   match(Set dst (AndL dst M7));
 10730   ins_cost(60);
 10732   format %{ "and  $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
 10733   ins_encode %{
 10734     Register dst = $dst$$Register;
 10736     __ dins(dst, R0, 1, 2);
 10737   %}
 10738   ins_pipe( ialu_regI_regI );
 10739 %}
 10741 instruct andL_Reg_immL_M4(mRegL dst,  immL_M4 M4) %{
 10742   match(Set dst (AndL dst M4));
 10743   ins_cost(60);
 10745   format %{ "and  $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
 10746   ins_encode %{
 10747     Register dst = $dst$$Register;
 10749     __ dins(dst, R0, 0, 2);
 10750   %}
 10751   ins_pipe( ialu_regI_regI );
 10752 %}
 10754 instruct andL_Reg_immL_M121(mRegL dst,  immL_M121 M121) %{
 10755   match(Set dst (AndL dst M121));
 10756   ins_cost(60);
 10758   format %{ "and  $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
 10759   ins_encode %{
 10760     Register dst = $dst$$Register;
 10762     __ dins(dst, R0, 3, 4);
 10763   %}
 10764   ins_pipe( ialu_regI_regI );
 10765 %}
 10767 // Or Long Register with Register
 10768 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10769   match(Set dst (OrL src1 src2));
 10770   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
 10771   ins_encode %{
 10772     Register dst_reg  = $dst$$Register;
 10773     Register src1_reg = $src1$$Register;
 10774     Register src2_reg = $src2$$Register;
 10776     __ orr(dst_reg, src1_reg, src2_reg);
 10777   %}
 10778   ins_pipe( ialu_regL_regL );
 10779 %}
 10781 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
 10782   match(Set dst (OrL (CastP2X src1) src2));
 10783   format %{ "OR    $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
 10784   ins_encode %{
 10785     Register dst_reg  = $dst$$Register;
 10786     Register src1_reg = $src1$$Register;
 10787     Register src2_reg = $src2$$Register;
 10789     __ orr(dst_reg, src1_reg, src2_reg);
 10790   %}
 10791   ins_pipe( ialu_regL_regL );
 10792 %}
 10794 // Xor Long Register with Register
 10795 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
 10796   match(Set dst (XorL src1 src2));
 10797   format %{ "XOR    $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
 10798   ins_encode %{
 10799     Register dst_reg = as_Register($dst$$reg);
 10800     Register src1_reg = as_Register($src1$$reg);
 10801     Register src2_reg = as_Register($src2$$reg);
 10803     __ xorr(dst_reg, src1_reg, src2_reg);
 10804   %}
 10805   ins_pipe( ialu_regL_regL );
 10806 %}
 10808 // Shift Left by 8-bit immediate
 10809 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 10810   match(Set dst (LShiftI src shift));
 10812   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm" %}
 10813   ins_encode %{
 10814     Register src = $src$$Register;
 10815     Register dst = $dst$$Register;
 10816     int    shamt = $shift$$constant;
 10818     __ sll(dst, src, shamt);
 10819   %}
 10820   ins_pipe( ialu_regI_regI );
 10821 %}
 10823 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
 10824   match(Set dst (LShiftI (ConvL2I src) shift));
 10826   format %{ "SHL    $dst, $src, $shift #@salL2I_Reg_imm" %}
 10827   ins_encode %{
 10828     Register src = $src$$Register;
 10829     Register dst = $dst$$Register;
 10830     int    shamt = $shift$$constant;
 10832     __ sll(dst, src, shamt);
 10833   %}
 10834   ins_pipe( ialu_regI_regI );
 10835 %}
 10837 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
 10838   match(Set dst (AndI (LShiftI src shift) mask));
 10840   format %{ "SHL    $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
 10841   ins_encode %{
 10842     Register src = $src$$Register;
 10843     Register dst = $dst$$Register;
 10845     __ sll(dst, src, 16);
 10846   %}
 10847   ins_pipe( ialu_regI_regI );
 10848 %}
 10850 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
 10851 %{
 10852   match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
 10854   format %{ "andi  $dst, $src, 7\t# @land7_2_s" %}
 10855   ins_encode %{
 10856     Register src = $src$$Register;
 10857     Register dst = $dst$$Register;
 10859     __ andi(dst, src, 7);
 10860   %}
 10861   ins_pipe(ialu_regI_regI);
 10862 %}
 10864 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
 10865 %{
 10866   match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
 10868   format %{ "ori  $dst, $src1, $src2\t# @ori2s" %}
 10869   ins_encode %{
 10870     Register src = $src1$$Register;
 10871     int      val = $src2$$constant;
 10872     Register dst = $dst$$Register;
 10874     __ ori(dst, src, val);
 10875   %}
 10876   ins_pipe(ialu_regI_regI);
 10877 %}
 10879 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
 10880 // This idiom is used by the compiler the i2s bytecode.
 10881 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
 10882 %{
 10883   match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
 10885   format %{ "i2s  $dst, $src\t# @i2s" %}
 10886   ins_encode %{
 10887     Register src = $src$$Register;
 10888     Register dst = $dst$$Register;
 10890     __ seh(dst, src);
 10891   %}
 10892   ins_pipe(ialu_regI_regI);
 10893 %}
 10895 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 10896 // This idiom is used by the compiler for the i2b bytecode.
 10897 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
 10898 %{
 10899   match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
 10901   format %{ "i2b  $dst, $src\t# @i2b" %}
 10902   ins_encode %{
 10903     Register src = $src$$Register;
 10904     Register dst = $dst$$Register;
 10906     __ seb(dst, src);
 10907   %}
 10908   ins_pipe(ialu_regI_regI);
 10909 %}
 10912 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
 10913   match(Set dst (LShiftI (ConvL2I src) shift));
 10915   format %{ "SHL    $dst, $src, $shift #@salI_RegL2I_imm" %}
 10916   ins_encode %{
 10917     Register src = $src$$Register;
 10918     Register dst = $dst$$Register;
 10919     int    shamt = $shift$$constant;
 10921     __ sll(dst, src, shamt);
 10922   %}
 10923   ins_pipe( ialu_regI_regI );
 10924 %}
 10926 // Shift Left by 8-bit immediate
 10927 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 10928   match(Set dst (LShiftI src shift));
 10930   format %{ "SHL    $dst, $src, $shift #@salI_Reg_Reg" %}
 10931   ins_encode %{
 10932     Register src = $src$$Register;
 10933     Register dst = $dst$$Register;
 10934     Register shamt = $shift$$Register;
 10935     __ sllv(dst, src, shamt);
 10936   %}
 10937   ins_pipe( ialu_regI_regI );
 10938 %}
 10941 // Shift Left Long
 10942 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 10943   //predicate(UseNewLongLShift);
 10944   match(Set dst (LShiftL src shift));
 10945   ins_cost(100);
 10946   format %{ "salL    $dst, $src, $shift @ salL_Reg_imm" %}
 10947   ins_encode %{
 10948     Register src_reg = as_Register($src$$reg);
 10949     Register dst_reg = as_Register($dst$$reg);
 10950     int      shamt = $shift$$constant;
 10952     if (__ is_simm(shamt, 5))
 10953         __ dsll(dst_reg, src_reg, shamt);
 10954     else {
 10955       int sa = Assembler::low(shamt, 6);
 10956       if (sa < 32) {
 10957         __ dsll(dst_reg, src_reg, sa);
 10958       } else {
 10959         __ dsll32(dst_reg, src_reg, sa - 32);
 10962   %}
 10963   ins_pipe( ialu_regL_regL );
 10964 %}
 10966 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
 10967   //predicate(UseNewLongLShift);
 10968   match(Set dst (LShiftL (ConvI2L src) shift));
 10969   ins_cost(100);
 10970   format %{ "salL    $dst, $src, $shift @ salL_RegI2L_imm" %}
 10971   ins_encode %{
 10972     Register src_reg = as_Register($src$$reg);
 10973     Register dst_reg = as_Register($dst$$reg);
 10974     int      shamt = $shift$$constant;
 10976     if (__ is_simm(shamt, 5))
 10977         __ dsll(dst_reg, src_reg, shamt);
 10978     else {
 10979       int sa = Assembler::low(shamt, 6);
 10980       if (sa < 32) {
 10981         __ dsll(dst_reg, src_reg, sa);
 10982       } else {
 10983         __ dsll32(dst_reg, src_reg, sa - 32);
 10986   %}
 10987   ins_pipe( ialu_regL_regL );
 10988 %}
 10990 // Shift Left Long
 10991 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 10992   //predicate(UseNewLongLShift);
 10993   match(Set dst (LShiftL src shift));
 10994   ins_cost(100);
 10995   format %{ "salL    $dst, $src, $shift @ salL_Reg_Reg" %}
 10996   ins_encode %{
 10997     Register src_reg = as_Register($src$$reg);
 10998     Register dst_reg = as_Register($dst$$reg);
 11000     __ dsllv(dst_reg, src_reg, $shift$$Register);
 11001   %}
 11002   ins_pipe( ialu_regL_regL );
 11003 %}
 11005 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
 11006   match(Set dst (LShiftL (ConvI2L src) shift));
 11007   ins_cost(100);
 11008   format %{ "salL    $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
 11009   ins_encode %{
 11010     Register src_reg = as_Register($src$$reg);
 11011     Register dst_reg = as_Register($dst$$reg);
 11012     int      shamt = $shift$$constant;
 11014     if (__ is_simm(shamt, 5)) {
 11015       __ dsll(dst_reg, src_reg, shamt);
 11016     } else {
 11017       int sa = Assembler::low(shamt, 6);
 11018       if (sa < 32) {
 11019         __ dsll(dst_reg, src_reg, sa);
 11020       } else {
 11021         __ dsll32(dst_reg, src_reg, sa - 32);
 11024     %}
 11025   ins_pipe( ialu_regL_regL );
 11026 %}
 11028 // Shift Right Long
 11029 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
 11030   match(Set dst (RShiftL src shift));
 11031   ins_cost(100);
 11032   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_imm" %}
 11033   ins_encode %{
 11034     Register src_reg = as_Register($src$$reg);
 11035     Register dst_reg = as_Register($dst$$reg);
 11036     int      shamt = ($shift$$constant & 0x3f);
 11037     if (__  is_simm(shamt, 5))
 11038       __ dsra(dst_reg, src_reg, shamt);
 11039     else {
 11040       int sa = Assembler::low(shamt, 6);
 11041       if (sa < 32) {
 11042         __ dsra(dst_reg, src_reg, sa);
 11043       } else {
 11044         __ dsra32(dst_reg, src_reg, sa - 32);
 11047   %}
 11048   ins_pipe( ialu_regL_regL );
 11049 %}
 11051 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
 11052   match(Set dst (ConvL2I (RShiftL src shift)));
 11053   ins_cost(100);
 11054   format %{ "sarL    $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
 11055   ins_encode %{
 11056     Register src_reg = as_Register($src$$reg);
 11057     Register dst_reg = as_Register($dst$$reg);
 11058     int      shamt   = $shift$$constant;
 11060     __ dsra32(dst_reg, src_reg, shamt - 32);
 11061   %}
 11062   ins_pipe( ialu_regL_regL );
 11063 %}
 11065 // Shift Right Long arithmetically
 11066 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 11067   //predicate(UseNewLongLShift);
 11068   match(Set dst (RShiftL src shift));
 11069   ins_cost(100);
 11070   format %{ "sarL    $dst, $src, $shift @ sarL_Reg_Reg" %}
 11071   ins_encode %{
 11072     Register src_reg = as_Register($src$$reg);
 11073     Register dst_reg = as_Register($dst$$reg);
 11075     __ dsrav(dst_reg, src_reg, $shift$$Register);
 11076   %}
 11077   ins_pipe( ialu_regL_regL );
 11078 %}
 11080 // Shift Right Long logically
 11081 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
 11082   match(Set dst (URShiftL src shift));
 11083   ins_cost(100);
 11084   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_Reg" %}
 11085   ins_encode %{
 11086     Register src_reg = as_Register($src$$reg);
 11087     Register dst_reg = as_Register($dst$$reg);
 11089     __ dsrlv(dst_reg, src_reg, $shift$$Register);
 11090   %}
 11091   ins_pipe( ialu_regL_regL );
 11092 %}
 11094 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
 11095   match(Set dst (URShiftL src shift));
 11096   ins_cost(80);
 11097   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
 11098   ins_encode %{
 11099     Register src_reg = as_Register($src$$reg);
 11100     Register dst_reg = as_Register($dst$$reg);
 11101     int        shamt = $shift$$constant;
 11103     __ dsrl(dst_reg, src_reg, shamt);
 11104   %}
 11105   ins_pipe( ialu_regL_regL );
 11106 %}
 11108 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
 11109   match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
 11110   ins_cost(80);
 11111   format %{ "dext    $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
 11112   ins_encode %{
 11113     Register src_reg = as_Register($src$$reg);
 11114     Register dst_reg = as_Register($dst$$reg);
 11115     int        shamt = $shift$$constant;
 11117     __ dext(dst_reg, src_reg, shamt, 31);
 11118   %}
 11119   ins_pipe( ialu_regL_regL );
 11120 %}
 11122 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
 11123   match(Set dst (URShiftL (CastP2X src) shift));
 11124   ins_cost(80);
 11125   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
 11126   ins_encode %{
 11127     Register src_reg = as_Register($src$$reg);
 11128     Register dst_reg = as_Register($dst$$reg);
 11129     int        shamt = $shift$$constant;
 11131     __ dsrl(dst_reg, src_reg, shamt);
 11132   %}
 11133   ins_pipe( ialu_regL_regL );
 11134 %}
 11136 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
 11137   match(Set dst (URShiftL src shift));
 11138   ins_cost(80);
 11139   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
 11140   ins_encode %{
 11141     Register src_reg = as_Register($src$$reg);
 11142     Register dst_reg = as_Register($dst$$reg);
 11143     int        shamt = $shift$$constant;
 11145     __ dsrl32(dst_reg, src_reg, shamt - 32);
 11146   %}
 11147   ins_pipe( ialu_regL_regL );
 11148 %}
 11150 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
 11151   match(Set dst (ConvL2I (URShiftL src shift)));
 11152   predicate(n->in(1)->in(2)->get_int() > 32);
 11153   ins_cost(80);
 11154   format %{ "slrL    $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
 11155   ins_encode %{
 11156     Register src_reg = as_Register($src$$reg);
 11157     Register dst_reg = as_Register($dst$$reg);
 11158     int        shamt = $shift$$constant;
 11160     __ dsrl32(dst_reg, src_reg, shamt - 32);
 11161   %}
 11162   ins_pipe( ialu_regL_regL );
 11163 %}
 11165 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
 11166   match(Set dst (URShiftL (CastP2X src) shift));
 11167   ins_cost(80);
 11168   format %{ "slrL    $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
 11169   ins_encode %{
 11170     Register src_reg = as_Register($src$$reg);
 11171     Register dst_reg = as_Register($dst$$reg);
 11172     int        shamt = $shift$$constant;
 11174     __ dsrl32(dst_reg, src_reg, shamt - 32);
 11175   %}
 11176   ins_pipe( ialu_regL_regL );
 11177 %}
 11179 // Xor Instructions
 11180 // Xor Register with Register
 11181 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11182   match(Set dst (XorI src1 src2));
 11184   format %{ "XOR    $dst, $src1, $src2 #@xorI_Reg_Reg" %}
 11186   ins_encode %{
 11187     Register  dst = $dst$$Register;
 11188     Register src1 = $src1$$Register;
 11189     Register src2 = $src2$$Register;
 11190     __ xorr(dst, src1, src2);
 11191     __ sll(dst, dst, 0); /* long -> int */
 11192   %}
 11194   ins_pipe( ialu_regI_regI );
 11195 %}
 11197 // Or Instructions
 11198 // Or Register with Register
 11199 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
 11200   match(Set dst (OrI src1 src2));
 11202   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_Reg" %}
 11203   ins_encode %{
 11204     Register  dst = $dst$$Register;
 11205     Register src1 = $src1$$Register;
 11206     Register src2 = $src2$$Register;
 11207     __ orr(dst, src1, src2);
 11208   %}
 11210   ins_pipe( ialu_regI_regI );
 11211 %}
 11213 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
 11214   match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
 11215   predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
 11217   format %{ "rotr     $dst, $src, 1 ...\n\t"
 11218             "srl      $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
 11219   ins_encode %{
 11220     Register   dst = $dst$$Register;
 11221     Register   src = $src$$Register;
 11222     int     rshift = $rshift$$constant;
 11224     __ rotr(dst, src, 1);
 11225     if (rshift - 1) {
 11226       __ srl(dst, dst, rshift - 1);
 11228   %}
 11230   ins_pipe( ialu_regI_regI );
 11231 %}
 11233 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
 11234   match(Set dst (OrI src1 (CastP2X src2)));
 11236   format %{ "OR     $dst, $src1, $src2 #@orI_Reg_castP2X" %}
 11237   ins_encode %{
 11238     Register  dst = $dst$$Register;
 11239     Register src1 = $src1$$Register;
 11240     Register src2 = $src2$$Register;
 11241     __ orr(dst, src1, src2);
 11242   %}
 11244   ins_pipe( ialu_regI_regI );
 11245 %}
 11247 // Logical Shift Right by 8-bit immediate
 11248 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 11249   match(Set dst (URShiftI src shift));
 11250   //effect(KILL cr);
 11252   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_imm" %}
 11253   ins_encode %{
 11254     Register src = $src$$Register;
 11255     Register dst = $dst$$Register;
 11256     int    shift = $shift$$constant;
 11258     __ srl(dst, src, shift);
 11259   %}
 11260   ins_pipe( ialu_regI_regI );
 11261 %}
 11263 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
 11264   match(Set dst (AndI (URShiftI src shift) mask));
 11266   format %{ "ext    $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
 11267   ins_encode %{
 11268     Register src = $src$$Register;
 11269     Register dst = $dst$$Register;
 11270     int      pos = $shift$$constant;
 11271     int     size = Assembler::is_int_mask($mask$$constant);
 11273     __ ext(dst, src, pos, size);
 11274   %}
 11275   ins_pipe( ialu_regI_regI );
 11276 %}
 11278 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
 11279 %{
 11280   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 11281   match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
 11283   ins_cost(100);
 11284   format %{ "rotr    $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
 11285   ins_encode %{
 11286     Register dst = $dst$$Register;
 11287     int      sa  = $rshift$$constant;
 11289     __ rotr(dst, dst, sa);
 11290   %}
 11291   ins_pipe( ialu_regI_regI );
 11292 %}
 11294 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
 11295 %{
 11296   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 11297   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 11299   ins_cost(100);
 11300   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
 11301   ins_encode %{
 11302     Register dst = $dst$$Register;
 11303     int      sa  = $rshift$$constant;
 11305     __ drotr(dst, dst, sa);
 11306   %}
 11307   ins_pipe( ialu_regI_regI );
 11308 %}
 11310 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
 11311 %{
 11312   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 11313   match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
 11315   ins_cost(100);
 11316   format %{ "rotr    $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
 11317   ins_encode %{
 11318     Register dst = $dst$$Register;
 11319     int      sa  = $rshift$$constant;
 11321     __ drotr32(dst, dst, sa - 32);
 11322   %}
 11323   ins_pipe( ialu_regI_regI );
 11324 %}
 11326 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
 11327 %{
 11328   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
 11329   match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
 11331   ins_cost(100);
 11332   format %{ "rotr    $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
 11333   ins_encode %{
 11334     Register dst = $dst$$Register;
 11335     int      sa  = $rshift$$constant;
 11337     __ rotr(dst, dst, sa);
 11338   %}
 11339   ins_pipe( ialu_regI_regI );
 11340 %}
 11342 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
 11343 %{
 11344   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 11345   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 11347   ins_cost(100);
 11348   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
 11349   ins_encode %{
 11350     Register dst = $dst$$Register;
 11351     int      sa  = $rshift$$constant;
 11353     __ drotr(dst, dst, sa);
 11354   %}
 11355   ins_pipe( ialu_regI_regI );
 11356 %}
 11358 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
 11359 %{
 11360   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
 11361   match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
 11363   ins_cost(100);
 11364   format %{ "rotr    $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
 11365   ins_encode %{
 11366     Register dst = $dst$$Register;
 11367     int      sa  = $rshift$$constant;
 11369     __ drotr32(dst, dst, sa - 32);
 11370   %}
 11371   ins_pipe( ialu_regI_regI );
 11372 %}
 11374 // Logical Shift Right
 11375 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 11376   match(Set dst (URShiftI src shift));
 11378   format %{ "SRL    $dst, $src, $shift #@shr_logical_Reg_Reg" %}
 11379   ins_encode %{
 11380     Register src = $src$$Register;
 11381     Register dst = $dst$$Register;
 11382     Register shift = $shift$$Register;
 11383     __ srlv(dst, src, shift);
 11384   %}
 11385   ins_pipe( ialu_regI_regI );
 11386 %}
 11389 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
 11390   match(Set dst (RShiftI src shift));
 11391  // effect(KILL cr);
 11393   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_imm" %}
 11394   ins_encode %{
 11395     Register src = $src$$Register;
 11396     Register dst = $dst$$Register;
 11397     int    shift = $shift$$constant;
 11398     __ sra(dst, src, shift);
 11399   %}
 11400   ins_pipe( ialu_regI_regI );
 11401 %}
 11403 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
 11404   match(Set dst (RShiftI src shift));
 11405  // effect(KILL cr);
 11407   format %{ "SRA    $dst, $src, $shift #@shr_arith_Reg_Reg" %}
 11408   ins_encode %{
 11409     Register src = $src$$Register;
 11410     Register dst = $dst$$Register;
 11411     Register shift = $shift$$Register;
 11412     __ srav(dst, src, shift);
 11413   %}
 11414   ins_pipe( ialu_regI_regI );
 11415 %}
 11417 //----------Convert Int to Boolean---------------------------------------------
 11419 instruct convI2B(mRegI dst, mRegI src) %{
 11420   match(Set dst (Conv2B src));
 11422   ins_cost(100);
 11423   format %{ "convI2B    $dst, $src @ convI2B"  %}
 11424   ins_encode %{
 11425     Register dst = as_Register($dst$$reg);
 11426     Register src = as_Register($src$$reg);
 11428     if (dst != src) {
 11429       __ daddiu(dst, R0, 1);
 11430       __ movz(dst, R0, src);
 11431     } else {
 11432       __ move(AT, src);
 11433       __ daddiu(dst, R0, 1);
 11434       __ movz(dst, R0, AT);
 11436   %}
 11438   ins_pipe( ialu_regL_regL );
 11439 %}
 11441 instruct convI2L_reg( mRegL dst, mRegI src) %{
 11442   match(Set dst (ConvI2L src));
 11444   ins_cost(100);
 11445   format %{ "SLL    $dst, $src @ convI2L_reg\t"  %}
 11446   ins_encode %{
 11447     Register dst = as_Register($dst$$reg);
 11448     Register src = as_Register($src$$reg);
 11450     if(dst != src) __ sll(dst, src, 0);
 11451   %}
 11452   ins_pipe( ialu_regL_regL );
 11453 %}
 11456 instruct convL2I_reg( mRegI dst, mRegL src ) %{
 11457   match(Set dst (ConvL2I src));
 11459   format %{ "MOV    $dst, $src @ convL2I_reg" %}
 11460   ins_encode %{
 11461     Register dst = as_Register($dst$$reg);
 11462     Register src = as_Register($src$$reg);
 11464     __ sll(dst, src, 0);
 11465   %}
 11467   ins_pipe( ialu_regI_regI );
 11468 %}
 11470 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
 11471   match(Set dst (ConvI2L (ConvL2I src)));
 11473   format %{ "sll    $dst, $src, 0 @ convL2I2L_reg" %}
 11474   ins_encode %{
 11475     Register dst = as_Register($dst$$reg);
 11476     Register src = as_Register($src$$reg);
 11478     __ sll(dst, src, 0);
 11479   %}
 11481   ins_pipe( ialu_regI_regI );
 11482 %}
 11484 instruct convL2D_reg( regD dst, mRegL src ) %{
 11485   match(Set dst (ConvL2D src));
 11486   format %{ "convL2D    $dst, $src @ convL2D_reg" %}
 11487   ins_encode %{
 11488     Register src = as_Register($src$$reg);
 11489     FloatRegister dst = as_FloatRegister($dst$$reg);
 11491     __ dmtc1(src, dst);
 11492     __ cvt_d_l(dst, dst);
 11493   %}
 11495   ins_pipe( pipe_slow );
 11496 %}
 11499 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
 11500   match(Set dst (ConvD2L src));
 11501   ins_cost(150);
 11502   format %{ "convD2L    $dst, $src @ convD2L_reg_fast" %}
 11503   ins_encode %{
 11504     Register dst = as_Register($dst$$reg);
 11505     FloatRegister src = as_FloatRegister($src$$reg);
 11507     Label Done;
 11509     __ trunc_l_d(F30, src);
 11510     // max_long:    0x7fffffffffffffff
 11511     // __ set64(AT, 0x7fffffffffffffff);
 11512     __ daddiu(AT, R0, -1);
 11513     __ dsrl(AT, AT, 1);
 11514     __ dmfc1(dst, F30);
 11516     __ bne(dst, AT, Done);
 11517     __ delayed()->mtc1(R0, F30);
 11519     __ cvt_d_w(F30, F30);
 11520     __ c_ult_d(src, F30);
 11521     __ bc1f(Done);
 11522     __ delayed()->daddiu(T9, R0, -1);
 11524     __ c_un_d(src, src);    //NaN?
 11525     __ subu(dst, T9, AT);
 11526     __ movt(dst, R0);
 11528     __ bind(Done);
 11529   %}
 11531   ins_pipe( pipe_slow );
 11532 %}
 11535 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
 11536   match(Set dst (ConvD2L src));
 11537   ins_cost(250);
 11538   format %{ "convD2L    $dst, $src @ convD2L_reg_slow" %}
 11539   ins_encode %{
 11540     Register dst = as_Register($dst$$reg);
 11541     FloatRegister src = as_FloatRegister($src$$reg);
 11543     Label L;
 11545     __ c_un_d(src, src);    //NaN?
 11546     __ bc1t(L);
 11547     __ delayed();
 11548     __ move(dst, R0);
 11550     __ trunc_l_d(F30, src);
 11551     __ cfc1(AT, 31);
 11552     __ li(T9, 0x10000);
 11553     __ andr(AT, AT, T9);
 11554     __ beq(AT, R0, L);
 11555     __ delayed()->dmfc1(dst, F30);
 11557     __ mov_d(F12, src);
 11558     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
 11559     __ move(dst, V0);
 11560     __ bind(L);
 11561   %}
 11563   ins_pipe( pipe_slow );
 11564 %}
 11567 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
 11568   match(Set dst (ConvF2I src));
 11569   ins_cost(150);
 11570   format %{ "convf2i    $dst, $src @ convF2I_reg_fast" %}
 11571   ins_encode %{
 11572     Register      dreg = $dst$$Register;
 11573     FloatRegister fval = $src$$FloatRegister;
 11574     Label L;
 11576     __ trunc_w_s(F30, fval);
 11577     __ move(AT, 0x7fffffff);
 11578     __ mfc1(dreg, F30);
 11579     __ c_un_s(fval, fval);    //NaN?
 11580     __ movt(dreg, R0);
 11582     __ bne(AT, dreg, L);
 11583     __ delayed()->lui(T9, 0x8000);
 11585     __ mfc1(AT, fval);
 11586     __ andr(AT, AT, T9);
 11588     __ movn(dreg, T9, AT);
 11590     __ bind(L);
 11592   %}
 11594   ins_pipe( pipe_slow );
 11595 %}
 11599 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
 11600   match(Set dst (ConvF2I src));
 11601   ins_cost(250);
 11602   format %{ "convf2i    $dst, $src @ convF2I_reg_slow" %}
 11603   ins_encode %{
 11604     Register      dreg = $dst$$Register;
 11605     FloatRegister fval = $src$$FloatRegister;
 11606     Label L;
 11608     __ c_un_s(fval, fval);    //NaN?
 11609     __ bc1t(L);
 11610     __ delayed();
 11611     __ move(dreg, R0);
 11613     __ trunc_w_s(F30, fval);
 11615     /* Call SharedRuntime:f2i() to do valid convention */
 11616     __ cfc1(AT, 31);
 11617     __ li(T9, 0x10000);
 11618     __ andr(AT, AT, T9);
 11619     __ beq(AT, R0, L);
 11620     __ delayed()->mfc1(dreg, F30);
 11622     __ mov_s(F12, fval);
 11624     /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
 11625      *    J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
 11627      * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
 11628      * V0 is corrupted during call_VM_leaf(), and should be preserved.
 11629      */
 11630     __ push(fval);
 11631     if(dreg != V0) {
 11632       __ push(V0);
 11634     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
 11635     if(dreg != V0) {
 11636       __ move(dreg, V0);
 11637       __ pop(V0);
 11639     __ pop(fval);
 11640     __ bind(L);
 11641   %}
 11643   ins_pipe( pipe_slow );
 11644 %}
 11647 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
 11648   match(Set dst (ConvF2L src));
 11649   ins_cost(150);
 11650   format %{ "convf2l    $dst, $src @ convF2L_reg_fast" %}
 11651   ins_encode %{
 11652     Register      dreg = $dst$$Register;
 11653     FloatRegister fval = $src$$FloatRegister;
 11654     Label L;
 11656     __ trunc_l_s(F30, fval);
 11657     __ daddiu(AT, R0, -1);
 11658     __ dsrl(AT, AT, 1);
 11659     __ dmfc1(dreg, F30);
 11660     __ c_un_s(fval, fval);    //NaN?
 11661     __ movt(dreg, R0);
 11663     __ bne(AT, dreg, L);
 11664     __ delayed()->lui(T9, 0x8000);
 11666     __ mfc1(AT, fval);
 11667     __ andr(AT, AT, T9);
 11669     __ dsll32(T9, T9, 0);
 11670     __ movn(dreg, T9, AT);
 11672     __ bind(L);
 11673   %}
 11675   ins_pipe( pipe_slow );
 11676 %}
 11679 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
 11680   match(Set dst (ConvF2L src));
 11681   ins_cost(250);
 11682   format %{ "convf2l    $dst, $src @ convF2L_reg_slow" %}
 11683   ins_encode %{
 11684     Register dst = as_Register($dst$$reg);
 11685     FloatRegister fval = $src$$FloatRegister;
 11686     Label L;
 11688     __ c_un_s(fval, fval);    //NaN?
 11689     __ bc1t(L);
 11690     __ delayed();
 11691     __ move(dst, R0);
 11693     __ trunc_l_s(F30, fval);
 11694     __ cfc1(AT, 31);
 11695     __ li(T9, 0x10000);
 11696     __ andr(AT, AT, T9);
 11697     __ beq(AT, R0, L);
 11698     __ delayed()->dmfc1(dst, F30);
 11700     __ mov_s(F12, fval);
 11701     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
 11702     __ move(dst, V0);
 11703     __ bind(L);
 11704   %}
 11706   ins_pipe( pipe_slow );
 11707 %}
 11709 instruct convL2F_reg( regF dst, mRegL src ) %{
 11710   match(Set dst (ConvL2F src));
 11711   format %{ "convl2f    $dst, $src @ convL2F_reg" %}
 11712   ins_encode %{
 11713     FloatRegister dst = $dst$$FloatRegister;
 11714     Register src = as_Register($src$$reg);
 11715     Label L;
 11717     __ dmtc1(src, dst);
 11718     __ cvt_s_l(dst, dst);
 11719   %}
 11721   ins_pipe( pipe_slow );
 11722 %}
 11724 instruct convI2F_reg( regF dst, mRegI src ) %{
 11725   match(Set dst (ConvI2F src));
 11726   format %{ "convi2f    $dst, $src @ convI2F_reg" %}
 11727   ins_encode %{
 11728     Register      src = $src$$Register;
 11729     FloatRegister dst = $dst$$FloatRegister;
 11731     __ mtc1(src, dst);
 11732     __ cvt_s_w(dst, dst);
 11733   %}
 11735   ins_pipe( fpu_regF_regF );
 11736 %}
 11738 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
 11739   match(Set dst (CmpLTMask p zero));
 11740   ins_cost(100);
 11742   format %{ "sra    $dst, $p, 31 @ cmpLTMask_immI0" %}
 11743     ins_encode %{
 11744        Register src = $p$$Register;
 11745        Register dst = $dst$$Register;
 11747        __ sra(dst, src, 31);
 11748     %}
 11749     ins_pipe( pipe_slow );
 11750 %}
 11753 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
 11754   match(Set dst (CmpLTMask p q));
 11755   ins_cost(400);
 11757   format %{ "cmpLTMask    $dst, $p, $q @ cmpLTMask" %}
 11758   ins_encode %{
 11759     Register p   = $p$$Register;
 11760     Register q   = $q$$Register;
 11761     Register dst = $dst$$Register;
 11763     __ slt(dst, p, q);
 11764     __ subu(dst, R0, dst);
 11765     %}
 11766   ins_pipe( pipe_slow );
 11767 %}
 11769 instruct convP2B(mRegI dst, mRegP src) %{
 11770   match(Set dst (Conv2B src));
 11772   ins_cost(100);
 11773   format %{ "convP2B    $dst, $src @ convP2B"  %}
 11774   ins_encode %{
 11775     Register dst = as_Register($dst$$reg);
 11776     Register src = as_Register($src$$reg);
 11778     if (dst != src) {
 11779       __ daddiu(dst, R0, 1);
 11780       __ movz(dst, R0, src);
 11781     } else {
 11782       __ move(AT, src);
 11783       __ daddiu(dst, R0, 1);
 11784       __ movz(dst, R0, AT);
 11786   %}
 11788   ins_pipe( ialu_regL_regL );
 11789 %}
 11792 instruct convI2D_reg_reg(regD dst, mRegI src) %{
 11793   match(Set dst (ConvI2D src));
 11794   format %{ "conI2D $dst, $src @convI2D_reg" %}
 11795   ins_encode %{
 11796     Register      src = $src$$Register;
 11797     FloatRegister dst = $dst$$FloatRegister;
 11798     __ mtc1(src, dst);
 11799     __ cvt_d_w(dst, dst);
 11800     %}
 11801   ins_pipe( fpu_regF_regF );
 11802 %}
 11804 instruct convF2D_reg_reg(regD dst, regF src) %{
 11805   match(Set dst (ConvF2D src));
 11806   format %{ "convF2D  $dst, $src\t# @convF2D_reg_reg" %}
 11807   ins_encode %{
 11808     FloatRegister dst = $dst$$FloatRegister;
 11809     FloatRegister src = $src$$FloatRegister;
 11811     __ cvt_d_s(dst, src);
 11812   %}
 11813   ins_pipe( fpu_regF_regF );
 11814 %}
 11816 instruct convD2F_reg_reg(regF dst, regD src) %{
 11817   match(Set dst (ConvD2F src));
 11818   format %{ "convD2F  $dst, $src\t# @convD2F_reg_reg" %}
 11819   ins_encode %{
 11820     FloatRegister dst = $dst$$FloatRegister;
 11821     FloatRegister src = $src$$FloatRegister;
 11823     __ cvt_s_d(dst, src);
 11824   %}
 11825   ins_pipe( fpu_regF_regF );
 11826 %}
 11829 // Convert a double to an int.  If the double is a NAN, stuff a zero in instead.
 11830 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
 11831   match(Set dst (ConvD2I src));
 11833   ins_cost(150);
 11834   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
 11836   ins_encode %{
 11837     FloatRegister src = $src$$FloatRegister;
 11838     Register      dst = $dst$$Register;
 11840     Label Done;
 11842     __ trunc_w_d(F30, src);
 11843     // max_int: 2147483647
 11844     __ move(AT, 0x7fffffff);
 11845     __ mfc1(dst, F30);
 11847     __ bne(dst, AT, Done);
 11848     __ delayed()->mtc1(R0, F30);
 11850     __ cvt_d_w(F30, F30);
 11851     __ c_ult_d(src, F30);
 11852     __ bc1f(Done);
 11853     __ delayed()->addiu(T9, R0, -1);
 11855     __ c_un_d(src, src);    //NaN?
 11856     __ subu32(dst, T9, AT);
 11857     __ movt(dst, R0);
 11859     __ bind(Done);
 11860   %}
 11861   ins_pipe( pipe_slow );
 11862 %}
 11865 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
 11866   match(Set dst (ConvD2I src));
 11868   ins_cost(250);
 11869   format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
 11871   ins_encode %{
 11872     FloatRegister src = $src$$FloatRegister;
 11873     Register      dst = $dst$$Register;
 11874     Label L;
 11876     __ trunc_w_d(F30, src);
 11877     __ cfc1(AT, 31);
 11878     __ li(T9, 0x10000);
 11879     __ andr(AT, AT, T9);
 11880     __ beq(AT, R0, L);
 11881     __ delayed()->mfc1(dst, F30);
 11883     __ mov_d(F12, src);
 11884     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
 11885     __ move(dst, V0);
 11886     __ bind(L);
 11888   %}
 11889   ins_pipe( pipe_slow );
 11890 %}
 11892 // Convert oop pointer into compressed form
 11893 instruct encodeHeapOop(mRegN dst, mRegP src) %{
 11894   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 11895   match(Set dst (EncodeP src));
 11896   format %{ "encode_heap_oop $dst,$src" %}
 11897   ins_encode %{
 11898     Register src = $src$$Register;
 11899     Register dst = $dst$$Register;
 11901     __ encode_heap_oop(dst, src);
 11902   %}
 11903   ins_pipe( ialu_regL_regL );
 11904 %}
 11906 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
 11907   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
 11908   match(Set dst (EncodeP src));
 11909   format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
 11910   ins_encode %{
 11911     __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
 11912   %}
 11913   ins_pipe( ialu_regL_regL );
 11914 %}
 11916 instruct decodeHeapOop(mRegP dst, mRegN src) %{
 11917   predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
 11918             n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
 11919   match(Set dst (DecodeN src));
 11920   format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
 11921   ins_encode %{
 11922     Register s = $src$$Register;
 11923     Register d = $dst$$Register;
 11925     __ decode_heap_oop(d, s);
 11926   %}
 11927   ins_pipe( ialu_regL_regL );
 11928 %}
 11930 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
 11931   predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
 11932             n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
 11933   match(Set dst (DecodeN src));
 11934   format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
 11935   ins_encode %{
 11936     Register s = $src$$Register;
 11937     Register d = $dst$$Register;
 11938     if (s != d) {
 11939       __ decode_heap_oop_not_null(d, s);
 11940     } else {
 11941       __ decode_heap_oop_not_null(d);
 11943   %}
 11944   ins_pipe( ialu_regL_regL );
 11945 %}
 11947 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
 11948   match(Set dst (EncodePKlass src));
 11949   format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
 11950   ins_encode %{
 11951     __ encode_klass_not_null($dst$$Register, $src$$Register);
 11952   %}
 11953   ins_pipe( ialu_regL_regL );
 11954 %}
 11956 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
 11957   match(Set dst (DecodeNKlass src));
 11958   format %{ "decode_heap_klass_not_null $dst,$src" %}
 11959   ins_encode %{
 11960     Register s = $src$$Register;
 11961     Register d = $dst$$Register;
 11962     if (s != d) {
 11963       __ decode_klass_not_null(d, s);
 11964     } else {
 11965       __ decode_klass_not_null(d);
 11967   %}
 11968   ins_pipe( ialu_regL_regL );
 11969 %}
 11971 //FIXME
 11972 instruct tlsLoadP(mRegP dst) %{
 11973   match(Set dst (ThreadLocal));
 11975   ins_cost(0);
 11976   format %{ " get_thread in $dst #@tlsLoadP" %}
 11977   ins_encode %{
 11978     Register dst = $dst$$Register;
 11979 #ifdef OPT_THREAD
 11980     __ move(dst, TREG);
 11981 #else
 11982     __ get_thread(dst);
 11983 #endif
 11984   %}
 11986   ins_pipe( ialu_loadI );
 11987 %}
 11990 instruct checkCastPP( mRegP dst ) %{
 11991   match(Set dst (CheckCastPP dst));
 11993   format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
 11994   ins_encode( /*empty encoding*/ );
 11995   ins_pipe( empty );
 11996 %}
 11998 instruct castPP(mRegP dst)
 11999 %{
 12000   match(Set dst (CastPP dst));
 12002   size(0);
 12003   format %{ "# castPP of $dst" %}
 12004   ins_encode(/* empty encoding */);
 12005   ins_pipe(empty);
 12006 %}
 12008 instruct castII( mRegI dst ) %{
 12009   match(Set dst (CastII dst));
 12010   format %{ "#castII of $dst  empty encoding" %}
 12011   ins_encode( /*empty encoding*/ );
 12012   ins_cost(0);
 12013   ins_pipe( empty );
 12014 %}
 12016 // Return Instruction
 12017 // Remove the return address & jump to it.
 12018 instruct Ret() %{
 12019   match(Return);
 12020   format %{ "RET #@Ret" %}
 12022   ins_encode %{
 12023    __ jr(RA);
 12024    __ nop();
 12025   %}
 12027   ins_pipe( pipe_jump );
 12028 %}
 12030 /*
 12031 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
 12032 instruct jumpXtnd(mRegL switch_val) %{
 12033   match(Jump switch_val);
 12035   ins_cost(350);
 12037   format %{  "load   T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
 12038              "jr     T9\n\t"
 12039              "nop" %}
 12040   ins_encode %{
 12041     Register table_base = $constanttablebase;
 12042     int      con_offset = $constantoffset;
 12043     Register switch_reg = $switch_val$$Register;
 12045     if (UseLoongsonISA) {
 12046        if (Assembler::is_simm(con_offset, 8)) {
 12047          __ gsldx(T9, table_base, switch_reg, con_offset);
 12048        } else if (Assembler::is_simm16(con_offset)) {
 12049          __ daddu(T9, table_base, switch_reg);
 12050          __ ld(T9, T9, con_offset);
 12051        } else {
 12052          __ move(T9, con_offset);
 12053          __ daddu(AT, table_base, switch_reg);
 12054          __ gsldx(T9, AT, T9, 0);
 12056     } else {
 12057        if (Assembler::is_simm16(con_offset)) {
 12058          __ daddu(T9, table_base, switch_reg);
 12059          __ ld(T9, T9, con_offset);
 12060        } else {
 12061          __ move(T9, con_offset);
 12062          __ daddu(AT, table_base, switch_reg);
 12063          __ daddu(AT, T9, AT);
 12064          __ ld(T9, AT, 0);
 12068     __ jr(T9);
 12069     __ nop();
 12071   %}
 12072   ins_pipe(pipe_jump);
 12073 %}
 12074 */
 12076 // Jump Direct - Label defines a relative address from JMP
 12077 instruct jmpDir(label labl) %{
 12078   match(Goto);
 12079   effect(USE labl);
 12081   ins_cost(300);
 12082   format %{ "JMP    $labl #@jmpDir" %}
 12084   ins_encode %{
 12085     Label &L = *($labl$$label);
 12086     if(&L)
 12087        __ b(L);
 12088     else
 12089          __ b(int(0));
 12090     __ nop();
 12091   %}
 12093     ins_pipe( pipe_jump );
 12094     ins_pc_relative(1);
 12095 %}
 12099 // Tail Jump; remove the return address; jump to target.
 12100 // TailCall above leaves the return address around.
 12101 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
 12102 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
 12103 // "restore" before this instruction (in Epilogue), we need to materialize it
 12104 // in %i0.
 12105 //FIXME
 12106 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
 12107   match( TailJump jump_target ex_oop );
 12108   ins_cost(200);
 12109   format %{ "Jmp     $jump_target  ; ex_oop = $ex_oop #@tailjmpInd" %}
 12110   ins_encode %{
 12111     Register target = $jump_target$$Register;
 12113     /* 2012/9/14 Jin: V0, V1 are indicated in:
 12114      *      [stubGenerator_mips.cpp] generate_forward_exception()
 12115      *      [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
 12116      */
 12117     Register oop  = $ex_oop$$Register;
 12118     Register exception_oop = V0;
 12119     Register exception_pc = V1;
 12121     __ move(exception_pc, RA);
 12122     __ move(exception_oop, oop);
 12124     __ jr(target);
 12125     __ nop();
 12126   %}
 12127   ins_pipe( pipe_jump );
 12128 %}
 12130 // ============================================================================
 12131 // Procedure Call/Return Instructions
 12132 // Call Java Static Instruction
 12133 // Note: If this code changes, the corresponding ret_addr_offset() and
 12134 //       compute_padding() functions will have to be adjusted.
 12135 instruct CallStaticJavaDirect(method meth) %{
 12136   match(CallStaticJava);
 12137   effect(USE meth);
 12139   ins_cost(300);
 12140   format %{ "CALL,static #@CallStaticJavaDirect " %}
 12141   ins_encode( Java_Static_Call( meth ) );
 12142   ins_pipe( pipe_slow );
 12143   ins_pc_relative(1);
 12144 %}
 12146 // Call Java Dynamic Instruction
 12147 // Note: If this code changes, the corresponding ret_addr_offset() and
 12148 //       compute_padding() functions will have to be adjusted.
 12149 instruct CallDynamicJavaDirect(method meth) %{
 12150   match(CallDynamicJava);
 12151   effect(USE meth);
 12153   ins_cost(300);
 12154   format %{"MOV IC_Klass, (oop)-1\n\t"
 12155            "CallDynamic @ CallDynamicJavaDirect" %}
 12156   ins_encode( Java_Dynamic_Call( meth ) );
 12157   ins_pipe( pipe_slow );
 12158   ins_pc_relative(1);
 12159 %}
 12161 instruct CallLeafNoFPDirect(method meth) %{
 12162   match(CallLeafNoFP);
 12163   effect(USE meth);
 12165   ins_cost(300);
 12166   format %{ "CALL_LEAF_NOFP,runtime " %}
 12167   ins_encode(Java_To_Runtime(meth));
 12168   ins_pipe( pipe_slow );
 12169   ins_pc_relative(1);
 12170   ins_alignment(16);
 12171 %}
 12173 // Prefetch instructions.
 12175 instruct prefetchrNTA( memory mem ) %{
 12176   match(PrefetchRead mem);
 12177   ins_cost(125);
 12179   format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
 12180   ins_encode %{
 12181     int  base = $mem$$base;
 12182     int  index = $mem$$index;
 12183     int  scale = $mem$$scale;
 12184     int  disp = $mem$$disp;
 12186     if( index != 0 ) {
 12187       if (scale == 0) {
 12188         __ daddu(AT, as_Register(base), as_Register(index));
 12189       } else {
 12190         __ dsll(AT, as_Register(index), scale);
 12191         __ daddu(AT, as_Register(base), AT);
 12193     } else {
 12194       __ move(AT, as_Register(base));
 12196     if( Assembler::is_simm16(disp) ) {
 12197       __ daddiu(AT, as_Register(base), disp);
 12198       __ daddiu(AT, AT, disp);
 12199     } else {
 12200       __ move(T9, disp);
 12201       __ daddu(AT, as_Register(base), T9);
 12203     __ pref(0, AT, 0); //hint: 0:load
 12204   %}
 12205   ins_pipe(pipe_slow);
 12206 %}
 12208 instruct prefetchwNTA( memory mem ) %{
 12209   match(PrefetchWrite mem);
 12210   ins_cost(125);
 12211   format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
 12212   ins_encode %{
 12213     int  base = $mem$$base;
 12214     int  index = $mem$$index;
 12215     int  scale = $mem$$scale;
 12216     int  disp = $mem$$disp;
 12218     if( index != 0 ) {
 12219       if (scale == 0) {
 12220         __ daddu(AT, as_Register(base), as_Register(index));
 12221       } else {
 12222         __ dsll(AT, as_Register(index), scale);
 12223         __ daddu(AT, as_Register(base), AT);
 12225     } else {
 12226       __ move(AT, as_Register(base));
 12228     if( Assembler::is_simm16(disp) ) {
 12229       __ daddiu(AT, as_Register(base), disp);
 12230       __ daddiu(AT, AT, disp);
 12231     } else {
 12232       __ move(T9, disp);
 12233       __ daddu(AT, as_Register(base), T9);
 12235      __ pref(1, AT, 0); //hint: 1:store
 12236   %}
 12237   ins_pipe(pipe_slow);
 12238 %}
 12240 // Prefetch instructions for allocation.
 12242 instruct prefetchAllocNTA( memory mem ) %{
 12243   match(PrefetchAllocation mem);
 12244   ins_cost(125);
 12245   format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
 12246   ins_encode %{
 12247     int  base = $mem$$base;
 12248     int  index = $mem$$index;
 12249     int  scale = $mem$$scale;
 12250     int  disp = $mem$$disp;
 12252     Register dst = R0;
 12254     if( index != 0 ) {
 12255       if( Assembler::is_simm16(disp) ) {
 12256         if( UseLoongsonISA ) {
 12257           if (scale == 0) {
 12258             __ gslbx(dst, as_Register(base), as_Register(index), disp);
 12259           } else {
 12260             __ dsll(AT, as_Register(index), scale);
 12261             __ gslbx(dst, as_Register(base), AT, disp);
 12263         } else {
 12264           if (scale == 0) {
 12265             __ addu(AT, as_Register(base), as_Register(index));
 12266           } else {
 12267             __ dsll(AT, as_Register(index), scale);
 12268             __ addu(AT, as_Register(base), AT);
 12270           __ lb(dst, AT, disp);
 12272       } else {
 12273         if (scale == 0) {
 12274           __ addu(AT, as_Register(base), as_Register(index));
 12275         } else {
 12276           __ dsll(AT, as_Register(index), scale);
 12277           __ addu(AT, as_Register(base), AT);
 12279         __ move(T9, disp);
 12280         if( UseLoongsonISA ) {
 12281           __ gslbx(dst, AT, T9, 0);
 12282         } else {
 12283           __ addu(AT, AT, T9);
 12284           __ lb(dst, AT, 0);
 12287     } else {
 12288       if( Assembler::is_simm16(disp) ) {
 12289         __ lb(dst, as_Register(base), disp);
 12290       } else {
 12291         __ move(T9, disp);
 12292         if( UseLoongsonISA ) {
 12293           __ gslbx(dst, as_Register(base), T9, 0);
 12294         } else {
 12295           __ addu(AT, as_Register(base), T9);
 12296           __ lb(dst, AT, 0);
 12300   %}
 12301   ins_pipe(pipe_slow);
 12302 %}
 12305 // Call runtime without safepoint
 12306 instruct CallLeafDirect(method meth) %{
 12307   match(CallLeaf);
 12308   effect(USE meth);
 12310   ins_cost(300);
 12311   format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
 12312   ins_encode(Java_To_Runtime(meth));
 12313   ins_pipe( pipe_slow );
 12314   ins_pc_relative(1);
 12315   ins_alignment(16);
 12316 %}
 12318 // Load Char (16bit unsigned)
 12319 instruct loadUS(mRegI dst, memory mem) %{
 12320   match(Set dst (LoadUS mem));
 12322   ins_cost(125);
 12323   format %{ "loadUS  $dst,$mem @ loadC" %}
 12324   ins_encode(load_C_enc(dst, mem));
 12325   ins_pipe( ialu_loadI );
 12326 %}
 12328 instruct loadUS_convI2L(mRegL dst, memory mem) %{
 12329   match(Set dst (ConvI2L (LoadUS mem)));
 12331   ins_cost(125);
 12332   format %{ "loadUS  $dst,$mem @ loadUS_convI2L" %}
 12333   ins_encode(load_C_enc(dst, mem));
 12334   ins_pipe( ialu_loadI );
 12335 %}
 12337 // Store Char (16bit unsigned)
 12338 instruct storeC(memory mem, mRegI src) %{
 12339   match(Set mem (StoreC mem src));
 12341   ins_cost(125);
 12342   format %{ "storeC  $src, $mem @ storeC" %}
 12343   ins_encode(store_C_reg_enc(mem, src));
 12344   ins_pipe( ialu_loadI );
 12345 %}
 12347 instruct storeC0(memory mem, immI0 zero) %{
 12348   match(Set mem (StoreC mem zero));
 12350   ins_cost(125);
 12351   format %{ "storeC  $zero, $mem @ storeC0" %}
 12352   ins_encode(store_C0_enc(mem));
 12353   ins_pipe( ialu_loadI );
 12354 %}
 12357 instruct loadConF0(regF dst, immF0 zero) %{
 12358   match(Set dst zero);
 12359   ins_cost(100);
 12361   format %{ "mov  $dst, zero @ loadConF0\n"%}
 12362   ins_encode %{
 12363     FloatRegister dst = $dst$$FloatRegister;
 12365     __ mtc1(R0, dst);
 12366   %}
 12367   ins_pipe( fpu_loadF );
 12368 %}
 12371 instruct loadConF(regF dst, immF src) %{
 12372   match(Set dst src);
 12373   ins_cost(125);
 12375   format %{ "lwc1  $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
 12376   ins_encode %{
 12377     int con_offset = $constantoffset($src);
 12379     if (Assembler::is_simm16(con_offset)) {
 12380       __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
 12381     } else {
 12382       __ set64(AT, con_offset);
 12383       if (UseLoongsonISA) {
 12384         __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 12385       } else {
 12386         __ daddu(AT, $constanttablebase, AT);
 12387         __ lwc1($dst$$FloatRegister, AT, 0);
 12390   %}
 12391   ins_pipe( fpu_loadF );
 12392 %}
 12395 instruct loadConD0(regD dst, immD0 zero) %{
 12396   match(Set dst zero);
 12397   ins_cost(100);
 12399   format %{ "mov  $dst, zero @ loadConD0"%}
 12400   ins_encode %{
 12401     FloatRegister dst = as_FloatRegister($dst$$reg);
 12403     __ dmtc1(R0, dst);
 12404   %}
 12405   ins_pipe( fpu_loadF );
 12406 %}
 12408 instruct loadConD(regD dst, immD src) %{
 12409   match(Set dst src);
 12410   ins_cost(125);
 12412   format %{ "ldc1  $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
 12413   ins_encode %{
 12414     int con_offset = $constantoffset($src);
 12416     if (Assembler::is_simm16(con_offset)) {
 12417       __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
 12418     } else {
 12419       __ set64(AT, con_offset);
 12420       if (UseLoongsonISA) {
 12421         __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
 12422       } else {
 12423         __ daddu(AT, $constanttablebase, AT);
 12424         __ ldc1($dst$$FloatRegister, AT, 0);
 12427   %}
 12428   ins_pipe( fpu_loadF );
 12429 %}
 12431 // Store register Float value (it is faster than store from FPU register)
 12432 instruct storeF_reg( memory mem, regF src) %{
 12433   match(Set mem (StoreF mem src));
 12435   ins_cost(50);
 12436   format %{ "store   $mem, $src\t# store float @ storeF_reg" %}
 12437   ins_encode(store_F_reg_enc(mem, src));
 12438   ins_pipe( fpu_storeF );
 12439 %}
 12441 instruct storeF_imm0( memory mem, immF0 zero) %{
 12442   match(Set mem (StoreF mem zero));
 12444   ins_cost(40);
 12445   format %{ "store   $mem, zero\t# store float @ storeF_imm0" %}
 12446   ins_encode %{
 12447     int      base = $mem$$base;
 12448     int     index = $mem$$index;
 12449     int     scale = $mem$$scale;
 12450     int      disp = $mem$$disp;
 12452     if( index != 0 ) {
 12453       if ( UseLoongsonISA ) {
 12454         if ( Assembler::is_simm(disp, 8) ) {
 12455           if ( scale == 0 ) {
 12456             __ gsswx(R0, as_Register(base), as_Register(index), disp);
 12457           } else {
 12458             __ dsll(T9, as_Register(index), scale);
 12459             __ gsswx(R0, as_Register(base), T9, disp);
 12461         } else if ( Assembler::is_simm16(disp) ) {
 12462           if ( scale == 0 ) {
 12463             __ daddu(AT, as_Register(base), as_Register(index));
 12464           } else {
 12465             __ dsll(T9, as_Register(index), scale);
 12466             __ daddu(AT, as_Register(base), T9);
 12468           __ sw(R0, AT, disp);
 12469         } else {
 12470           if ( scale == 0 ) {
 12471             __ move(T9, disp);
 12472             __ daddu(AT, as_Register(index), T9);
 12473             __ gsswx(R0, as_Register(base), AT, 0);
 12474           } else {
 12475             __ dsll(T9, as_Register(index), scale);
 12476             __ move(AT, disp);
 12477             __ daddu(AT, AT, T9);
 12478             __ gsswx(R0, as_Register(base), AT, 0);
 12481       } else { //not use loongson isa
 12482         if(scale != 0) {
 12483           __ dsll(T9, as_Register(index), scale);
 12484           __ daddu(AT, as_Register(base), T9);
 12485         } else {
 12486           __ daddu(AT, as_Register(base), as_Register(index));
 12488         if( Assembler::is_simm16(disp) ) {
 12489           __ sw(R0, AT, disp);
 12490         } else {
 12491           __ move(T9, disp);
 12492           __ daddu(AT, AT, T9);
 12493           __ sw(R0, AT, 0);
 12496     } else { //index is 0
 12497       if ( UseLoongsonISA ) {
 12498         if ( Assembler::is_simm16(disp) ) {
 12499           __ sw(R0, as_Register(base), disp);
 12500         } else {
 12501           __ move(T9, disp);
 12502           __ gsswx(R0, as_Register(base), T9, 0);
 12504       } else {
 12505         if( Assembler::is_simm16(disp) ) {
 12506           __ sw(R0, as_Register(base), disp);
 12507         } else {
 12508           __ move(T9, disp);
 12509           __ daddu(AT, as_Register(base), T9);
 12510           __ sw(R0, AT, 0);
 12514   %}
 12515   ins_pipe( ialu_storeI );
 12516 %}
 12518 // Load Double
 12519 instruct loadD(regD dst, memory mem) %{
 12520   match(Set dst (LoadD mem));
 12522   ins_cost(150);
 12523   format %{ "loadD   $dst, $mem #@loadD" %}
 12524   ins_encode(load_D_enc(dst, mem));
 12525   ins_pipe( ialu_loadI );
 12526 %}
 12528 // Load Double - UNaligned
 12529 instruct loadD_unaligned(regD dst, memory mem ) %{
 12530   match(Set dst (LoadD_unaligned mem));
 12531   ins_cost(250);
 12532   // FIXME: Jin: Need more effective ldl/ldr
 12533   format %{ "loadD_unaligned   $dst, $mem #@loadD_unaligned" %}
 12534   ins_encode(load_D_enc(dst, mem));
 12535   ins_pipe( ialu_loadI );
 12536 %}
 12538 instruct storeD_reg( memory mem, regD src) %{
 12539   match(Set mem (StoreD mem src));
 12541   ins_cost(50);
 12542   format %{ "store   $mem, $src\t# store float @ storeD_reg" %}
 12543   ins_encode(store_D_reg_enc(mem, src));
 12544   ins_pipe( fpu_storeF );
 12545 %}
 12547 instruct storeD_imm0( memory mem, immD0 zero) %{
 12548   match(Set mem (StoreD mem zero));
 12550   ins_cost(40);
 12551   format %{ "store   $mem, zero\t# store float @ storeD_imm0" %}
 12552   ins_encode %{
 12553     int      base = $mem$$base;
 12554     int     index = $mem$$index;
 12555     int     scale = $mem$$scale;
 12556     int      disp = $mem$$disp;
 12558     __ mtc1(R0, F30);
 12559     __ cvt_d_w(F30, F30);
 12561     if( index != 0 ) {
 12562     if ( UseLoongsonISA ) {
 12563       if ( Assembler::is_simm(disp, 8) ) {
 12564         if (scale == 0) {
 12565           __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
 12566         } else {
 12567           __ dsll(T9, as_Register(index), scale);
 12568           __ gssdxc1(F30, as_Register(base), T9, disp);
 12570       } else if ( Assembler::is_simm16(disp) ) {
 12571         if (scale == 0) {
 12572           __ daddu(AT, as_Register(base), as_Register(index));
 12573           __ sdc1(F30, AT, disp);
 12574         } else {
 12575           __ dsll(T9, as_Register(index), scale);
 12576           __ daddu(AT, as_Register(base), T9);
 12577           __ sdc1(F30, AT, disp);
 12579       } else {
 12580         if (scale == 0) {
 12581           __ move(T9, disp);
 12582           __ daddu(AT, as_Register(index), T9);
 12583           __ gssdxc1(F30, as_Register(base), AT, 0);
 12584         } else {
 12585           __ move(T9, disp);
 12586           __ dsll(AT, as_Register(index), scale);
 12587           __ daddu(AT, AT, T9);
 12588           __ gssdxc1(F30, as_Register(base), AT, 0);
 12591     } else { // not use loongson isa
 12592         if(scale != 0) {
 12593            __ dsll(T9, as_Register(index), scale);
 12594            __ daddu(AT, as_Register(base), T9);
 12595         } else {
 12596            __ daddu(AT, as_Register(base), as_Register(index));
 12598        if( Assembler::is_simm16(disp) ) {
 12599           __ sdc1(F30, AT, disp);
 12600        } else {
 12601           __ move(T9, disp);
 12602           __ daddu(AT, AT, T9);
 12603           __ sdc1(F30, AT, 0);
 12606     } else {// index is 0
 12607     if ( UseLoongsonISA ) {
 12608       if ( Assembler::is_simm16(disp) ) {
 12609         __ sdc1(F30, as_Register(base), disp);
 12610       } else {
 12611         __ move(T9, disp);
 12612         __ gssdxc1(F30, as_Register(base), T9, 0);
 12614     } else {
 12615        if( Assembler::is_simm16(disp) ) {
 12616           __ sdc1(F30, as_Register(base), disp);
 12617        } else {
 12618           __ move(T9, disp);
 12619           __ daddu(AT, as_Register(base), T9);
 12620           __ sdc1(F30, AT, 0);
 12624   %}
 12625   ins_pipe( ialu_storeI );
 12626 %}
 12628 instruct loadSSI(mRegI dst, stackSlotI src)
 12629 %{
 12630   match(Set dst src);
 12632   ins_cost(125);
 12633   format %{ "lw    $dst, $src\t# int stk @ loadSSI" %}
 12634   ins_encode %{
 12635     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
 12636     __ lw($dst$$Register, SP, $src$$disp);
 12637   %}
 12638   ins_pipe(ialu_loadI);
 12639 %}
 12641 instruct storeSSI(stackSlotI dst, mRegI src)
 12642 %{
 12643   match(Set dst src);
 12645   ins_cost(100);
 12646   format %{ "sw    $dst, $src\t# int stk @ storeSSI" %}
 12647   ins_encode %{
 12648     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
 12649     __ sw($src$$Register, SP, $dst$$disp);
 12650   %}
 12651   ins_pipe(ialu_storeI);
 12652 %}
 12654 instruct loadSSL(mRegL dst, stackSlotL src)
 12655 %{
 12656   match(Set dst src);
 12658   ins_cost(125);
 12659   format %{ "ld    $dst, $src\t# long stk @ loadSSL" %}
 12660   ins_encode %{
 12661     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
 12662     __ ld($dst$$Register, SP, $src$$disp);
 12663   %}
 12664   ins_pipe(ialu_loadI);
 12665 %}
 12667 instruct storeSSL(stackSlotL dst, mRegL src)
 12668 %{
 12669   match(Set dst src);
 12671   ins_cost(100);
 12672   format %{ "sd    $dst, $src\t# long stk @ storeSSL" %}
 12673   ins_encode %{
 12674     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
 12675     __ sd($src$$Register, SP, $dst$$disp);
 12676   %}
 12677   ins_pipe(ialu_storeI);
 12678 %}
 12680 instruct loadSSP(mRegP dst, stackSlotP src)
 12681 %{
 12682   match(Set dst src);
 12684   ins_cost(125);
 12685   format %{ "ld    $dst, $src\t# ptr stk @ loadSSP" %}
 12686   ins_encode %{
 12687     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
 12688     __ ld($dst$$Register, SP, $src$$disp);
 12689   %}
 12690   ins_pipe(ialu_loadI);
 12691 %}
 12693 instruct storeSSP(stackSlotP dst, mRegP src)
 12694 %{
 12695   match(Set dst src);
 12697   ins_cost(100);
 12698   format %{ "sd    $dst, $src\t# ptr stk @ storeSSP" %}
 12699   ins_encode %{
 12700     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
 12701     __ sd($src$$Register, SP, $dst$$disp);
 12702   %}
 12703   ins_pipe(ialu_storeI);
 12704 %}
 12706 instruct loadSSF(regF dst, stackSlotF src)
 12707 %{
 12708   match(Set dst src);
 12710   ins_cost(125);
 12711   format %{ "lwc1   $dst, $src\t# float stk @ loadSSF" %}
 12712   ins_encode %{
 12713     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
 12714     __ lwc1($dst$$FloatRegister, SP, $src$$disp);
 12715   %}
 12716   ins_pipe(ialu_loadI);
 12717 %}
 12719 instruct storeSSF(stackSlotF dst, regF src)
 12720 %{
 12721   match(Set dst src);
 12723   ins_cost(100);
 12724   format %{ "swc1    $dst, $src\t# float stk @ storeSSF" %}
 12725   ins_encode %{
 12726     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
 12727     __ swc1($src$$FloatRegister, SP, $dst$$disp);
 12728   %}
 12729   ins_pipe(fpu_storeF);
 12730 %}
 12732 // Use the same format since predicate() can not be used here.
 12733 instruct loadSSD(regD dst, stackSlotD src)
 12734 %{
 12735   match(Set dst src);
 12737   ins_cost(125);
 12738   format %{ "ldc1   $dst, $src\t# double stk @ loadSSD" %}
 12739   ins_encode %{
 12740     guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
 12741     __ ldc1($dst$$FloatRegister, SP, $src$$disp);
 12742   %}
 12743   ins_pipe(ialu_loadI);
 12744 %}
 12746 instruct storeSSD(stackSlotD dst, regD src)
 12747 %{
 12748   match(Set dst src);
 12750   ins_cost(100);
 12751   format %{ "sdc1    $dst, $src\t# double stk @ storeSSD" %}
 12752   ins_encode %{
 12753     guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
 12754     __ sdc1($src$$FloatRegister, SP, $dst$$disp);
 12755   %}
 12756   ins_pipe(fpu_storeF);
 12757 %}
 12759 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
 12760   match( Set cr (FastLock object box) );
 12761   effect( TEMP tmp, TEMP scr, USE_KILL box );
 12762   ins_cost(300);
 12763   format %{ "FASTLOCK $cr $object, $box, $tmp #@ cmpFastLock" %}
 12764   ins_encode %{
 12765     __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
 12766   %}
 12768   ins_pipe( pipe_slow );
 12769   ins_pc_relative(1);
 12770 %}
 12772 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
 12773   match( Set cr (FastUnlock object box) );
 12774   effect( TEMP tmp, USE_KILL box );
 12775   ins_cost(300);
 12776   format %{ "FASTUNLOCK $object, $box, $tmp #@cmpFastUnlock" %}
 12777   ins_encode %{
 12778     __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
 12779   %}
 12781   ins_pipe( pipe_slow );
 12782   ins_pc_relative(1);
 12783 %}
 12785 // Store CMS card-mark Immediate
 12786 instruct storeImmCM(memory mem, immI8 src) %{
 12787   match(Set mem (StoreCM mem src));
 12789   ins_cost(150);
 12790   format %{ "MOV8   $mem,$src\t! CMS card-mark imm0" %}
 12791 //  opcode(0xC6);
 12792   ins_encode(store_B_immI_enc_sync(mem, src));
 12793   ins_pipe( ialu_storeI );
 12794 %}
 12796 // Die now
 12797 instruct ShouldNotReachHere( )
 12798 %{
 12799   match(Halt);
 12800   ins_cost(300);
 12802   // Use the following format syntax
 12803   format %{ "ILLTRAP   ;#@ShouldNotReachHere" %}
 12804   ins_encode %{
 12805     // Here we should emit illtrap !
 12807     __ stop("in ShoudNotReachHere");
 12809   %}
 12810   ins_pipe( pipe_jump );
 12811 %}
 12813 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
 12814 %{
 12815   predicate(Universe::narrow_oop_shift() == 0);
 12816   match(Set dst mem);
 12818   ins_cost(110);
 12819   format %{ "leaq    $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
 12820   ins_encode %{
 12821     Register  dst  = $dst$$Register;
 12822     Register  base = as_Register($mem$$base);
 12823     int       disp = $mem$$disp;
 12825     __ daddiu(dst, base, disp);
 12826   %}
 12827   ins_pipe( ialu_regI_imm16 );
 12828 %}
 12830 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
 12831 %{
 12832   match(Set dst mem);
 12834   ins_cost(110);
 12835   format %{ "leaq    $dst, $mem\t# @ PosIdxScaleOff8" %}
 12836   ins_encode %{
 12837     Register  dst   = $dst$$Register;
 12838     Register  base  = as_Register($mem$$base);
 12839     Register  index = as_Register($mem$$index);
 12840     int       scale = $mem$$scale;
 12841     int       disp  = $mem$$disp;
 12843     if (scale == 0) {
 12844       __ daddu(AT, base, index);
 12845       __ daddiu(dst, AT, disp);
 12846     } else {
 12847       __ dsll(AT, index, scale);
 12848       __ daddu(AT, base, AT);
 12849       __ daddiu(dst, AT, disp);
 12851  %}
 12853   ins_pipe( ialu_regI_imm16 );
 12854 %}
 12856 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
 12857 %{
 12858   match(Set dst mem);
 12860   ins_cost(110);
 12861   format %{ "leaq    $dst, $mem\t# @ leaPIdxScale" %}
 12862   ins_encode %{
 12863     Register  dst   = $dst$$Register;
 12864     Register  base  = as_Register($mem$$base);
 12865     Register  index = as_Register($mem$$index);
 12866     int       scale = $mem$$scale;
 12868     if (scale == 0) {
 12869        __ daddu(dst, base, index);
 12870     } else {
 12871        __ dsll(AT, index, scale);
 12872        __ daddu(dst, base, AT);
 12874  %}
 12876   ins_pipe( ialu_regI_imm16 );
 12877 %}
 12879 // Jump Direct Conditional - Label defines a relative address from Jcc+1
 12880 instruct  jmpLoopEnd(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
 12881   match(CountedLoopEnd cop (CmpI src1 src2));
 12882   effect(USE labl);
 12884   ins_cost(300);
 12885   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd" %}
 12886   ins_encode %{
 12887     Register op1 = $src1$$Register;
 12888     Register op2 = $src2$$Register;
 12889     Label     &L = *($labl$$label);
 12890     int     flag = $cop$$cmpcode;
 12892     switch(flag) {
 12893       case 0x01: //equal
 12894         if (&L)
 12895           __ beq(op1, op2, L);
 12896         else
 12897           __ beq(op1, op2, (int)0);
 12898         break;
 12899       case 0x02: //not_equal
 12900         if (&L)
 12901           __ bne(op1, op2, L);
 12902         else
 12903           __ bne(op1, op2, (int)0);
 12904         break;
 12905       case 0x03: //above
 12906         __ slt(AT, op2, op1);
 12907         if(&L)
 12908           __ bne(AT, R0, L);
 12909         else
 12910           __ bne(AT, R0, (int)0);
 12911         break;
 12912       case 0x04: //above_equal
 12913         __ slt(AT, op1, op2);
 12914         if(&L)
 12915           __ beq(AT, R0, L);
 12916         else
 12917           __ beq(AT, R0, (int)0);
 12918         break;
 12919       case 0x05: //below
 12920         __ slt(AT, op1, op2);
 12921         if(&L)
 12922           __ bne(AT, R0, L);
 12923         else
 12924           __ bne(AT, R0, (int)0);
 12925         break;
 12926       case 0x06: //below_equal
 12927         __ slt(AT, op2, op1);
 12928         if(&L)
 12929           __ beq(AT, R0, L);
 12930         else
 12931           __ beq(AT, R0, (int)0);
 12932         break;
 12933       default:
 12934         Unimplemented();
 12936     __ nop();
 12937   %}
 12938   ins_pipe( pipe_jump );
 12939   ins_pc_relative(1);
 12940 %}
 12942 instruct  jmpLoopEnd_reg_immI(cmpOp cop, mRegI src1, immI src2, label labl) %{
 12943   match(CountedLoopEnd cop (CmpI src1 src2));
 12944   effect(USE labl);
 12946   ins_cost(300);
 12947   format %{ "J$cop  $src1, $src2,  $labl\t# Loop end @ jmpLoopEnd_reg_immI" %}
 12948   ins_encode %{
 12949     Register op1 = $src1$$Register;
 12950     Register op2 = AT;
 12951     Label     &L = *($labl$$label);
 12952     int     flag = $cop$$cmpcode;
 12954     __ move(op2, $src2$$constant);
 12956     switch(flag) {
 12957       case 0x01: //equal
 12958         if (&L)
 12959           __ beq(op1, op2, L);
 12960         else
 12961           __ beq(op1, op2, (int)0);
 12962         break;
 12963       case 0x02: //not_equal
 12964         if (&L)
 12965           __ bne(op1, op2, L);
 12966         else
 12967           __ bne(op1, op2, (int)0);
 12968         break;
 12969       case 0x03: //above
 12970         __ slt(AT, op2, op1);
 12971         if(&L)
 12972           __ bne(AT, R0, L);
 12973         else
 12974           __ bne(AT, R0, (int)0);
 12975         break;
 12976       case 0x04: //above_equal
 12977         __ slt(AT, op1, op2);
 12978         if(&L)
 12979           __ beq(AT, R0, L);
 12980         else
 12981           __ beq(AT, R0, (int)0);
 12982         break;
 12983       case 0x05: //below
 12984         __ slt(AT, op1, op2);
 12985         if(&L)
 12986           __ bne(AT, R0, L);
 12987         else
 12988           __ bne(AT, R0, (int)0);
 12989         break;
 12990       case 0x06: //below_equal
 12991         __ slt(AT, op2, op1);
 12992         if(&L)
 12993           __ beq(AT, R0, L);
 12994         else
 12995           __ beq(AT, R0, (int)0);
 12996         break;
 12997       default:
 12998         Unimplemented();
 13000     __ nop();
 13001   %}
 13002   ins_pipe( pipe_jump );
 13003   ins_pc_relative(1);
 13004 %}
 13007 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
 13008 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{
 13009   match(If cop cr);
 13010   effect(USE labl);
 13012   ins_cost(300);
 13013   format %{ "J$cop    $labl  #mips uses AT as eflag @jmpCon_flags" %}
 13015   ins_encode %{
 13016     Label    &L =  *($labl$$label);
 13017     switch($cop$$cmpcode) {
 13018       case 0x01: //equal
 13019         if (&L)
 13020           __ bne(AT, R0, L);
 13021         else
 13022           __ bne(AT, R0, (int)0);
 13023         break;
 13024       case 0x02: //not equal
 13025         if (&L)
 13026           __ beq(AT, R0, L);
 13027         else
 13028           __ beq(AT, R0, (int)0);
 13029         break;
 13030       default:
 13031         Unimplemented();
 13033     __ nop();
 13034   %}
 13036   ins_pipe( pipe_jump );
 13037   ins_pc_relative(1);
 13038 %}
 13041 // ============================================================================
 13042 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary superklass
 13043 // array for an instance of the superklass.  Set a hidden internal cache on a
 13044 // hit (cache is checked with exposed code in gen_subtype_check()).  Return
 13045 // NZ for a miss or zero for a hit.  The encoding ALSO sets flags.
 13046 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
 13047   match(Set result (PartialSubtypeCheck sub super));
 13048   effect(KILL tmp);
 13049   ins_cost(1100);  // slightly larger than the next version
 13050   format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
 13052   ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
 13053   ins_pipe( pipe_slow );
 13054 %}
 13057 // Conditional-store of an int value.
 13058 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
 13059 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
 13060   match(Set cr (StoreIConditional mem (Binary oldval newval)));
 13061 //  effect(KILL oldval);
 13062   format %{ "CMPXCHG  $newval, $mem, $oldval \t# @storeIConditional" %}
 13064   ins_encode %{
 13065     Register oldval = $oldval$$Register;
 13066     Register newval = $newval$$Register;
 13067     Address  addr(as_Register($mem$$base), $mem$$disp);
 13068     Label    again, failure;
 13070     int     index = $mem$$index;
 13071     int     scale = $mem$$scale;
 13072     int      disp = $mem$$disp;
 13074     guarantee(Assembler::is_simm16(disp), "");
 13076     if( index != 0 ) {
 13077       __ stop("in storeIConditional: index != 0");
 13078     } else {
 13079       __ bind(again);
 13080       if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
 13081       __ ll(AT, addr);
 13082       __ bne(AT, oldval, failure);
 13083       __ delayed()->addu(AT, R0, R0);
 13085       __ addu(AT, newval, R0);
 13086       __ sc(AT, addr);
 13087       __ beq(AT, R0, again);
 13088       __ delayed()->addiu(AT, R0, 0xFF);
 13089       __ bind(failure);
 13090       __ sync();
 13092 %}
 13094   ins_pipe( long_memory_op );
 13095 %}
 13097 // Conditional-store of a long value.
 13098 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
 13099 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
 13100 %{
 13101   match(Set cr (StoreLConditional mem (Binary oldval newval)));
 13102   effect(KILL oldval);
 13104   format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
 13105   ins_encode%{
 13106     Register oldval = $oldval$$Register;
 13107     Register newval = $newval$$Register;
 13108     Address addr((Register)$mem$$base, $mem$$disp);
 13110     int     index = $mem$$index;
 13111     int     scale = $mem$$scale;
 13112     int      disp = $mem$$disp;
 13114     guarantee(Assembler::is_simm16(disp), "");
 13116     if( index != 0 ) {
 13117       __ stop("in storeIConditional: index != 0");
 13118     } else {
 13119       __ cmpxchg(newval, addr, oldval);
 13121   %}
 13122   ins_pipe( long_memory_op );
 13123 %}
 13126 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
 13127   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
 13128   effect(KILL oldval);
 13129 //  match(CompareAndSwapI mem_ptr (Binary oldval newval));
 13130   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
 13131             "MOV    $res, 1 @ compareAndSwapI\n\t"
 13132             "BNE    AT, R0 @ compareAndSwapI\n\t"
 13133             "MOV    $res, 0 @ compareAndSwapI\n"
 13134           "L:" %}
 13135   ins_encode %{
 13136     Register newval = $newval$$Register;
 13137     Register oldval = $oldval$$Register;
 13138     Register res    = $res$$Register;
 13139     Address  addr($mem_ptr$$Register, 0);
 13140     Label L;
 13142     __ cmpxchg32(newval, addr, oldval);
 13143     __ move(res, AT);
 13144   %}
 13145   ins_pipe( long_memory_op );
 13146 %}
 13148 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
 13149   predicate(VM_Version::supports_cx8());
 13150   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
 13151   effect(KILL oldval);
 13152   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
 13153             "MOV    $res, 1 @ compareAndSwapI\n\t"
 13154             "BNE    AT, R0 @ compareAndSwapI\n\t"
 13155             "MOV    $res, 0 @ compareAndSwapI\n"
 13156           "L:" %}
 13157   ins_encode %{
 13158     Register newval = $newval$$Register;
 13159     Register oldval = $oldval$$Register;
 13160     Register res    = $res$$Register;
 13161     Address  addr($mem_ptr$$Register, 0);
 13162     Label L;
 13164     __ cmpxchg(newval, addr, oldval);
 13165     __ move(res, AT);
 13166   %}
 13167   ins_pipe( long_memory_op );
 13168 %}
 13170 //FIXME:
 13171 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
 13172   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
 13173   effect(KILL oldval);
 13174   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
 13175             "MOV    $res, AT @ compareAndSwapP\n\t"
 13176           "L:" %}
 13177   ins_encode %{
 13178     Register newval = $newval$$Register;
 13179     Register oldval = $oldval$$Register;
 13180     Register res    = $res$$Register;
 13181     Address  addr($mem_ptr$$Register, 0);
 13182     Label L;
 13184     __ cmpxchg(newval, addr, oldval);
 13185     __ move(res, AT);
 13186   %}
 13187   ins_pipe( long_memory_op );
 13188 %}
 13190 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
 13191   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
 13192   effect(KILL oldval);
 13193   format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
 13194             "MOV    $res, AT @ compareAndSwapN\n\t"
 13195           "L:" %}
 13196   ins_encode %{
 13197     Register newval = $newval$$Register;
 13198     Register oldval = $oldval$$Register;
 13199     Register res    = $res$$Register;
 13200     Address  addr($mem_ptr$$Register, 0);
 13201     Label L;
 13203     /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
 13204      *      Thus, we should extend oldval's sign for correct comparision.
 13205      */
 13206     __ sll(oldval, oldval, 0);
 13208     __ cmpxchg32(newval, addr, oldval);
 13209     __ move(res, AT);
 13210   %}
 13211   ins_pipe( long_memory_op );
 13212 %}
 13214 //----------Max and Min--------------------------------------------------------
 13215 // Min Instructions
 13216 ////
 13217 //   *** Min and Max using the conditional move are slower than the
 13218 //   *** branch version on a Pentium III.
 13219 // // Conditional move for min
 13220 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 13221 //  effect( USE_DEF op2, USE op1, USE cr );
 13222 //  format %{ "CMOVlt $op2,$op1\t! min" %}
 13223 //  opcode(0x4C,0x0F);
 13224 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 13225 //  ins_pipe( pipe_cmov_reg );
 13226 //%}
 13227 //
 13228 //// Min Register with Register (P6 version)
 13229 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
 13230 //  predicate(VM_Version::supports_cmov() );
 13231 //  match(Set op2 (MinI op1 op2));
 13232 //  ins_cost(200);
 13233 //  expand %{
 13234 //    eFlagsReg cr;
 13235 //    compI_eReg(cr,op1,op2);
 13236 //    cmovI_reg_lt(op2,op1,cr);
 13237 //  %}
 13238 //%}
 13240 // Min Register with Register (generic version)
 13241 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
 13242   match(Set dst (MinI dst src));
 13243   //effect(KILL flags);
 13244   ins_cost(80);
 13246   format %{ "MIN    $dst, $src @minI_Reg_Reg" %}
 13247   ins_encode %{
 13248     Register dst   = $dst$$Register;
 13249     Register src   = $src$$Register;
 13251     __ slt(AT, src, dst);
 13252     __ movn(dst, src, AT);
 13254   %}
 13256   ins_pipe( pipe_slow );
 13257 %}
 13259 // Max Register with Register
 13260 //   *** Min and Max using the conditional move are slower than the
 13261 //   *** branch version on a Pentium III.
 13262 // // Conditional move for max
 13263 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
 13264 //  effect( USE_DEF op2, USE op1, USE cr );
 13265 //  format %{ "CMOVgt $op2,$op1\t! max" %}
 13266 //  opcode(0x4F,0x0F);
 13267 //  ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
 13268 //  ins_pipe( pipe_cmov_reg );
 13269 //%}
 13270 //
 13271 // // Max Register with Register (P6 version)
 13272 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
 13273 //  predicate(VM_Version::supports_cmov() );
 13274 //  match(Set op2 (MaxI op1 op2));
 13275 //  ins_cost(200);
 13276 //  expand %{
 13277 //    eFlagsReg cr;
 13278 //    compI_eReg(cr,op1,op2);
 13279 //    cmovI_reg_gt(op2,op1,cr);
 13280 //  %}
 13281 //%}
 13283 // Max Register with Register (generic version)
 13284 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
 13285   match(Set dst (MaxI dst src));
 13286   ins_cost(80);
 13288   format %{ "MAX    $dst, $src @maxI_Reg_Reg" %}
 13290   ins_encode %{
 13291     Register dst   = $dst$$Register;
 13292     Register src   = $src$$Register;
 13294     __ slt(AT, dst, src);
 13295     __ movn(dst, src, AT);
 13297   %}
 13299   ins_pipe( pipe_slow );
 13300 %}
 13302 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
 13303   match(Set dst (MaxI dst zero));
 13304   ins_cost(50);
 13306   format %{ "MAX    $dst, 0 @maxI_Reg_zero" %}
 13308   ins_encode %{
 13309     Register dst   = $dst$$Register;
 13311     __ slt(AT, dst, R0);
 13312     __ movn(dst, R0, AT);
 13314   %}
 13316   ins_pipe( pipe_slow );
 13317 %}
 13319 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
 13320 %{
 13321   match(Set dst (AndL src mask));
 13323   format %{ "movl    $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
 13324   ins_encode %{
 13325     Register dst = $dst$$Register;
 13326     Register src = $src$$Register;
 13328     __ dext(dst, src, 0, 32);
 13329   %}
 13330   ins_pipe(ialu_regI_regI);
 13331 %}
 13333 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
 13334 %{
 13335   match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
 13337   format %{ "combine_i2l    $dst, $src2(H), $src1(L) @ combine_i2l" %}
 13338   ins_encode %{
 13339     Register dst  = $dst$$Register;
 13340     Register src1 = $src1$$Register;
 13341     Register src2 = $src2$$Register;
 13343     if (src1 == dst) {
 13344        __ dinsu(dst, src2, 32, 32);
 13345     } else if (src2 == dst) {
 13346        __ dsll32(dst, dst, 0);
 13347        __ dins(dst, src1, 0, 32);
 13348     } else {
 13349        __ dext(dst, src1, 0, 32);
 13350        __ dinsu(dst, src2, 32, 32);
 13352   %}
 13353   ins_pipe(ialu_regI_regI);
 13354 %}
 13356 // Zero-extend convert int to long
 13357 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
 13358 %{
 13359   match(Set dst (AndL (ConvI2L src) mask));
 13361   format %{ "movl    $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
 13362   ins_encode %{
 13363     Register dst = $dst$$Register;
 13364     Register src = $src$$Register;
 13366     __ dext(dst, src, 0, 32);
 13367   %}
 13368   ins_pipe(ialu_regI_regI);
 13369 %}
 13371 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
 13372 %{
 13373   match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
 13375   format %{ "movl    $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
 13376   ins_encode %{
 13377     Register dst = $dst$$Register;
 13378     Register src = $src$$Register;
 13380     __ dext(dst, src, 0, 32);
 13381   %}
 13382   ins_pipe(ialu_regI_regI);
 13383 %}
 13385 // Match loading integer and casting it to unsigned int in long register.
 13386 // LoadI + ConvI2L + AndL 0xffffffff.
 13387 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
 13388   match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 13390   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
 13391   ins_encode (load_N_enc(dst, mem));
 13392   ins_pipe(ialu_loadI);
 13393 %}
 13395 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
 13396   match(Set dst (AndL mask (ConvI2L (LoadI mem))));
 13398   format %{ "lwu     $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
 13399   ins_encode (load_N_enc(dst, mem));
 13400   ins_pipe(ialu_loadI);
 13401 %}
 13404 // ============================================================================
 13405 // Safepoint Instruction
 13406 instruct safePoint_poll_reg(mRegP poll) %{
 13407   match(SafePoint poll);
 13408   predicate(false);
 13409   effect(USE poll);
 13411   ins_cost(125);
 13412   format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
 13414   ins_encode %{
 13415     Register poll_reg = $poll$$Register;
 13417     __ block_comment("Safepoint:");
 13418     __ relocate(relocInfo::poll_type);
 13419     __ lw(AT, poll_reg, 0);
 13420   %}
 13422   ins_pipe( ialu_storeI );
 13423 %}
 13425 instruct safePoint_poll() %{
 13426   match(SafePoint);
 13428   ins_cost(105);
 13429   format %{ "poll for GC @ safePoint_poll" %}
 13431   ins_encode %{
 13432     __ block_comment("Safepoint:");
 13433     __ set64(T9, (long)os::get_polling_page());
 13434     __ relocate(relocInfo::poll_type);
 13435     __ lw(AT, T9, 0);
 13436   %}
 13438   ins_pipe( ialu_storeI );
 13439 %}
 13441 //----------Arithmetic Conversion Instructions---------------------------------
 13443 instruct roundFloat_nop(regF dst)
 13444 %{
 13445   match(Set dst (RoundFloat dst));
 13447   ins_cost(0);
 13448   ins_encode();
 13449   ins_pipe(empty);
 13450 %}
 13452 instruct roundDouble_nop(regD dst)
 13453 %{
 13454   match(Set dst (RoundDouble dst));
 13456   ins_cost(0);
 13457   ins_encode();
 13458   ins_pipe(empty);
 13459 %}
 13461 //---------- Zeros Count Instructions ------------------------------------------
 13462 // CountLeadingZerosINode CountTrailingZerosINode
 13463 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
 13464   predicate(UseCountLeadingZerosInstruction);
 13465   match(Set dst (CountLeadingZerosI src));
 13467   format %{ "clz  $dst, $src\t# count leading zeros (int)" %}
 13468   ins_encode %{
 13469     __ clz($dst$$Register, $src$$Register);
 13470   %}
 13471   ins_pipe( ialu_regL_regL );
 13472 %}
 13474 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
 13475   predicate(UseCountLeadingZerosInstruction);
 13476   match(Set dst (CountLeadingZerosL src));
 13478   format %{ "dclz  $dst, $src\t# count leading zeros (long)" %}
 13479   ins_encode %{
 13480     __ dclz($dst$$Register, $src$$Register);
 13481   %}
 13482   ins_pipe( ialu_regL_regL );
 13483 %}
 13485 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
 13486   predicate(UseCountTrailingZerosInstruction);
 13487   match(Set dst (CountTrailingZerosI src));
 13489   format %{ "ctz    $dst, $src\t# count trailing zeros (int)" %}
 13490   ins_encode %{
 13491     // ctz and dctz is gs instructions.
 13492     __ ctz($dst$$Register, $src$$Register);
 13493   %}
 13494   ins_pipe( ialu_regL_regL );
 13495 %}
 13497 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
 13498   predicate(UseCountTrailingZerosInstruction);
 13499   match(Set dst (CountTrailingZerosL src));
 13501   format %{ "dcto    $dst, $src\t# count trailing zeros (long)" %}
 13502   ins_encode %{
 13503     __ dctz($dst$$Register, $src$$Register);
 13504   %}
 13505   ins_pipe( ialu_regL_regL );
 13506 %}
 13508 // ====================VECTOR INSTRUCTIONS=====================================
 13510 // Load vectors (8 bytes long)
 13511 instruct loadV8(vecD dst, memory mem) %{
 13512   predicate(n->as_LoadVector()->memory_size() == 8);
 13513   match(Set dst (LoadVector mem));
 13514   ins_cost(125);
 13515   format %{ "load    $dst, $mem\t! load vector (8 bytes)" %}
 13516   ins_encode(load_D_enc(dst, mem));
 13517   ins_pipe( fpu_loadF );
 13518 %}
 13520 // Store vectors (8 bytes long)
 13521 instruct storeV8(memory mem, vecD src) %{
 13522   predicate(n->as_StoreVector()->memory_size() == 8);
 13523   match(Set mem (StoreVector mem src));
 13524   ins_cost(145);
 13525   format %{ "store    $mem, $src\t! store vector (8 bytes)" %}
 13526   ins_encode(store_D_reg_enc(mem, src));
 13527   ins_pipe( fpu_storeF );
 13528 %}
 13530 instruct Repl8B_DSP(vecD dst, mRegI src) %{
 13531   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 13532   match(Set dst (ReplicateB src));
 13533   ins_cost(100);
 13534   format %{ "replv_ob    AT, $src\n\t"
 13535             "dmtc1 AT, $dst\t! replicate8B" %}
 13536   ins_encode %{
 13537     __ replv_ob(AT, $src$$Register);
 13538     __ dmtc1(AT, $dst$$FloatRegister);
 13539   %}
 13540   ins_pipe( pipe_mtc1 );
 13541 %}
 13543 instruct Repl8B(vecD dst, mRegI src) %{
 13544   predicate(n->as_Vector()->length() == 8);
 13545   match(Set dst (ReplicateB src));
 13546   ins_cost(140);
 13547   format %{ "move       AT,  $src\n\t"
 13548             "dins  AT, AT,  8,  8\n\t"
 13549             "dins  AT, AT, 16, 16\n\t"
 13550             "dinsu AT, AT, 32, 32\n\t"
 13551             "dmtc1 AT, $dst\t! replicate8B" %}
 13552   ins_encode %{
 13553     __ move(AT, $src$$Register);
 13554     __ dins(AT, AT, 8, 8);
 13555     __ dins(AT, AT, 16, 16);
 13556     __ dinsu(AT, AT, 32, 32);
 13557     __ dmtc1(AT, $dst$$FloatRegister);
 13558   %}
 13559   ins_pipe( pipe_mtc1 );
 13560 %}
 13562 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
 13563   predicate(n->as_Vector()->length() == 8 && Use3A2000);
 13564   match(Set dst (ReplicateB con));
 13565   ins_cost(110);
 13566   format %{ "repl_ob    AT, [$con]\n\t"
 13567             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 13568   ins_encode %{
 13569     int      val = $con$$constant;
 13570     __ repl_ob(AT, val);
 13571     __ dmtc1(AT, $dst$$FloatRegister);
 13572   %}
 13573   ins_pipe( pipe_mtc1 );
 13574 %}
 13576 instruct Repl8B_imm(vecD dst, immI con) %{
 13577   predicate(n->as_Vector()->length() == 8);
 13578   match(Set dst (ReplicateB con));
 13579   ins_cost(150);
 13580   format %{ "move      AT, [$con]\n\t"
 13581             "dins  AT, AT,  8,  8\n\t"
 13582             "dins  AT, AT, 16, 16\n\t"
 13583             "dinsu AT, AT, 32, 32\n\t"
 13584             "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
 13585   ins_encode %{
 13586     __ move(AT, $con$$constant);
 13587     __ dins(AT, AT, 8, 8);
 13588     __ dins(AT, AT, 16, 16);
 13589     __ dinsu(AT, AT, 32, 32);
 13590     __ dmtc1(AT, $dst$$FloatRegister);
 13591   %}
 13592   ins_pipe( pipe_mtc1 );
 13593 %}
 13595 instruct Repl8B_zero(vecD dst, immI0 zero) %{
 13596   predicate(n->as_Vector()->length() == 8);
 13597   match(Set dst (ReplicateB zero));
 13598   ins_cost(90);
 13599   format %{ "dmtc1    R0, $dst\t! replicate8B zero" %}
 13600   ins_encode %{
 13601     __ dmtc1(R0, $dst$$FloatRegister);
 13602   %}
 13603   ins_pipe( pipe_mtc1 );
 13604 %}
 13606 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
 13607   predicate(n->as_Vector()->length() == 8);
 13608   match(Set dst (ReplicateB M1));
 13609   ins_cost(80);
 13610   format %{ "dmtc1    -1, $dst\t! replicate8B -1" %}
 13611   ins_encode %{
 13612     __ nor(AT, R0, R0);
 13613     __ dmtc1(AT, $dst$$FloatRegister);
 13614   %}
 13615   ins_pipe( pipe_mtc1 );
 13616 %}
 13618 instruct Repl4S_DSP(vecD dst, mRegI src) %{
 13619   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 13620   match(Set dst (ReplicateS src));
 13621   ins_cost(100);
 13622   format %{ "replv_qh    AT, $src\n\t"
 13623             "dmtc1 AT, $dst\t! replicate4S" %}
 13624   ins_encode %{
 13625     __ replv_qh(AT, $src$$Register);
 13626     __ dmtc1(AT, $dst$$FloatRegister);
 13627   %}
 13628   ins_pipe( pipe_mtc1 );
 13629 %}
 13631 instruct Repl4S(vecD dst, mRegI src) %{
 13632   predicate(n->as_Vector()->length() == 4);
 13633   match(Set dst (ReplicateS src));
 13634   ins_cost(120);
 13635   format %{ "move    AT,     $src  \n\t"
 13636             "dins    AT, AT, 16, 16\n\t"
 13637             "dinsu   AT, AT, 32, 32\n\t"
 13638             "dmtc1 AT, $dst\t! replicate4S" %}
 13639   ins_encode %{
 13640     __ move(AT, $src$$Register);
 13641     __ dins(AT, AT, 16, 16);
 13642     __ dinsu(AT, AT, 32, 32);
 13643     __ dmtc1(AT, $dst$$FloatRegister);
 13644   %}
 13645   ins_pipe( pipe_mtc1 );
 13646 %}
 13648 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
 13649   predicate(n->as_Vector()->length() == 4 && Use3A2000);
 13650   match(Set dst (ReplicateS con));
 13651   ins_cost(100);
 13652   format %{ "repl_qh    AT, [$con]\n\t"
 13653             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 13654   ins_encode %{
 13655     int      val = $con$$constant;
 13656     if ( Assembler::is_simm(val, 10)) {
 13657       //repl_qh supports 10 bits immediate
 13658       __ repl_qh(AT, val);
 13659     } else {
 13660       __ li32(AT, val);
 13661       __ replv_qh(AT, AT);
 13663     __ dmtc1(AT, $dst$$FloatRegister);
 13664   %}
 13665   ins_pipe( pipe_mtc1 );
 13666 %}
 13668 instruct Repl4S_imm(vecD dst, immI con) %{
 13669   predicate(n->as_Vector()->length() == 4);
 13670   match(Set dst (ReplicateS con));
 13671   ins_cost(110);
 13672   format %{ "move    AT,   [$con]\n\t"
 13673             "dins  AT, AT, 16, 16\n\t"
 13674             "dinsu AT, AT, 32, 32\n\t"
 13675             "dmtc1 AT, $dst\t! replicate4S($con)" %}
 13676   ins_encode %{
 13677     __ move(AT, $con$$constant);
 13678     __ dins(AT, AT, 16, 16);
 13679     __ dinsu(AT, AT, 32, 32);
 13680     __ dmtc1(AT, $dst$$FloatRegister);
 13681   %}
 13682   ins_pipe( pipe_mtc1 );
 13683 %}
 13685 instruct Repl4S_zero(vecD dst, immI0 zero) %{
 13686   predicate(n->as_Vector()->length() == 4);
 13687   match(Set dst (ReplicateS zero));
 13688   format %{ "dmtc1    R0, $dst\t! replicate4S zero" %}
 13689   ins_encode %{
 13690     __ dmtc1(R0, $dst$$FloatRegister);
 13691   %}
 13692   ins_pipe( pipe_mtc1 );
 13693 %}
 13695 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
 13696   predicate(n->as_Vector()->length() == 4);
 13697   match(Set dst (ReplicateS M1));
 13698   format %{ "dmtc1    -1, $dst\t! replicate4S -1" %}
 13699   ins_encode %{
 13700     __ nor(AT, R0, R0);
 13701     __ dmtc1(AT, $dst$$FloatRegister);
 13702   %}
 13703   ins_pipe( pipe_mtc1 );
 13704 %}
 13706 // Replicate integer (4 byte) scalar to be vector
 13707 instruct Repl2I(vecD dst, mRegI src) %{
 13708   predicate(n->as_Vector()->length() == 2);
 13709   match(Set dst (ReplicateI src));
 13710   format %{ "dins    AT, $src, 0, 32\n\t"
 13711             "dinsu   AT, $src, 32, 32\n\t"
 13712             "dmtc1   AT, $dst\t! replicate2I" %}
 13713   ins_encode %{
 13714     __ dins(AT, $src$$Register, 0, 32);
 13715     __ dinsu(AT, $src$$Register, 32, 32);
 13716     __ dmtc1(AT, $dst$$FloatRegister);
 13717   %}
 13718   ins_pipe( pipe_mtc1 );
 13719 %}
 13721 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
 13722 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
 13723   predicate(n->as_Vector()->length() == 2);
 13724   match(Set dst (ReplicateI con));
 13725   effect(KILL tmp);
 13726   format %{ "li32    AT, [$con], 32\n\t"
 13727             "dinsu   AT,         AT\n\t"
 13728             "dmtc1   AT, $dst\t! replicate2I($con)" %}
 13729   ins_encode %{
 13730     int      val = $con$$constant;
 13731     __ li32(AT, val);
 13732     __ dinsu(AT, AT, 32, 32);
 13733     __ dmtc1(AT, $dst$$FloatRegister);
 13734   %}
 13735   ins_pipe( pipe_mtc1 );
 13736 %}
 13738 // Replicate integer (4 byte) scalar zero to be vector
 13739 instruct Repl2I_zero(vecD dst, immI0 zero) %{
 13740   predicate(n->as_Vector()->length() == 2);
 13741   match(Set dst (ReplicateI zero));
 13742   format %{ "dmtc1    R0, $dst\t! replicate2I zero" %}
 13743   ins_encode %{
 13744     __ dmtc1(R0, $dst$$FloatRegister);
 13745   %}
 13746   ins_pipe( pipe_mtc1 );
 13747 %}
 13749 // Replicate integer (4 byte) scalar -1 to be vector
 13750 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
 13751   predicate(n->as_Vector()->length() == 2);
 13752   match(Set dst (ReplicateI M1));
 13753   format %{ "dmtc1    -1, $dst\t! replicate2I -1, use AT" %}
 13754   ins_encode %{
 13755     __ nor(AT, R0, R0);
 13756     __ dmtc1(AT, $dst$$FloatRegister);
 13757   %}
 13758   ins_pipe( pipe_mtc1 );
 13759 %}
 13761 // Replicate float (4 byte) scalar to be vector
 13762 instruct Repl2F(vecD dst, regF src) %{
 13763   predicate(n->as_Vector()->length() == 2);
 13764   match(Set dst (ReplicateF src));
 13765   format %{ "cvt.ps  $dst, $src, $src\t! replicate2F" %}
 13766   ins_encode %{
 13767     __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
 13768   %}
 13769   ins_pipe( pipe_slow );
 13770 %}
 13772 // Replicate float (4 byte) scalar zero to be vector
 13773 instruct Repl2F_zero(vecD dst, immF0 zero) %{
 13774   predicate(n->as_Vector()->length() == 2);
 13775   match(Set dst (ReplicateF zero));
 13776   format %{ "dmtc1   R0, $dst\t! replicate2F zero" %}
 13777   ins_encode %{
 13778     __ dmtc1(R0, $dst$$FloatRegister);
 13779   %}
 13780   ins_pipe( pipe_mtc1 );
 13781 %}
 13784 // ====================VECTOR ARITHMETIC=======================================
 13786 // --------------------------------- ADD --------------------------------------
 13788 // Floats vector add
 13789 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
 13790 instruct vadd2F(vecD dst, vecD src) %{
 13791   predicate(n->as_Vector()->length() == 2);
 13792   match(Set dst (AddVF dst src));
 13793   format %{ "add.ps   $dst,$src\t! add packed2F" %}
 13794   ins_encode %{
 13795     __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 13796   %}
 13797   ins_pipe( pipe_slow );
 13798 %}
 13800 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
 13801   predicate(n->as_Vector()->length() == 2);
 13802   match(Set dst (AddVF src1 src2));
 13803   format %{ "add.ps   $dst,$src1,$src2\t! add packed2F" %}
 13804   ins_encode %{
 13805     __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 13806   %}
 13807   ins_pipe( fpu_regF_regF );
 13808 %}
 13810 // --------------------------------- SUB --------------------------------------
 13812 // Floats vector sub
 13813 instruct vsub2F(vecD dst, vecD src) %{
 13814   predicate(n->as_Vector()->length() == 2);
 13815   match(Set dst (SubVF dst src));
 13816   format %{ "sub.ps   $dst,$src\t! sub packed2F" %}
 13817   ins_encode %{
 13818     __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 13819   %}
 13820   ins_pipe( fpu_regF_regF );
 13821 %}
 13823 // --------------------------------- MUL --------------------------------------
 13825 // Floats vector mul
 13826 instruct vmul2F(vecD dst, vecD src) %{
 13827   predicate(n->as_Vector()->length() == 2);
 13828   match(Set dst (MulVF dst src));
 13829   format %{ "mul.ps   $dst, $src\t! mul packed2F" %}
 13830   ins_encode %{
 13831     __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
 13832   %}
 13833   ins_pipe( fpu_regF_regF );
 13834 %}
 13836 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
 13837   predicate(n->as_Vector()->length() == 2);
 13838   match(Set dst (MulVF src1 src2));
 13839   format %{ "mul.ps   $dst, $src1, $src2\t! mul packed2F" %}
 13840   ins_encode %{
 13841     __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 13842   %}
 13843   ins_pipe( fpu_regF_regF );
 13844 %}
 13846 // --------------------------------- DIV --------------------------------------
 13847 // MIPS do not have div.ps
 13849 // --------------------------------- MADD --------------------------------------
 13850 // Floats vector madd
 13851 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
 13852 //  predicate(n->as_Vector()->length() == 2);
 13853 //  match(Set dst (AddVF (MulVF src1 src2) src3));
 13854 //  ins_cost(50);
 13855 //  format %{ "madd.ps   $dst, $src3, $src1, $src2\t! madd packed2F" %}
 13856 //  ins_encode %{
 13857 //    __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
 13858 //  %}
 13859 //  ins_pipe( fpu_regF_regF );
 13860 //%}
 13863 //----------PEEPHOLE RULES-----------------------------------------------------
 13864 // These must follow all instruction definitions as they use the names
 13865 // defined in the instructions definitions.
 13866 //
 13867 // peepmatch ( root_instr_name [preceeding_instruction]* );
 13868 //
 13869 // peepconstraint %{
 13870 // (instruction_number.operand_name relational_op instruction_number.operand_name
 13871 //  [, ...] );
 13872 // // instruction numbers are zero-based using left to right order in peepmatch
 13873 //
 13874 // peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
 13875 // // provide an instruction_number.operand_name for each operand that appears
 13876 // // in the replacement instruction's match rule
 13877 //
 13878 // ---------VM FLAGS---------------------------------------------------------
 13879 //
 13880 // All peephole optimizations can be turned off using -XX:-OptoPeephole
 13881 //
 13882 // Each peephole rule is given an identifying number starting with zero and
 13883 // increasing by one in the order seen by the parser.  An individual peephole
 13884 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
 13885 // on the command-line.
 13886 //
 13887 // ---------CURRENT LIMITATIONS----------------------------------------------
 13888 //
 13889 // Only match adjacent instructions in same basic block
 13890 // Only equality constraints
 13891 // Only constraints between operands, not (0.dest_reg == EAX_enc)
 13892 // Only one replacement instruction
 13893 //
 13894 // ---------EXAMPLE----------------------------------------------------------
 13895 //
 13896 // // pertinent parts of existing instructions in architecture description
 13897 // instruct movI(eRegI dst, eRegI src) %{
 13898 //   match(Set dst (CopyI src));
 13899 // %}
 13900 //
 13901 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
 13902 //   match(Set dst (AddI dst src));
 13903 //   effect(KILL cr);
 13904 // %}
 13905 //
 13906 // // Change (inc mov) to lea
 13907 // peephole %{
 13908 //   // increment preceeded by register-register move
 13909 //   peepmatch ( incI_eReg movI );
 13910 //   // require that the destination register of the increment
 13911 //   // match the destination register of the move
 13912 //   peepconstraint ( 0.dst == 1.dst );
 13913 //   // construct a replacement instruction that sets
 13914 //   // the destination to ( move's source register + one )
 13915 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 13916 // %}
 13917 //
 13918 // Implementation no longer uses movX instructions since
 13919 // machine-independent system no longer uses CopyX nodes.
 13920 //
 13921 // peephole %{
 13922 //   peepmatch ( incI_eReg movI );
 13923 //   peepconstraint ( 0.dst == 1.dst );
 13924 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 13925 // %}
 13926 //
 13927 // peephole %{
 13928 //   peepmatch ( decI_eReg movI );
 13929 //   peepconstraint ( 0.dst == 1.dst );
 13930 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 13931 // %}
 13932 //
 13933 // peephole %{
 13934 //   peepmatch ( addI_eReg_imm movI );
 13935 //   peepconstraint ( 0.dst == 1.dst );
 13936 //   peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
 13937 // %}
 13938 //
 13939 // peephole %{
 13940 //   peepmatch ( addP_eReg_imm movP );
 13941 //   peepconstraint ( 0.dst == 1.dst );
 13942 //   peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
 13943 // %}
 13945 // // Change load of spilled value to only a spill
 13946 // instruct storeI(memory mem, eRegI src) %{
 13947 //   match(Set mem (StoreI mem src));
 13948 // %}
 13949 //
 13950 // instruct loadI(eRegI dst, memory mem) %{
 13951 //   match(Set dst (LoadI mem));
 13952 // %}
 13953 //
 13954 //peephole %{
 13955 //  peepmatch ( loadI storeI );
 13956 //  peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
 13957 //  peepreplace ( storeI( 1.mem 1.mem 1.src ) );
 13958 //%}
 13960 //----------SMARTSPILL RULES---------------------------------------------------
 13961 // These must follow all instruction definitions as they use the names
 13962 // defined in the instructions definitions.

mercurial