hotspot/src/cpu/ppc/vm/assembler_ppc.cpp
changeset 22824 28258dd5cb2e
child 23492 af5352f40e65
equal deleted inserted replaced
22823:40b2c6c30123 22824:28258dd5cb2e
       
     1 /*
       
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * Copyright 2012, 2013 SAP AG. 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  */
       
    25 
       
    26 #include "precompiled.hpp"
       
    27 #include "asm/assembler.hpp"
       
    28 #include "asm/assembler.inline.hpp"
       
    29 #include "gc_interface/collectedHeap.inline.hpp"
       
    30 #include "interpreter/interpreter.hpp"
       
    31 #include "memory/cardTableModRefBS.hpp"
       
    32 #include "memory/resourceArea.hpp"
       
    33 #include "prims/methodHandles.hpp"
       
    34 #include "runtime/biasedLocking.hpp"
       
    35 #include "runtime/interfaceSupport.hpp"
       
    36 #include "runtime/objectMonitor.hpp"
       
    37 #include "runtime/os.hpp"
       
    38 #include "runtime/sharedRuntime.hpp"
       
    39 #include "runtime/stubRoutines.hpp"
       
    40 #if INCLUDE_ALL_GCS
       
    41 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
       
    42 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
       
    43 #include "gc_implementation/g1/heapRegion.hpp"
       
    44 #endif // INCLUDE_ALL_GCS
       
    45 
       
    46 #ifdef PRODUCT
       
    47 #define BLOCK_COMMENT(str) // nothing
       
    48 #else
       
    49 #define BLOCK_COMMENT(str) block_comment(str)
       
    50 #endif
       
    51 
       
    52 int AbstractAssembler::code_fill_byte() {
       
    53   return 0x00;                  // illegal instruction 0x00000000
       
    54 }
       
    55 
       
    56 void Assembler::print_instruction(int inst) {
       
    57   Unimplemented();
       
    58 }
       
    59 
       
    60 // Patch instruction `inst' at offset `inst_pos' to refer to
       
    61 // `dest_pos' and return the resulting instruction.  We should have
       
    62 // pcs, not offsets, but since all is relative, it will work out fine.
       
    63 int Assembler::patched_branch(int dest_pos, int inst, int inst_pos) {
       
    64   int m = 0; // mask for displacement field
       
    65   int v = 0; // new value for displacement field
       
    66 
       
    67   switch (inv_op_ppc(inst)) {
       
    68   case b_op:  m = li(-1); v = li(disp(dest_pos, inst_pos)); break;
       
    69   case bc_op: m = bd(-1); v = bd(disp(dest_pos, inst_pos)); break;
       
    70     default: ShouldNotReachHere();
       
    71   }
       
    72   return inst & ~m | v;
       
    73 }
       
    74 
       
    75 // Return the offset, relative to _code_begin, of the destination of
       
    76 // the branch inst at offset pos.
       
    77 int Assembler::branch_destination(int inst, int pos) {
       
    78   int r = 0;
       
    79   switch (inv_op_ppc(inst)) {
       
    80     case b_op:  r = bxx_destination_offset(inst, pos); break;
       
    81     case bc_op: r = inv_bd_field(inst, pos); break;
       
    82     default: ShouldNotReachHere();
       
    83   }
       
    84   return r;
       
    85 }
       
    86 
       
    87 // Low-level andi-one-instruction-macro.
       
    88 void Assembler::andi(Register a, Register s, const int ui16) {
       
    89   assert(is_uimm(ui16, 16), "must be 16-bit unsigned immediate");
       
    90   if (is_power_of_2_long(((jlong) ui16)+1)) {
       
    91     // pow2minus1
       
    92     clrldi(a, s, 64-log2_long((((jlong) ui16)+1)));
       
    93   } else if (is_power_of_2_long((jlong) ui16)) {
       
    94     // pow2
       
    95     rlwinm(a, s, 0, 31-log2_long((jlong) ui16), 31-log2_long((jlong) ui16));
       
    96   } else if (is_power_of_2_long((jlong)-ui16)) {
       
    97     // negpow2
       
    98     clrrdi(a, s, log2_long((jlong)-ui16));
       
    99   } else {
       
   100     andi_(a, s, ui16);
       
   101   }
       
   102 }
       
   103 
       
   104 // RegisterOrConstant version.
       
   105 void Assembler::ld(Register d, RegisterOrConstant roc, Register s1) {
       
   106   if (roc.is_constant()) {
       
   107     if (s1 == noreg) {
       
   108       int simm16_rest = load_const_optimized(d, roc.as_constant(), noreg, true);
       
   109       Assembler::ld(d, simm16_rest, d);
       
   110     } else if (is_simm(roc.as_constant(), 16)) {
       
   111       Assembler::ld(d, roc.as_constant(), s1);
       
   112     } else {
       
   113       load_const_optimized(d, roc.as_constant());
       
   114       Assembler::ldx(d, d, s1);
       
   115     }
       
   116   } else {
       
   117     if (s1 == noreg)
       
   118       Assembler::ld(d, 0, roc.as_register());
       
   119     else
       
   120       Assembler::ldx(d, roc.as_register(), s1);
       
   121   }
       
   122 }
       
   123 
       
   124 void Assembler::lwa(Register d, RegisterOrConstant roc, Register s1) {
       
   125   if (roc.is_constant()) {
       
   126     if (s1 == noreg) {
       
   127       int simm16_rest = load_const_optimized(d, roc.as_constant(), noreg, true);
       
   128       Assembler::lwa(d, simm16_rest, d);
       
   129     } else if (is_simm(roc.as_constant(), 16)) {
       
   130       Assembler::lwa(d, roc.as_constant(), s1);
       
   131     } else {
       
   132       load_const_optimized(d, roc.as_constant());
       
   133       Assembler::lwax(d, d, s1);
       
   134     }
       
   135   } else {
       
   136     if (s1 == noreg)
       
   137       Assembler::lwa(d, 0, roc.as_register());
       
   138     else
       
   139       Assembler::lwax(d, roc.as_register(), s1);
       
   140   }
       
   141 }
       
   142 
       
   143 void Assembler::lwz(Register d, RegisterOrConstant roc, Register s1) {
       
   144   if (roc.is_constant()) {
       
   145     if (s1 == noreg) {
       
   146       int simm16_rest = load_const_optimized(d, roc.as_constant(), noreg, true);
       
   147       Assembler::lwz(d, simm16_rest, d);
       
   148     } else if (is_simm(roc.as_constant(), 16)) {
       
   149       Assembler::lwz(d, roc.as_constant(), s1);
       
   150     } else {
       
   151       load_const_optimized(d, roc.as_constant());
       
   152       Assembler::lwzx(d, d, s1);
       
   153     }
       
   154   } else {
       
   155     if (s1 == noreg)
       
   156       Assembler::lwz(d, 0, roc.as_register());
       
   157     else
       
   158       Assembler::lwzx(d, roc.as_register(), s1);
       
   159   }
       
   160 }
       
   161 
       
   162 void Assembler::lha(Register d, RegisterOrConstant roc, Register s1) {
       
   163   if (roc.is_constant()) {
       
   164     if (s1 == noreg) {
       
   165       int simm16_rest = load_const_optimized(d, roc.as_constant(), noreg, true);
       
   166       Assembler::lha(d, simm16_rest, d);
       
   167     } else if (is_simm(roc.as_constant(), 16)) {
       
   168       Assembler::lha(d, roc.as_constant(), s1);
       
   169     } else {
       
   170       load_const_optimized(d, roc.as_constant());
       
   171       Assembler::lhax(d, d, s1);
       
   172     }
       
   173   } else {
       
   174     if (s1 == noreg)
       
   175       Assembler::lha(d, 0, roc.as_register());
       
   176     else
       
   177       Assembler::lhax(d, roc.as_register(), s1);
       
   178   }
       
   179 }
       
   180 
       
   181 void Assembler::lhz(Register d, RegisterOrConstant roc, Register s1) {
       
   182   if (roc.is_constant()) {
       
   183     if (s1 == noreg) {
       
   184       int simm16_rest = load_const_optimized(d, roc.as_constant(), noreg, true);
       
   185       Assembler::lhz(d, simm16_rest, d);
       
   186     } else if (is_simm(roc.as_constant(), 16)) {
       
   187       Assembler::lhz(d, roc.as_constant(), s1);
       
   188     } else {
       
   189       load_const_optimized(d, roc.as_constant());
       
   190       Assembler::lhzx(d, d, s1);
       
   191     }
       
   192   } else {
       
   193     if (s1 == noreg)
       
   194       Assembler::lhz(d, 0, roc.as_register());
       
   195     else
       
   196       Assembler::lhzx(d, roc.as_register(), s1);
       
   197   }
       
   198 }
       
   199 
       
   200 void Assembler::lbz(Register d, RegisterOrConstant roc, Register s1) {
       
   201   if (roc.is_constant()) {
       
   202     if (s1 == noreg) {
       
   203       int simm16_rest = load_const_optimized(d, roc.as_constant(), noreg, true);
       
   204       Assembler::lbz(d, simm16_rest, d);
       
   205     } else if (is_simm(roc.as_constant(), 16)) {
       
   206       Assembler::lbz(d, roc.as_constant(), s1);
       
   207     } else {
       
   208       load_const_optimized(d, roc.as_constant());
       
   209       Assembler::lbzx(d, d, s1);
       
   210     }
       
   211   } else {
       
   212     if (s1 == noreg)
       
   213       Assembler::lbz(d, 0, roc.as_register());
       
   214     else
       
   215       Assembler::lbzx(d, roc.as_register(), s1);
       
   216   }
       
   217 }
       
   218 
       
   219 void Assembler::std(Register d, RegisterOrConstant roc, Register s1, Register tmp) {
       
   220   if (roc.is_constant()) {
       
   221     if (s1 == noreg) {
       
   222       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   223       int simm16_rest = load_const_optimized(tmp, roc.as_constant(), noreg, true);
       
   224       Assembler::std(d, simm16_rest, tmp);
       
   225     } else if (is_simm(roc.as_constant(), 16)) {
       
   226       Assembler::std(d, roc.as_constant(), s1);
       
   227     } else {
       
   228       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   229       load_const_optimized(tmp, roc.as_constant());
       
   230       Assembler::stdx(d, tmp, s1);
       
   231     }
       
   232   } else {
       
   233     if (s1 == noreg)
       
   234       Assembler::std(d, 0, roc.as_register());
       
   235     else
       
   236       Assembler::stdx(d, roc.as_register(), s1);
       
   237   }
       
   238 }
       
   239 
       
   240 void Assembler::stw(Register d, RegisterOrConstant roc, Register s1, Register tmp) {
       
   241   if (roc.is_constant()) {
       
   242     if (s1 == noreg) {
       
   243       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   244       int simm16_rest = load_const_optimized(tmp, roc.as_constant(), noreg, true);
       
   245       Assembler::stw(d, simm16_rest, tmp);
       
   246     } else if (is_simm(roc.as_constant(), 16)) {
       
   247       Assembler::stw(d, roc.as_constant(), s1);
       
   248     } else {
       
   249       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   250       load_const_optimized(tmp, roc.as_constant());
       
   251       Assembler::stwx(d, tmp, s1);
       
   252     }
       
   253   } else {
       
   254     if (s1 == noreg)
       
   255       Assembler::stw(d, 0, roc.as_register());
       
   256     else
       
   257       Assembler::stwx(d, roc.as_register(), s1);
       
   258   }
       
   259 }
       
   260 
       
   261 void Assembler::sth(Register d, RegisterOrConstant roc, Register s1, Register tmp) {
       
   262   if (roc.is_constant()) {
       
   263     if (s1 == noreg) {
       
   264       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   265       int simm16_rest = load_const_optimized(tmp, roc.as_constant(), noreg, true);
       
   266       Assembler::sth(d, simm16_rest, tmp);
       
   267     } else if (is_simm(roc.as_constant(), 16)) {
       
   268       Assembler::sth(d, roc.as_constant(), s1);
       
   269     } else {
       
   270       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   271       load_const_optimized(tmp, roc.as_constant());
       
   272       Assembler::sthx(d, tmp, s1);
       
   273     }
       
   274   } else {
       
   275     if (s1 == noreg)
       
   276       Assembler::sth(d, 0, roc.as_register());
       
   277     else
       
   278       Assembler::sthx(d, roc.as_register(), s1);
       
   279   }
       
   280 }
       
   281 
       
   282 void Assembler::stb(Register d, RegisterOrConstant roc, Register s1, Register tmp) {
       
   283   if (roc.is_constant()) {
       
   284     if (s1 == noreg) {
       
   285       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   286       int simm16_rest = load_const_optimized(tmp, roc.as_constant(), noreg, true);
       
   287       Assembler::stb(d, simm16_rest, tmp);
       
   288     } else if (is_simm(roc.as_constant(), 16)) {
       
   289       Assembler::stb(d, roc.as_constant(), s1);
       
   290     } else {
       
   291       guarantee(tmp != noreg, "Need tmp reg to encode large constants");
       
   292       load_const_optimized(tmp, roc.as_constant());
       
   293       Assembler::stbx(d, tmp, s1);
       
   294     }
       
   295   } else {
       
   296     if (s1 == noreg)
       
   297       Assembler::stb(d, 0, roc.as_register());
       
   298     else
       
   299       Assembler::stbx(d, roc.as_register(), s1);
       
   300   }
       
   301 }
       
   302 
       
   303 void Assembler::add(Register d, RegisterOrConstant roc, Register s1) {
       
   304   if (roc.is_constant()) {
       
   305     intptr_t c = roc.as_constant();
       
   306     assert(is_simm(c, 16), "too big");
       
   307     addi(d, s1, (int)c);
       
   308   }
       
   309   else add(d, roc.as_register(), s1);
       
   310 }
       
   311 
       
   312 void Assembler::subf(Register d, RegisterOrConstant roc, Register s1) {
       
   313   if (roc.is_constant()) {
       
   314     intptr_t c = roc.as_constant();
       
   315     assert(is_simm(-c, 16), "too big");
       
   316     addi(d, s1, (int)-c);
       
   317   }
       
   318   else subf(d, roc.as_register(), s1);
       
   319 }
       
   320 
       
   321 void Assembler::cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1) {
       
   322   if (roc.is_constant()) {
       
   323     intptr_t c = roc.as_constant();
       
   324     assert(is_simm(c, 16), "too big");
       
   325     cmpdi(d, s1, (int)c);
       
   326   }
       
   327   else cmpd(d, roc.as_register(), s1);
       
   328 }
       
   329 
       
   330 // Load a 64 bit constant. Patchable.
       
   331 void Assembler::load_const(Register d, long x, Register tmp) {
       
   332   // 64-bit value: x = xa xb xc xd
       
   333   int xa = (x >> 48) & 0xffff;
       
   334   int xb = (x >> 32) & 0xffff;
       
   335   int xc = (x >> 16) & 0xffff;
       
   336   int xd = (x >>  0) & 0xffff;
       
   337   if (tmp == noreg) {
       
   338     Assembler::lis( d, (int)(short)xa);
       
   339     Assembler::ori( d, d, (unsigned int)xb);
       
   340     Assembler::sldi(d, d, 32);
       
   341     Assembler::oris(d, d, (unsigned int)xc);
       
   342     Assembler::ori( d, d, (unsigned int)xd);
       
   343   } else {
       
   344     // exploit instruction level parallelism if we have a tmp register
       
   345     assert_different_registers(d, tmp);
       
   346     Assembler::lis(tmp, (int)(short)xa);
       
   347     Assembler::lis(d, (int)(short)xc);
       
   348     Assembler::ori(tmp, tmp, (unsigned int)xb);
       
   349     Assembler::ori(d, d, (unsigned int)xd);
       
   350     Assembler::insrdi(d, tmp, 32, 0);
       
   351   }
       
   352 }
       
   353 
       
   354 // Load a 64 bit constant, optimized, not identifyable.
       
   355 // Tmp can be used to increase ILP. Set return_simm16_rest=true to get a
       
   356 // 16 bit immediate offset.
       
   357 int Assembler::load_const_optimized(Register d, long x, Register tmp, bool return_simm16_rest) {
       
   358   // Avoid accidentally trying to use R0 for indexed addressing.
       
   359   assert(d != R0, "R0 not allowed");
       
   360   assert_different_registers(d, tmp);
       
   361 
       
   362   short xa, xb, xc, xd; // Four 16-bit chunks of const.
       
   363   long rem = x;         // Remaining part of const.
       
   364 
       
   365   xd = rem & 0xFFFF;    // Lowest 16-bit chunk.
       
   366   rem = (rem >> 16) + ((unsigned short)xd >> 15); // Compensation for sign extend.
       
   367 
       
   368   if (rem == 0) { // opt 1: simm16
       
   369     li(d, xd);
       
   370     return 0;
       
   371   }
       
   372 
       
   373   xc = rem & 0xFFFF; // Next 16-bit chunk.
       
   374   rem = (rem >> 16) + ((unsigned short)xc >> 15); // Compensation for sign extend.
       
   375 
       
   376   if (rem == 0) { // opt 2: simm32
       
   377     lis(d, xc);
       
   378   } else { // High 32 bits needed.
       
   379 
       
   380     if (tmp != noreg) { // opt 3: We have a temp reg.
       
   381       // No carry propagation between xc and higher chunks here (use logical instructions).
       
   382       xa = (x >> 48) & 0xffff;
       
   383       xb = (x >> 32) & 0xffff; // No sign compensation, we use lis+ori or li to allow usage of R0.
       
   384       bool load_xa = (xa != 0) || (xb < 0);
       
   385       bool return_xd = false;
       
   386 
       
   387       if (load_xa) lis(tmp, xa);
       
   388       if (xc) lis(d, xc);
       
   389       if (load_xa) {
       
   390         if (xb) ori(tmp, tmp, xb); // No addi, we support tmp == R0.
       
   391       } else {
       
   392         li(tmp, xb); // non-negative
       
   393       }
       
   394       if (xc) {
       
   395         if (return_simm16_rest && xd >= 0) { return_xd = true; } // >= 0 to avoid carry propagation after insrdi/rldimi.
       
   396         else if (xd) { addi(d, d, xd); }
       
   397       } else {
       
   398         li(d, xd);
       
   399       }
       
   400       insrdi(d, tmp, 32, 0);
       
   401       return return_xd ? xd : 0; // non-negative
       
   402     }
       
   403 
       
   404     xb = rem & 0xFFFF; // Next 16-bit chunk.
       
   405     rem = (rem >> 16) + ((unsigned short)xb >> 15); // Compensation for sign extend.
       
   406 
       
   407     xa = rem & 0xFFFF; // Highest 16-bit chunk.
       
   408 
       
   409     // opt 4: avoid adding 0
       
   410     if (xa) { // Highest 16-bit needed?
       
   411       lis(d, xa);
       
   412       if (xb) addi(d, d, xb);
       
   413     } else {
       
   414       li(d, xb);
       
   415     }
       
   416     sldi(d, d, 32);
       
   417     if (xc) addis(d, d, xc);
       
   418   }
       
   419 
       
   420   // opt 5: Return offset to be inserted into following instruction.
       
   421   if (return_simm16_rest) return xd;
       
   422 
       
   423   if (xd) addi(d, d, xd);
       
   424   return 0;
       
   425 }
       
   426 
       
   427 #ifndef PRODUCT
       
   428 // Test of ppc assembler.
       
   429 void Assembler::test_asm() {
       
   430   // PPC 1, section 3.3.8, Fixed-Point Arithmetic Instructions
       
   431   addi(   R0,  R1,  10);
       
   432   addis(  R5,  R2,  11);
       
   433   addic_( R3,  R31, 42);
       
   434   subfic( R21, R12, 2112);
       
   435   add(    R3,  R2,  R1);
       
   436   add_(   R11, R22, R30);
       
   437   subf(   R7,  R6,  R5);
       
   438   subf_(  R8,  R9,  R4);
       
   439   addc(   R11, R12, R13);
       
   440   addc_(  R14, R14, R14);
       
   441   subfc(  R15, R16, R17);
       
   442   subfc_( R18, R20, R19);
       
   443   adde(   R20, R22, R24);
       
   444   adde_(  R29, R27, R26);
       
   445   subfe(  R28, R1,  R0);
       
   446   subfe_( R21, R11, R29);
       
   447   neg(    R21, R22);
       
   448   neg_(   R13, R23);
       
   449   mulli(  R0,  R11, -31);
       
   450   mulld(  R1,  R18, R21);
       
   451   mulld_( R2,  R17, R22);
       
   452   mullw(  R3,  R16, R23);
       
   453   mullw_( R4,  R15, R24);
       
   454   divd(   R5,  R14, R25);
       
   455   divd_(  R6,  R13, R26);
       
   456   divw(   R7,  R12, R27);
       
   457   divw_(  R8,  R11, R28);
       
   458 
       
   459   li(     R3, -4711);
       
   460 
       
   461   // PPC 1, section 3.3.9, Fixed-Point Compare Instructions
       
   462   cmpi(   CCR7,  0, R27, 4711);
       
   463   cmp(    CCR0, 1, R14, R11);
       
   464   cmpli(  CCR5,  1, R17, 45);
       
   465   cmpl(   CCR3, 0, R9,  R10);
       
   466 
       
   467   cmpwi(  CCR7,  R27, 4711);
       
   468   cmpw(   CCR0, R14, R11);
       
   469   cmplwi( CCR5,  R17, 45);
       
   470   cmplw(  CCR3, R9,  R10);
       
   471 
       
   472   cmpdi(  CCR7,  R27, 4711);
       
   473   cmpd(   CCR0, R14, R11);
       
   474   cmpldi( CCR5,  R17, 45);
       
   475   cmpld(  CCR3, R9,  R10);
       
   476 
       
   477   // PPC 1, section 3.3.11, Fixed-Point Logical Instructions
       
   478   andi_(  R4,  R5,  0xff);
       
   479   andis_( R12, R13, 0x7b51);
       
   480   ori(    R1,  R4,  13);
       
   481   oris(   R3,  R5,  177);
       
   482   xori(   R7,  R6,  51);
       
   483   xoris(  R29, R0,  1);
       
   484   andr(   R17, R21, R16);
       
   485   and_(   R3,  R5,  R15);
       
   486   orr(    R2,  R1,  R9);
       
   487   or_(    R17, R15, R11);
       
   488   xorr(   R19, R18, R10);
       
   489   xor_(   R31, R21, R11);
       
   490   nand(   R5,  R7,  R3);
       
   491   nand_(  R3,  R1,  R0);
       
   492   nor(    R2,  R3,  R5);
       
   493   nor_(   R3,  R6,  R8);
       
   494   andc(   R25, R12, R11);
       
   495   andc_(  R24, R22, R21);
       
   496   orc(    R20, R10, R12);
       
   497   orc_(   R22, R2,  R13);
       
   498 
       
   499   nop();
       
   500 
       
   501   // PPC 1, section 3.3.12, Fixed-Point Rotate and Shift Instructions
       
   502   sld(    R5,  R6,  R8);
       
   503   sld_(   R3,  R5,  R9);
       
   504   slw(    R2,  R1,  R10);
       
   505   slw_(   R6,  R26, R16);
       
   506   srd(    R16, R24, R8);
       
   507   srd_(   R21, R14, R7);
       
   508   srw(    R22, R25, R29);
       
   509   srw_(   R5,  R18, R17);
       
   510   srad(   R7,  R11, R0);
       
   511   srad_(  R9,  R13, R1);
       
   512   sraw(   R7,  R15, R2);
       
   513   sraw_(  R4,  R17, R3);
       
   514   sldi(   R3,  R18, 63);
       
   515   sldi_(  R2,  R20, 30);
       
   516   slwi(   R1,  R21, 30);
       
   517   slwi_(  R7,  R23, 8);
       
   518   srdi(   R0,  R19, 2);
       
   519   srdi_(  R12, R24, 5);
       
   520   srwi(   R13, R27, 6);
       
   521   srwi_(  R14, R29, 7);
       
   522   sradi(  R15, R30, 9);
       
   523   sradi_( R16, R31, 19);
       
   524   srawi(  R17, R31, 15);
       
   525   srawi_( R18, R31, 12);
       
   526 
       
   527   clrrdi( R3, R30, 5);
       
   528   clrldi( R9, R10, 11);
       
   529 
       
   530   rldicr( R19, R20, 13, 15);
       
   531   rldicr_(R20, R20, 16, 14);
       
   532   rldicl( R21, R21, 30, 33);
       
   533   rldicl_(R22, R1,  20, 25);
       
   534   rlwinm( R23, R2,  25, 10, 11);
       
   535   rlwinm_(R24, R3,  12, 13, 14);
       
   536 
       
   537   // PPC 1, section 3.3.2 Fixed-Point Load Instructions
       
   538   lwzx(   R3,  R5, R7);
       
   539   lwz(    R11,  0, R1);
       
   540   lwzu(   R31, -4, R11);
       
   541 
       
   542   lwax(   R3,  R5, R7);
       
   543   lwa(    R31, -4, R11);
       
   544   lhzx(   R3,  R5, R7);
       
   545   lhz(    R31, -4, R11);
       
   546   lhzu(   R31, -4, R11);
       
   547 
       
   548 
       
   549   lhax(   R3,  R5, R7);
       
   550   lha(    R31, -4, R11);
       
   551   lhau(   R11,  0, R1);
       
   552 
       
   553   lbzx(   R3,  R5, R7);
       
   554   lbz(    R31, -4, R11);
       
   555   lbzu(   R11,  0, R1);
       
   556 
       
   557   ld(     R31, -4, R11);
       
   558   ldx(    R3,  R5, R7);
       
   559   ldu(    R31, -4, R11);
       
   560 
       
   561   //  PPC 1, section 3.3.3 Fixed-Point Store Instructions
       
   562   stwx(   R3,  R5, R7);
       
   563   stw(    R31, -4, R11);
       
   564   stwu(   R11,  0, R1);
       
   565 
       
   566   sthx(   R3,  R5, R7 );
       
   567   sth(    R31, -4, R11);
       
   568   sthu(   R31, -4, R11);
       
   569 
       
   570   stbx(   R3,  R5, R7);
       
   571   stb(    R31, -4, R11);
       
   572   stbu(   R31, -4, R11);
       
   573 
       
   574   std(    R31, -4, R11);
       
   575   stdx(   R3,  R5, R7);
       
   576   stdu(   R31, -4, R11);
       
   577 
       
   578  // PPC 1, section 3.3.13 Move To/From System Register Instructions
       
   579   mtlr(   R3);
       
   580   mflr(   R3);
       
   581   mtctr(  R3);
       
   582   mfctr(  R3);
       
   583   mtcrf(  0xff, R15);
       
   584   mtcr(   R15);
       
   585   mtcrf(  0x03, R15);
       
   586   mtcr(   R15);
       
   587   mfcr(   R15);
       
   588 
       
   589  // PPC 1, section 2.4.1 Branch Instructions
       
   590   Label lbl1, lbl2, lbl3;
       
   591   bind(lbl1);
       
   592 
       
   593   b(pc());
       
   594   b(pc() - 8);
       
   595   b(lbl1);
       
   596   b(lbl2);
       
   597   b(lbl3);
       
   598 
       
   599   bl(pc() - 8);
       
   600   bl(lbl1);
       
   601   bl(lbl2);
       
   602 
       
   603   bcl(4, 10, pc() - 8);
       
   604   bcl(4, 10, lbl1);
       
   605   bcl(4, 10, lbl2);
       
   606 
       
   607   bclr( 4, 6, 0);
       
   608   bclrl(4, 6, 0);
       
   609 
       
   610   bind(lbl2);
       
   611 
       
   612   bcctr( 4, 6, 0);
       
   613   bcctrl(4, 6, 0);
       
   614 
       
   615   blt(CCR0, lbl2);
       
   616   bgt(CCR1, lbl2);
       
   617   beq(CCR2, lbl2);
       
   618   bso(CCR3, lbl2);
       
   619   bge(CCR4, lbl2);
       
   620   ble(CCR5, lbl2);
       
   621   bne(CCR6, lbl2);
       
   622   bns(CCR7, lbl2);
       
   623 
       
   624   bltl(CCR0, lbl2);
       
   625   bgtl(CCR1, lbl2);
       
   626   beql(CCR2, lbl2);
       
   627   bsol(CCR3, lbl2);
       
   628   bgel(CCR4, lbl2);
       
   629   blel(CCR5, lbl2);
       
   630   bnel(CCR6, lbl2);
       
   631   bnsl(CCR7, lbl2);
       
   632   blr();
       
   633 
       
   634   sync();
       
   635   icbi( R1, R2);
       
   636   dcbst(R2, R3);
       
   637 
       
   638   // FLOATING POINT instructions ppc.
       
   639   // PPC 1, section 4.6.2 Floating-Point Load Instructions
       
   640   lfs( F1, -11, R3);
       
   641   lfsu(F2, 123, R4);
       
   642   lfsx(F3, R5,  R6);
       
   643   lfd( F4, 456, R7);
       
   644   lfdu(F5, 789, R8);
       
   645   lfdx(F6, R10, R11);
       
   646 
       
   647   // PPC 1, section 4.6.3 Floating-Point Store Instructions
       
   648   stfs(  F7,  876, R12);
       
   649   stfsu( F8,  543, R13);
       
   650   stfsx( F9,  R14, R15);
       
   651   stfd(  F10, 210, R16);
       
   652   stfdu( F11, 111, R17);
       
   653   stfdx( F12, R18, R19);
       
   654 
       
   655   // PPC 1, section 4.6.4 Floating-Point Move Instructions
       
   656   fmr(   F13, F14);
       
   657   fmr_(  F14, F15);
       
   658   fneg(  F16, F17);
       
   659   fneg_( F18, F19);
       
   660   fabs(  F20, F21);
       
   661   fabs_( F22, F23);
       
   662   fnabs( F24, F25);
       
   663   fnabs_(F26, F27);
       
   664 
       
   665   // PPC 1, section 4.6.5.1 Floating-Point Elementary Arithmetic
       
   666   // Instructions
       
   667   fadd(  F28, F29, F30);
       
   668   fadd_( F31, F0,  F1);
       
   669   fadds( F2,  F3,  F4);
       
   670   fadds_(F5,  F6,  F7);
       
   671   fsub(  F8,  F9,  F10);
       
   672   fsub_( F11, F12, F13);
       
   673   fsubs( F14, F15, F16);
       
   674   fsubs_(F17, F18, F19);
       
   675   fmul(  F20, F21, F22);
       
   676   fmul_( F23, F24, F25);
       
   677   fmuls( F26, F27, F28);
       
   678   fmuls_(F29, F30, F31);
       
   679   fdiv(  F0,  F1,  F2);
       
   680   fdiv_( F3,  F4,  F5);
       
   681   fdivs( F6,  F7,  F8);
       
   682   fdivs_(F9,  F10, F11);
       
   683 
       
   684   // PPC 1, section 4.6.6 Floating-Point Rounding and Conversion
       
   685   // Instructions
       
   686   frsp(  F12, F13);
       
   687   fctid( F14, F15);
       
   688   fctidz(F16, F17);
       
   689   fctiw( F18, F19);
       
   690   fctiwz(F20, F21);
       
   691   fcfid( F22, F23);
       
   692 
       
   693   // PPC 1, section 4.6.7 Floating-Point Compare Instructions
       
   694   fcmpu( CCR7, F24, F25);
       
   695 
       
   696   tty->print_cr("\ntest_asm disassembly (0x%lx 0x%lx):", code()->insts_begin(), code()->insts_end());
       
   697   code()->decode();
       
   698 }
       
   699 #endif // !PRODUCT