src/hotspot/cpu/s390/copy_s390.hpp
author coleenp
Thu, 10 Jan 2019 15:13:51 -0500
changeset 53244 9807daeb47c4
parent 48956 400f4d17a3c6
permissions -rw-r--r--
8216167: Update include guards to reflect correct directories Summary: Use script and some manual fixup to fix directores names in include guards. Reviewed-by: lfoltan, eosterlund, kbarrett
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     1
/*
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 48956
diff changeset
     2
 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     3
 * Copyright (c) 2016 SAP SE. All rights reserved.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     5
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     6
 * This code is free software; you can redistribute it and/or modify it
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     7
 * under the terms of the GNU General Public License version 2 only, as
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     8
 * published by the Free Software Foundation.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     9
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    14
 * accompanied this code).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    15
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    19
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    22
 * questions.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    23
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    24
 */
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    25
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    26
// Major contributions by LS
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    27
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 48956
diff changeset
    28
#ifndef CPU_S390_COPY_S390_HPP
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 48956
diff changeset
    29
#define CPU_S390_COPY_S390_HPP
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    30
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    31
// Inline functions for memory copy and fill.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    32
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    33
// HeapWordSize (the size of class HeapWord) is 8 Bytes (the size of a
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    34
// pointer variable), since we always run the _LP64 model. As a consequence,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    35
// HeapWord* memory ranges are always assumed to be doubleword-aligned,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    36
// having a size which is an integer multiple of HeapWordSize.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    37
//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    38
// Dealing only with doubleword-aligned doubleword units has important
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    39
// positive performance and data access consequences. Many of the move
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    40
// instructions perform particularly well under these circumstances.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    41
// Data access is "doubleword-concurrent", except for MVC and XC.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    42
// Furthermore, data access can be forced to be sequential (MVCL and MVCLE)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    43
// by use of the special padding byte 0xb1, where required. For copying,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    44
// we use padding byte 0xb0 to prevent the D-cache from being polluted.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    45
//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    46
// On z/Architecture, gcc optimizes memcpy into a series of MVC instructions.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    47
// This is optimal, even if just one HeapWord is copied. However, MVC
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    48
// copying is not atomic, i.e. not "doubleword concurrent" by definition.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    49
//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    50
// If the -mmvcle compiler option is specified, memcpy translates into
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    51
// code such that the entire memory range is copied or preset with just
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    52
// one MVCLE instruction.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    53
//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    54
// *to = *from is transformed into a MVC instruction already with -O1.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    55
// Thus, for atomic copy operations, (inline) assembler code is required
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    56
// to guarantee atomic data accesses.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    57
//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    58
// For large (len >= MVCLEThreshold) chunks of memory, we exploit
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    59
// special H/W support of z/Architecture:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    60
// 1) copy short piece of memory to page-align address(es)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    61
// 2) copy largest part (all contained full pages) of memory using mvcle instruction.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    62
//    z/Architecture processors have special H/W support for page-aligned storage
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    63
//    where len is an int multiple of page size. In that case, up to 4 cache lines are
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    64
//    processed in parallel and L1 cache is not polluted.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    65
// 3) copy the remaining piece of memory.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    66
//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    67
//  Measurement classifications:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    68
//  very rare - <=     10.000 calls AND <=     1.000 usec elapsed
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    69
//       rare - <=    100.000 calls AND <=    10.000 usec elapsed
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    70
//       some - <=  1.000.000 calls AND <=   100.000 usec elapsed
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    71
//       freq - <= 10.000.000 calls AND <= 1.000.000 usec elapsed
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    72
//  very freq - >  10.000.000 calls OR  >  1.000.000 usec elapsed
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    73
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    74
#undef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    75
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
    76
static void copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    77
  if (from > to) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    78
    while (count-- > 0) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    79
      // Copy forwards
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    80
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    81
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    82
  } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    83
    from += count - 1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    84
    to   += count - 1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    85
    while (count-- > 0) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    86
      // Copy backwards
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    87
      *to-- = *from--;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    88
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    89
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    90
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    91
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
    92
static void copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    93
  if (from > to) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    94
    while (count-- > 0) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    95
      // Copy forwards
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    96
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    97
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    98
  } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    99
    from += count - 1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   100
    to   += count - 1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   101
    while (count-- > 0) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   102
      // Copy backwards
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   103
      *to-- = *from--;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   104
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   105
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   106
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   107
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   108
static bool has_destructive_overlap(const char* from, char* to, size_t byte_count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   109
  return (from < to) && ((to-from) < (ptrdiff_t)byte_count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   110
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   111
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   112
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   113
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   114
  //--------------------------------------------------------------
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   115
  // Atomic copying. Atomicity is given by the minimum of source
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   116
  // and target alignment. Refer to mail comm with Tim Slegel/IBM.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   117
  // Only usable for disjoint source and target.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   118
  //--------------------------------------------------------------
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   119
  #define MOVE8_ATOMIC_4(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   120
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   121
    unsigned long fromaddr;                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   122
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   123
      "LG      %[toaddr],%[to]     \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   124
      "LG      %[fromaddr],%[from] \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   125
      "MVC     0(32,%[toaddr]),0(%[fromaddr]) \n\t" /* move data */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   126
      : [to]       "+Q"  (_to)          /* outputs   */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   127
      , [from]     "+Q"  (_from)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   128
      , [toaddr]   "=a"  (toaddr)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   129
      , [fromaddr] "=a"  (fromaddr)                              \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   130
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   131
      : "cc"                            /* clobbered */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   132
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   133
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   134
  #define MOVE8_ATOMIC_3(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   135
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   136
    unsigned long fromaddr;                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   137
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   138
      "LG      %[toaddr],%[to]     \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   139
      "LG      %[fromaddr],%[from] \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   140
      "MVC     0(24,%[toaddr]),0(%[fromaddr]) \n\t" /* move data */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   141
      : [to]       "+Q"  (_to)          /* outputs   */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   142
      , [from]     "+Q"  (_from)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   143
      , [toaddr]   "=a"  (toaddr)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   144
      , [fromaddr] "=a"  (fromaddr)                              \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   145
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   146
      : "cc"                            /* clobbered */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   147
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   148
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   149
  #define MOVE8_ATOMIC_2(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   150
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   151
    unsigned long fromaddr;                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   152
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   153
      "LG      %[toaddr],%[to]     \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   154
      "LG      %[fromaddr],%[from] \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   155
      "MVC     0(16,%[toaddr]),0(%[fromaddr]) \n\t" /* move data */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   156
      : [to]       "+Q"  (_to)          /* outputs   */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   157
      , [from]     "+Q"  (_from)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   158
      , [toaddr]   "=a"  (toaddr)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   159
      , [fromaddr] "=a"  (fromaddr)                              \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   160
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   161
      : "cc"                            /* clobbered */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   162
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   163
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   164
  #define MOVE8_ATOMIC_1(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   165
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   166
    unsigned long fromaddr;                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   167
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   168
      "LG      %[toaddr],%[to]     \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   169
      "LG      %[fromaddr],%[from] \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   170
      "MVC     0(8,%[toaddr]),0(%[fromaddr]) \n\t"  /* move data */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   171
      : [to]       "+Q"  (_to)          /* outputs   */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   172
      , [from]     "+Q"  (_from)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   173
      , [toaddr]   "=a"  (toaddr)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   174
      , [fromaddr] "=a"  (fromaddr)                              \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   175
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   176
      : "cc"                            /* clobbered */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   177
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   178
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   179
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   180
  //--------------------------------------------------------------
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   181
  // Atomic copying of 8-byte entities.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   182
  // Conjoint/disjoint property does not matter. Entities are first
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   183
  // loaded and then stored.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   184
  // _to and _from must be 8-byte aligned.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   185
  //--------------------------------------------------------------
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   186
  #define COPY8_ATOMIC_4(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   187
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   188
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   189
      "LG      3,%[from]        \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   190
      "LG      %[toaddr],%[to]  \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   191
      "LMG     0,3,0(3)         \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   192
      "STMG    0,3,0(%[toaddr]) \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   193
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   194
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   195
      , [toaddr] "=a"  (toaddr)       /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   196
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   197
      : "cc",  "r0", "r1", "r2", "r3" /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   198
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   199
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   200
  #define COPY8_ATOMIC_3(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   201
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   202
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   203
      "LG      2,%[from]        \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   204
      "LG      %[toaddr],%[to]  \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   205
      "LMG     0,2,0(2)         \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   206
      "STMG    0,2,0(%[toaddr]) \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   207
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   208
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   209
      , [toaddr] "=a"  (toaddr)       /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   210
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   211
      : "cc",  "r0", "r1", "r2"       /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   212
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   213
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   214
  #define COPY8_ATOMIC_2(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   215
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   216
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   217
      "LG      1,%[from]        \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   218
      "LG      %[toaddr],%[to]  \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   219
      "LMG     0,1,0(1)         \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   220
      "STMG    0,1,0(%[toaddr]) \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   221
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   222
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   223
      , [toaddr] "=a"  (toaddr)       /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   224
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   225
      : "cc",  "r0", "r1"             /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   226
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   227
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   228
  #define COPY8_ATOMIC_1(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   229
    unsigned long addr;                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   230
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   231
      "LG      %[addr],%[from]  \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   232
      "LG      0,0(0,%[addr])   \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   233
      "LG      %[addr],%[to]    \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   234
      "STG     0,0(0,%[addr])   \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   235
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   236
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   237
      , [addr]   "=a"  (addr)         /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   238
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   239
      : "cc",  "r0"                   /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   240
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   241
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   242
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   243
  //--------------------------------------------------------------
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   244
  // Atomic copying of 4-byte entities.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   245
  // Exactly 4 (four) entities are copied.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   246
  // Conjoint/disjoint property does not matter. Entities are first
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   247
  // loaded and then stored.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   248
  // _to and _from must be 4-byte aligned.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   249
  //--------------------------------------------------------------
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   250
  #define COPY4_ATOMIC_4(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   251
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   252
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   253
      "LG      3,%[from]        \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   254
      "LG      %[toaddr],%[to]  \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   255
      "LM      0,3,0(3)         \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   256
      "STM     0,3,0(%[toaddr]) \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   257
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   258
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   259
      , [toaddr] "=a"  (toaddr)       /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   260
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   261
      : "cc",  "r0", "r1", "r2", "r3" /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   262
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   263
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   264
  #define COPY4_ATOMIC_3(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   265
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   266
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   267
      "LG      2,%[from]        \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   268
      "LG      %[toaddr],%[to]  \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   269
      "LM      0,2,0(2)         \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   270
      "STM     0,2,0(%[toaddr]) \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   271
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   272
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   273
      , [toaddr] "=a"  (toaddr)       /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   274
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   275
      : "cc",  "r0", "r1", "r2"       /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   276
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   277
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   278
  #define COPY4_ATOMIC_2(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   279
    unsigned long toaddr;                                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   280
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   281
      "LG      1,%[from]        \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   282
      "LG      %[toaddr],%[to]  \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   283
      "LM      0,1,0(1)         \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   284
      "STM     0,1,0(%[toaddr]) \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   285
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   286
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   287
      , [toaddr] "=a"  (toaddr)       /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   288
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   289
      : "cc",  "r0", "r1"             /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   290
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   291
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   292
  #define COPY4_ATOMIC_1(_to,_from) {                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   293
    unsigned long addr;                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   294
    asm(                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   295
      "LG      %[addr],%[from]  \n\t" /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   296
      "L       0,0(0,%[addr])   \n\t" /* load data            */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   297
      "LG      %[addr],%[to]    \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   298
      "ST      0,0(0,%[addr])   \n\t" /* store data           */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   299
      : [to]     "+Q"  (_to)          /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   300
      , [from]   "+Q"  (_from)        /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   301
      , [addr]   "=a"  (addr)         /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   302
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   303
      : "cc",  "r0"                   /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   304
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   305
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   306
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   307
#if 0  // Waiting for gcc to support EXRL.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   308
  #define MVC_MEMCOPY(_to,_from,_len)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   309
    if (VM_Version::has_ExecuteExtensions()) {                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   310
      asm("\t"                                                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   311
      "    LAY     1,-1(0,%[len])      \n\t" /* decr for MVC  */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   312
      "    EXRL    1,1f                \n\t" /* execute MVC instr */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   313
      "    BRC     15,2f               \n\t" /* skip template */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   314
      "1:  MVC     0(%[len],%[to]),0(%[from]) \n\t"                  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   315
      "2:  BCR     0,0                 \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   316
      : [to]   "+Q"  (_to)             /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   317
      , [from] "+Q"  (_from)           /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   318
      : [len]  "r"   (_len)            /* inputs    */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   319
      : "cc",  "r1"                    /* clobbered */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   320
      );                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   321
    } else {                                                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   322
      asm("\t"                                                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   323
      "    LARL    2,3f                \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   324
      "    LAY     1,-1(0,%[len])      \n\t" /* decr for MVC  */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   325
      "    EX      1,0(2)              \n\t" /* execute MVC instr */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   326
      "    BRC     15,4f               \n\t" /* skip template */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   327
      "3:  MVC     0(%[len],%[to]),0(%[from])  \n\t"                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   328
      "4:  BCR     0,0                 \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   329
      : [to]   "+Q"  (_to)             /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   330
      , [from] "+Q"  (_from)           /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   331
      : [len]  "r"   (_len)            /* inputs    */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   332
      : "cc",  "r1", "r2"              /* clobbered */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   333
      );                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   334
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   335
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   336
  #define MVC_MEMCOPY(_to,_from,_len)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   337
  { unsigned long toaddr;   unsigned long tolen;                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   338
    unsigned long fromaddr; unsigned long target;                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   339
      asm("\t"                                                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   340
      "    LTGR    %[tolen],%[len]     \n\t" /* decr for MVC  */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   341
      "    BRC     8,2f                \n\t" /* do nothing for l=0*/ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   342
      "    AGHI    %[tolen],-1         \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   343
      "    LG      %[toaddr],%[to]     \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   344
      "    LG      %[fromaddr],%[from] \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   345
      "    LARL    %[target],1f        \n\t" /* addr of MVC instr */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   346
      "    EX      %[tolen],0(%[target])         \n\t" /* execute MVC instr */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   347
      "    BRC     15,2f                         \n\t" /* skip template */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   348
      "1:  MVC     0(1,%[toaddr]),0(%[fromaddr]) \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   349
      "2:  BCR     0,0                 \n\t" /* nop a branch target*/\
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   350
      : [to]       "+Q"  (_to)         /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   351
      , [from]     "+Q"  (_from)                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   352
      , [tolen]    "=a"  (tolen)                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   353
      , [toaddr]   "=a"  (toaddr)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   354
      , [fromaddr] "=a"  (fromaddr)                                  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   355
      , [target]   "=a"  (target)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   356
      : [len]       "r"  (_len)        /* inputs    */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   357
      : "cc"                           /* clobbered */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   358
      );                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   359
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   360
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   361
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   362
  #if 0  // code snippet to be used for debugging
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   363
      /* ASSERT code BEGIN */                                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   364
      "    LARL    %[len],5f       \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   365
      "    LARL    %[mta],4f       \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   366
      "    SLGR    %[len],%[mta]   \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   367
      "    CGHI    %[len],16       \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   368
      "    BRC     7,9f            \n\t"      /* block size !=  16 */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   369
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   370
      "    LARL    %[len],1f       \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   371
      "    SLGR    %[len],%[mta]   \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   372
      "    CGHI    %[len],256      \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   373
      "    BRC     7,9f            \n\t"      /* list len   != 256 */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   374
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   375
      "    LGR     0,0             \n\t"      /* artificial SIGILL */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   376
      "9:  BRC     7,-2            \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   377
      "    LARL    %[mta],1f       \n\t"      /* restore MVC table begin */  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   378
      /* ASSERT code END   */
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   379
  #endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   380
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   381
  // Optimized copying for data less than 4k
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   382
  // - no destructive overlap
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   383
  // - 0 <= _n_bytes <= 4096
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   384
  // This macro needs to be gcc-compiled with -march=z990. Otherwise, the
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   385
  // LAY instruction is not available.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   386
  #define MVC_MULTI(_to,_from,_n_bytes)                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   387
  { unsigned long toaddr;                                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   388
    unsigned long fromaddr;                                                  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   389
    unsigned long movetable;                                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   390
    unsigned long len;                                                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   391
      asm("\t"                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   392
      "    LTGFR   %[len],%[nby]   \n\t"                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   393
      "    LG      %[ta],%[to]     \n\t"      /* address of to area   */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   394
      "    BRC     8,1f            \n\t"      /* nothing to copy   */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   395
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   396
      "    NILL    %[nby],255      \n\t"      /* # bytes mod 256      */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   397
      "    LG      %[fa],%[from]   \n\t"      /* address of from area */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   398
      "    BRC     8,3f            \n\t"      /* no rest, skip copying */    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   399
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   400
      "    LARL    %[mta],2f       \n\t"      /* MVC template addr */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   401
      "    AHI     %[nby],-1       \n\t"      /* adjust for EX MVC  */       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   402
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   403
      "    EX      %[nby],0(%[mta]) \n\t"     /* only rightmost */           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   404
                                              /* 8 bits of nby used */       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   405
      /* Since nby is <= 4096 on entry to this code, we do need */           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   406
      /* no zero extension before using it in addr calc.        */           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   407
      "    LA      %[fa],1(%[nby],%[fa]) \n\t"/* adjust from addr */         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   408
      "    LA      %[ta],1(%[nby],%[ta]) \n\t"/* adjust to   addr */         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   409
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   410
      "3:  SRAG    %[nby],%[len],8 \n\t"      /* # cache lines     */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   411
      "    LARL    %[mta],1f       \n\t"      /* MVC table begin   */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   412
      "    BRC     8,1f            \n\t"      /* nothing to copy   */        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   413
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   414
      /* Insert ASSERT code here if required. */                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   415
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   416
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   417
      "    LNGFR   %[nby],%[nby]   \n\t"      /* negative offset into     */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   418
      "    SLLG    %[nby],%[nby],4 \n\t"      /* MVC table 16-byte blocks */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   419
      "    BC      15,0(%[nby],%[mta]) \n\t"  /* branch to block #ncl  */    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   420
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   421
      "2:  MVC     0(1,%[ta]),0(%[fa]) \n\t"  /* MVC template */             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   422
                                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   423
      "4:  MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 4096 == l        */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   424
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   425
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   426
      "5:  MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 3840 <= l < 4096 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   427
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   428
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   429
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 3548 <= l < 3328 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   430
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   431
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   432
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 3328 <= l < 3328 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   433
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   434
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   435
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 3072 <= l < 3328 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   436
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   437
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   438
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 2816 <= l < 3072 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   439
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   440
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   441
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 2560 <= l < 2816 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   442
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   443
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   444
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 2304 <= l < 2560 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   445
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   446
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   447
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 2048 <= l < 2304 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   448
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   449
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   450
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 1792 <= l < 2048 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   451
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   452
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   453
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 1536 <= l < 1792 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   454
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   455
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   456
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 1280 <= l < 1536 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   457
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   458
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   459
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /* 1024 <= l < 1280 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   460
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   461
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   462
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /*  768 <= l < 1024 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   463
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   464
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   465
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /*  512 <= l <  768 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   466
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   467
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   468
      "    MVC     0(256,%[ta]),0(%[fa])   \n\t" /*  256 <= l <  512 */      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   469
      "    LAY     %[ta],256(0,%[ta])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   470
      "    LA      %[fa],256(0,%[fa])      \n\t"                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   471
      "1:  BCR     0,0                     \n\t" /* nop as branch target */  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   472
      : [to]       "+Q"  (_to)          /* outputs   */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   473
      , [from]     "+Q"  (_from)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   474
      , [ta]       "=a"  (toaddr)                                \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   475
      , [fa]       "=a"  (fromaddr)                              \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   476
      , [mta]      "=a"  (movetable)                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   477
      , [nby]      "+a"  (_n_bytes)                              \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   478
      , [len]      "=a"  (len)                                   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   479
      :                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   480
      : "cc"                            /* clobbered */          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   481
    );                                                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   482
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   483
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   484
  #define MVCLE_MEMCOPY(_to,_from,_len)                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   485
    asm(                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   486
      "    LG      0,%[to]     \n\t"   /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   487
      "    LG      2,%[from]   \n\t"   /* address of from area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   488
      "    LGR     1,%[len]    \n\t"   /* len of to area       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   489
      "    LGR     3,%[len]    \n\t"   /* len of from area     */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   490
      "1:  MVCLE   0,2,176     \n\t"   /* copy storage, bypass cache (0xb0) */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   491
      "    BRC     1,1b        \n\t"   /* retry if interrupted */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   492
      : [to]   "+Q"  (_to)             /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   493
      , [from] "+Q"  (_from)           /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   494
      : [len]  "r"   (_len)            /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   495
      : "cc",  "r0", "r1", "r2", "r3"  /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   496
    );
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   497
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   498
  #define MVCLE_MEMINIT(_to,_val,_len)                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   499
    asm(                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   500
      "    LG      0,%[to]       \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   501
      "    LGR     1,%[len]      \n\t" /* len of to area       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   502
      "    XGR     3,3           \n\t" /* from area len = 0    */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   503
      "1:  MVCLE   0,2,0(%[val]) \n\t" /* init storage         */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   504
      "    BRC     1,1b          \n\t" /* retry if interrupted */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   505
      : [to]   "+Q"  (_to)             /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   506
      : [len]  "r"   (_len)            /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   507
      , [val]  "r"   (_val)            /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   508
      : "cc",  "r0", "r1", "r3"        /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   509
    );
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   510
  #define MVCLE_MEMZERO(_to,_len)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   511
    asm(                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   512
      "    LG      0,%[to]       \n\t" /* address of to area   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   513
      "    LGR     1,%[len]      \n\t" /* len of to area       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   514
      "    XGR     3,3           \n\t" /* from area len = 0    */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   515
      "1:  MVCLE   0,2,0         \n\t" /* clear storage        */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   516
      "    BRC     1,1b          \n\t" /* retry if interrupted */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   517
      : [to]   "+Q"  (_to)             /* outputs   */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   518
      : [len]  "r"   (_len)            /* inputs    */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   519
      : "cc",  "r0", "r1", "r3"        /* clobbered */            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   520
    );
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   521
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   522
  // Clear a stretch of memory, 0 <= _len <= 256.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   523
  // There is no alignment prereq.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   524
  // There is no test for len out of range specified above.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   525
  #define XC_MEMZERO_256(_to,_len)                                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   526
{ unsigned long toaddr;   unsigned long tolen;                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   527
  unsigned long target;                                            \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   528
    asm("\t"                                                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   529
    "    LTGR    %[tolen],%[len]     \n\t" /* decr for MVC  */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   530
    "    BRC     8,2f                \n\t" /* do nothing for l=0*/ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   531
    "    AGHI    %[tolen],-1         \n\t" /* adjust for EX XC  */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   532
    "    LARL    %[target],1f        \n\t" /* addr of XC instr  */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   533
    "    LG      %[toaddr],%[to]     \n\t" /* addr of data area */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   534
    "    EX      %[tolen],0(%[target])       \n\t" /* execute MVC instr */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   535
    "    BRC     15,2f                       \n\t" /* skip template */     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   536
    "1:  XC      0(1,%[toaddr]),0(%[toaddr]) \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   537
    "2:  BCR     0,0                 \n\t" /* nop a branch target*/\
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   538
    : [to]       "+Q"  (_to)         /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   539
    , [tolen]    "=a"  (tolen)                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   540
    , [toaddr]   "=a"  (toaddr)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   541
    , [target]   "=a"  (target)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   542
    : [len]       "r"  (_len)        /* inputs    */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   543
    : "cc"                           /* clobbered */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   544
    );                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   545
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   546
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   547
  // Clear a stretch of memory, 256 < _len.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   548
  // XC_MEMZERO_256 may be used to clear shorter areas.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   549
  //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   550
  // The code
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   551
  // - first zeroes a few bytes to align on a HeapWord.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   552
  //   This step is currently inactive because all calls seem
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   553
  //   to have their data aligned on HeapWord boundaries.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   554
  // - then zeroes a few HeapWords to align on a cache line.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   555
  // - then zeroes entire cache lines in a loop.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   556
  // - then zeroes the remaining (partial) cache line.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   557
#if 1
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   558
  #define XC_MEMZERO_ANY(_to,_len)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   559
{ unsigned long toaddr;   unsigned long tolen;                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   560
  unsigned long len8;     unsigned long len256;                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   561
  unsigned long target;   unsigned long lenx;                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   562
    asm("\t"                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   563
    "    LTGR    %[tolen],%[len]      \n\t" /*                   */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   564
    "    BRC     8,2f                 \n\t" /* do nothing for l=0*/   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   565
    "    LG      %[toaddr],%[to]      \n\t" /* addr of data area */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   566
    "    LARL    %[target],1f         \n\t" /* addr of XC instr  */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   567
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   568
    "    LCGR    %[len256],%[toaddr]  \n\t" /* cache line alignment */\
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   569
    "    NILL    %[len256],0xff       \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   570
    "    BRC     8,4f                 \n\t" /* already aligned     */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   571
    "    NILH    %[len256],0x00       \n\t" /* zero extend         */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   572
    "    LLGFR   %[len256],%[len256]  \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   573
    "    LAY     %[lenx],-1(,%[len256]) \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   574
    "    EX      %[lenx],0(%[target]) \n\t" /* execute MVC instr   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   575
    "    LA      %[toaddr],0(%[len256],%[toaddr]) \n\t"               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   576
    "    SGR     %[tolen],%[len256]   \n\t" /* adjust len          */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   577
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   578
    "4:  SRAG    %[lenx],%[tolen],8   \n\t" /* # cache lines       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   579
    "    BRC     8,6f                 \n\t" /* no full cache lines */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   580
    "5:  XC      0(256,%[toaddr]),0(%[toaddr]) \n\t"                  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   581
    "    LA      %[toaddr],256(,%[toaddr]) \n\t"                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   582
    "    BRCTG   %[lenx],5b           \n\t" /* iterate             */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   583
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   584
    "6:  NILL    %[tolen],0xff        \n\t" /* leftover bytes      */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   585
    "    BRC     8,2f                 \n\t" /* done if none        */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   586
    "    LAY     %[lenx],-1(,%[tolen]) \n\t"                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   587
    "    EX      %[lenx],0(%[target]) \n\t" /* execute MVC instr   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   588
    "    BRC     15,2f                \n\t" /* skip template       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   589
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   590
    "1:  XC      0(1,%[toaddr]),0(%[toaddr]) \n\t"                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   591
    "2:  BCR     0,0                  \n\t" /* nop a branch target */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   592
    : [to]       "+Q"  (_to)         /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   593
    , [lenx]     "=a"  (lenx)                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   594
    , [len256]   "=a"  (len256)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   595
    , [tolen]    "=a"  (tolen)                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   596
    , [toaddr]   "=a"  (toaddr)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   597
    , [target]   "=a"  (target)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   598
    : [len]       "r"  (_len)        /* inputs    */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   599
    : "cc"                           /* clobbered */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   600
    );                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   601
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   602
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   603
  #define XC_MEMZERO_ANY(_to,_len)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   604
{ unsigned long toaddr;   unsigned long tolen;                        \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   605
  unsigned long len8;     unsigned long len256;                       \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   606
  unsigned long target;   unsigned long lenx;                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   607
    asm("\t"                                                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   608
    "    LTGR    %[tolen],%[len]      \n\t" /*                   */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   609
    "    BRC     8,2f                 \n\t" /* do nothing for l=0*/   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   610
    "    LG      %[toaddr],%[to]      \n\t" /* addr of data area */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   611
    "    LARL    %[target],1f         \n\t" /* addr of XC instr  */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   612
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   613
    "    LCGR    %[len8],%[toaddr]    \n\t" /* HeapWord alignment  */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   614
    "    NILL    %[len8],0x07         \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   615
    "    BRC     8,3f                 \n\t" /* already aligned     */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   616
    "    NILH    %[len8],0x00         \n\t" /* zero extend         */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   617
    "    LLGFR   %[len8],%[len8]      \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   618
    "    LAY     %[lenx],-1(,%[len8]) \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   619
    "    EX      %[lenx],0(%[target]) \n\t" /* execute MVC instr */   \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   620
    "    LA      %[toaddr],0(%[len8],%[toaddr]) \n\t"                 \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   621
    "    SGR     %[tolen],%[len8]     \n\t" /* adjust len          */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   622
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   623
    "3:  LCGR    %[len256],%[toaddr]  \n\t" /* cache line alignment */\
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   624
    "    NILL    %[len256],0xff       \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   625
    "    BRC     8,4f                 \n\t" /* already aligned     */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   626
    "    NILH    %[len256],0x00       \n\t" /* zero extend         */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   627
    "    LLGFR   %[len256],%[len256]  \n\t"                           \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   628
    "    LAY     %[lenx],-1(,%[len256]) \n\t"                         \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   629
    "    EX      %[lenx],0(%[target]) \n\t" /* execute MVC instr   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   630
    "    LA      %[toaddr],0(%[len256],%[toaddr]) \n\t"               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   631
    "    SGR     %[tolen],%[len256]   \n\t" /* adjust len          */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   632
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   633
    "4:  SRAG    %[lenx],%[tolen],8   \n\t" /* # cache lines       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   634
    "    BRC     8,6f                 \n\t" /* no full cache lines */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   635
    "5:  XC      0(256,%[toaddr]),0(%[toaddr]) \n\t"                  \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   636
    "    LA      %[toaddr],256(,%[toaddr]) \n\t"                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   637
    "    BRCTG   %[lenx],5b           \n\t" /* iterate             */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   638
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   639
    "6:  NILL    %[tolen],0xff        \n\t" /* leftover bytes      */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   640
    "    BRC     8,2f                 \n\t" /* done if none        */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   641
    "    LAY     %[lenx],-1(,%[tolen]) \n\t"                          \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   642
    "    EX      %[lenx],0(%[target]) \n\t" /* execute MVC instr   */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   643
    "    BRC     15,2f                \n\t" /* skip template       */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   644
    " "                                                               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   645
    "1:  XC      0(1,%[toaddr]),0(%[toaddr]) \n\t"                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   646
    "2:  BCR     0,0                  \n\t" /* nop a branch target */ \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   647
    : [to]       "+Q"  (_to)         /* outputs   */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   648
    , [lenx]     "=a"  (lenx)                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   649
    , [len8]     "=a"  (len8)                                      \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   650
    , [len256]   "=a"  (len256)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   651
    , [tolen]    "=a"  (tolen)                                     \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   652
    , [toaddr]   "=a"  (toaddr)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   653
    , [target]   "=a"  (target)                                    \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   654
    : [len]       "r"  (_len)        /* inputs    */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   655
    : "cc"                           /* clobbered */               \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   656
    );                                                             \
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   657
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   658
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   659
#endif // USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   660
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   661
//*************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   662
//   D I S J O I N T   C O P Y I N G   //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   663
//*************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   664
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   665
static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   666
  // JVM2008: very frequent, some tests frequent.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   667
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   668
  // Copy HeapWord (=DW) aligned storage. Use MVCLE in inline-asm code.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   669
  // MVCLE guarantees DW concurrent (i.e. atomic) accesses if both the addresses of the operands
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   670
  // are DW aligned and the length is an integer multiple of a DW. Should always be true here.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   671
  //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   672
  // No special exploit needed. H/W discovers suitable situations itself.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   673
  //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   674
  // For large chunks of memory, exploit special H/W support of z/Architecture:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   675
  // 1) copy short piece of memory to page-align address(es)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   676
  // 2) copy largest part (all contained full pages) of memory using mvcle instruction.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   677
  //    z/Architecture processors have special H/W support for page-aligned storage
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   678
  //    where len is an int multiple of page size. In that case, up to 4 cache lines are
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   679
  //    processed in parallel and L1 cache is not polluted.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   680
  // 3) copy the remaining piece of memory.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   681
  //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   682
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   683
  jbyte* to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   684
  jbyte* from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   685
  size_t len_bytes  = count*HeapWordSize;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   686
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   687
  // Optimized copying for data less than 4k
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   688
  switch (count) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   689
    case 0: return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   690
    case 1: MOVE8_ATOMIC_1(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   691
            return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   692
    case 2: MOVE8_ATOMIC_2(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   693
            return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   694
//  case 3: MOVE8_ATOMIC_3(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   695
//          return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   696
//  case 4: MOVE8_ATOMIC_4(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   697
//          return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   698
    default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   699
      if (len_bytes <= 4096) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   700
        MVC_MULTI(to,from,len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   701
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   702
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   703
      // else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   704
      MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   705
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   706
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   707
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   708
  // Fallback code.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   709
  switch (count) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   710
    case 0:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   711
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   712
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   713
    case 1:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   714
      *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   715
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   716
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   717
    case 2:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   718
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   719
      *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   720
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   721
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   722
    case 3:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   723
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   724
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   725
      *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   726
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   727
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   728
    case 4:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   729
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   730
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   731
      *to++ = *from++;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   732
      *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   733
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   734
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   735
    default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   736
      while (count-- > 0)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   737
        *(to++) = *(from++);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   738
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   739
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   740
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   741
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   742
48956
400f4d17a3c6 8197572: s390 build broken after 8165929
mdoerr
parents: 48951
diff changeset
   743
static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   744
  // JVM2008: < 4k calls.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   745
  assert(((((size_t)from) & 0x07L) | (((size_t)to) & 0x07L)) == 0, "No atomic copy w/o aligned data");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   746
  pd_aligned_disjoint_words(from, to, count); // Rare calls -> just delegate.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   747
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   748
48956
400f4d17a3c6 8197572: s390 build broken after 8165929
mdoerr
parents: 48951
diff changeset
   749
static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   750
  // JVM2008: very rare.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   751
  pd_aligned_disjoint_words(from, to, count); // Rare calls -> just delegate.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   752
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   753
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   754
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   755
//*************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   756
//   C O N J O I N T   C O P Y I N G   //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   757
//*************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   758
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   759
static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   760
  // JVM2008: between some and lower end of frequent.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   761
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   762
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   763
  size_t  count_in = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   764
  if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerLong)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   765
    switch (count_in) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   766
      case 4: COPY8_ATOMIC_4(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   767
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   768
      case 3: COPY8_ATOMIC_3(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   769
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   770
      case 2: COPY8_ATOMIC_2(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   771
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   772
      case 1: COPY8_ATOMIC_1(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   773
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   774
      case 0: return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   775
      default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   776
        from += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   777
        to   += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   778
        while (count_in-- > 0)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   779
          *(--to) = *(--from); // Copy backwards, areas overlap destructively.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   780
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   781
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   782
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   783
  // else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   784
  jbyte* to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   785
  jbyte* from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   786
  size_t len_bytes  = count_in*BytesPerLong;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   787
  MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   788
  return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   789
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   790
  // Fallback code.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   791
  if (has_destructive_overlap((char*)from, (char*)to, count*BytesPerLong)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   792
    HeapWord t1, t2, t3;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   793
    switch (count) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   794
      case 0:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   795
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   796
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   797
      case 1:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   798
        *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   799
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   800
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   801
      case 2:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   802
        t1 = *(from+1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   803
        *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   804
        *(to+1) = t1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   805
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   806
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   807
      case 3:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   808
        t1 = *(from+1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   809
        t2 = *(from+2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   810
        *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   811
        *(to+1) = t1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   812
        *(to+2) = t2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   813
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   814
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   815
      case 4:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   816
        t1 = *(from+1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   817
        t2 = *(from+2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   818
        t3 = *(from+3);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   819
        *to = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   820
        *(to+1) = t1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   821
        *(to+2) = t2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   822
        *(to+3) = t3;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   823
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   824
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   825
      default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   826
        from += count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   827
        to   += count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   828
        while (count-- > 0)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   829
          *(--to) = *(--from); // Copy backwards, areas overlap destructively.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   830
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   831
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   832
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   833
  // else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   834
  // Just delegate. HeapWords are optimally aligned anyway.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   835
  pd_aligned_disjoint_words(from, to, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   836
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   837
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   838
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   839
static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   840
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   841
  // Just delegate. HeapWords are optimally aligned anyway.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   842
  pd_aligned_conjoint_words(from, to, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   843
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   844
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   845
static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   846
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   847
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   848
  size_t count_in = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   849
  if (has_destructive_overlap((char*)from, (char*)to, count_in))
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   850
    (void)memmove(to, from, count_in);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   851
  else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   852
    jbyte*  to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   853
    jbyte*  from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   854
    size_t  len_bytes  = count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   855
    MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   856
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   857
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   858
  if (has_destructive_overlap((char*)from, (char*)to, count))
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   859
    (void)memmove(to, from, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   860
  else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   861
    (void)memcpy(to, from, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   862
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   863
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   864
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   865
//**************************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   866
//   C O N J O I N T  A T O M I C   C O P Y I N G   //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   867
//**************************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   868
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   869
static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   870
  // Call arraycopy stubs to do the job.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   871
  pd_conjoint_bytes(from, to, count); // bytes are always accessed atomically.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   872
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   873
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   874
static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   875
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   876
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   877
  size_t count_in = count;
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   878
  if (has_destructive_overlap((const char*)from, (char*)to, count_in*BytesPerShort)) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   879
    // Use optimizations from shared code where no z-specific optimization exists.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   880
    copy_conjoint_jshorts_atomic(from, to, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   881
  } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   882
    jbyte* to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   883
    jbyte* from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   884
    size_t len_bytes  = count_in*BytesPerShort;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   885
    MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   886
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   887
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   888
  // Use optimizations from shared code where no z-specific optimization exists.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   889
  copy_conjoint_jshorts_atomic(from, to, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   890
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   891
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   892
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   893
static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   894
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   895
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   896
  size_t count_in = count;
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   897
  if (has_destructive_overlap((const char*)from, (char*)to, count_in*BytesPerInt)) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   898
    switch (count_in) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   899
      case 4: COPY4_ATOMIC_4(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   900
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   901
      case 3: COPY4_ATOMIC_3(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   902
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   903
      case 2: COPY4_ATOMIC_2(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   904
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   905
      case 1: COPY4_ATOMIC_1(to,from)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   906
              return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   907
      case 0: return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   908
      default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   909
        // Use optimizations from shared code where no z-specific optimization exists.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   910
        copy_conjoint_jints_atomic(from, to, count_in);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   911
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   912
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   913
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   914
  // else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   915
  jbyte* to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   916
  jbyte* from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   917
  size_t len_bytes  = count_in*BytesPerInt;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   918
  MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   919
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   920
  // Use optimizations from shared code where no z-specific optimization exists.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   921
  copy_conjoint_jints_atomic(from, to, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   922
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   923
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   924
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   925
static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   926
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   927
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   928
  size_t count_in = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   929
  if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerLong)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   930
    switch (count_in) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   931
      case 4: COPY8_ATOMIC_4(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   932
      case 3: COPY8_ATOMIC_3(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   933
      case 2: COPY8_ATOMIC_2(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   934
      case 1: COPY8_ATOMIC_1(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   935
      case 0: return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   936
      default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   937
        from += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   938
        to   += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   939
        while (count_in-- > 0) { *(--to) = *(--from); } // Copy backwards, areas overlap destructively.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   940
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   941
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   942
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   943
  // else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   944
  jbyte* to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   945
  jbyte* from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   946
  size_t len_bytes  = count_in*BytesPerLong;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   947
  MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   948
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   949
  size_t count_in = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   950
  if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerLong)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   951
    if (count_in < 8) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   952
      from += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   953
      to   += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   954
      while (count_in-- > 0)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   955
         *(--to) = *(--from); // Copy backwards, areas overlap destructively.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   956
      return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   957
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   958
    // else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   959
    from += count_in-1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   960
    to   += count_in-1;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   961
    if (count_in&0x01) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   962
      *(to--) = *(from--);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   963
      count_in--;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   964
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   965
    for (; count_in>0; count_in-=2) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   966
      *to     = *from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   967
      *(to-1) = *(from-1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   968
      to     -= 2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   969
      from   -= 2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   970
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   971
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   972
  else
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   973
    pd_aligned_disjoint_words((const HeapWord*)from, (HeapWord*)to, count_in); // rare calls -> just delegate.
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   974
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   975
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   976
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
   977
static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   978
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   979
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   980
  size_t count_in = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   981
  if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerOop)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   982
    switch (count_in) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   983
      case 4: COPY8_ATOMIC_4(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   984
      case 3: COPY8_ATOMIC_3(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   985
      case 2: COPY8_ATOMIC_2(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   986
      case 1: COPY8_ATOMIC_1(to,from) return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   987
      case 0: return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   988
      default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   989
        from += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   990
        to   += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   991
        while (count_in-- > 0) { *(--to) = *(--from); } // Copy backwards, areas overlap destructively.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   992
        return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   993
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   994
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   995
  // else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   996
  jbyte* to_bytes   = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   997
  jbyte* from_bytes = (jbyte*)from;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   998
  size_t len_bytes  = count_in*BytesPerOop;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   999
  MVCLE_MEMCOPY(to_bytes, from_bytes, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1000
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1001
  size_t count_in = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1002
  if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerOop)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1003
    from += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1004
    to   += count_in;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1005
    while (count_in-- > 0) *(--to) = *(--from); // Copy backwards, areas overlap destructively.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1006
    return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1007
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1008
  // else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1009
  pd_aligned_disjoint_words((HeapWord*)from, (HeapWord*)to, count_in); // rare calls -> just delegate.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1010
  return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1011
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1012
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1013
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1014
static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1015
  pd_conjoint_bytes_atomic(from, to, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1016
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1017
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1018
static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1019
  pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1020
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1021
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1022
static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1023
  pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1024
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1025
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1026
static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1027
  pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1028
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1029
48951
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1030
static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
950c35ea6237 8165929: Constify arguments of Copy methods
coleenp
parents: 47216
diff changeset
  1031
  pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1032
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1033
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1034
//**********************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1035
//  M E M O R Y   I N I T I A L I S A T I O N   //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1036
//**********************************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1037
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1038
static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1039
  // JVM2008: very rare, only in some tests.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1040
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1041
  // Initialize storage to a given value. Use memset instead of copy loop.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1042
  // For large chunks of memory, exploit special H/W support of z/Architecture:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1043
  // 1) init short piece of memory to page-align address
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1044
  // 2) init largest part (all contained full pages) of memory using mvcle instruction.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1045
  //    z/Architecture processors have special H/W support for page-aligned storage
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1046
  //    where len is an int multiple of page size. In that case, up to 4 cache lines are
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1047
  //    processed in parallel and L1 cache is not polluted.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1048
  // 3) init the remaining piece of memory.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1049
  // Atomicity cannot really be an issue since gcc implements the loop body with XC anyway.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1050
  // If atomicity is a problem, we have to prevent gcc optimization. Best workaround: inline asm.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1051
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1052
  jbyte*  to_bytes  = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1053
  size_t  len_bytes = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1054
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1055
  MVCLE_MEMINIT(to_bytes, value, len_bytes)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1056
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1057
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1058
  // Memset does the best job possible: loop over 256-byte MVCs, with
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1059
  // the last MVC EXecuted. With the -mmvcle option, initialization
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1060
  // is done using MVCLE -> slight advantage for large areas.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1061
  (void)memset(to, value, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1062
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1063
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1064
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1065
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1066
  // Occurs in dbg builds only. Usually memory poisoning with BAADBABE, DEADBEEF, etc.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1067
  // JVM2008: < 4k calls.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1068
  if (value == 0) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1069
    pd_zero_to_words(tohw, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1070
    return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1071
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1072
  if (value == ~(juint)(0)) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1073
    pd_fill_to_bytes(tohw, count*HeapWordSize, (jubyte)(~(juint)(0)));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1074
    return;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1075
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1076
  julong* to = (julong*) tohw;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1077
  julong  v  = ((julong) value << 32) | value;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1078
  while (count-- > 0) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1079
    *to++ = v;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1080
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1081
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1082
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1083
static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1084
  // JVM2008: very frequent, but virtually all calls are with value == 0.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1085
  pd_fill_to_words(tohw, count, value);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1086
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1087
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1088
//**********************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1089
//  M E M O R Y   C L E A R I N G   //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1090
//**********************************//
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1091
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1092
// Delegate to pd_zero_to_bytes. It also works HeapWord-atomic.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1093
// Distinguish between simple and large zero_to_words.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1094
static void pd_zero_to_words(HeapWord* tohw, size_t count) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1095
  pd_zero_to_bytes(tohw, count*HeapWordSize);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1096
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1097
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1098
// Delegate to pd_zero_to_bytes. It also works HeapWord-atomic.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1099
static void pd_zero_to_words_large(HeapWord* tohw, size_t count) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1100
  // JVM2008: generally frequent, some tests show very frequent calls.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1101
  pd_zero_to_bytes(tohw, count*HeapWordSize);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1102
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1103
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1104
static void pd_zero_to_bytes(void* to, size_t count) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1105
  // JVM2008: some calls (generally), some tests frequent
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1106
#ifdef USE_INLINE_ASM
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1107
  // Even zero_to_bytes() requires HeapWord-atomic, or, at least, sequential
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1108
  // zeroing of the memory. MVCLE is not fit for that job:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1109
  //   "As observed by other CPUs and by the channel subsystem,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1110
  //    that portion of the first operand which is filled
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1111
  //    with the padding byte is not necessarily stored into in
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1112
  //    a left-to-right direction and may appear to be stored
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1113
  //    into more than once."
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1114
  // Therefore, implementation was changed to use (multiple) XC instructions.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1115
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1116
  const long line_size = 256;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1117
  jbyte* to_bytes  = (jbyte*)to;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1118
  size_t len_bytes = count;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1119
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1120
  if (len_bytes <= line_size) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1121
    XC_MEMZERO_256(to_bytes, len_bytes);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1122
  } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1123
    XC_MEMZERO_ANY(to_bytes, len_bytes);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1124
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1125
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1126
#else
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1127
  // Memset does the best job possible: loop over 256-byte MVCs, with
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1128
  // the last MVC EXecuted. With the -mmvcle option, initialization
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1129
  // is done using MVCLE -> slight advantage for large areas.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1130
  (void)memset(to, 0, count);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1131
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1132
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1133
53244
9807daeb47c4 8216167: Update include guards to reflect correct directories
coleenp
parents: 48956
diff changeset
  1134
#endif // CPU_S390_COPY_S390_HPP