vm_version_solaris_sparc.cpp revision 1472:c18cbe5936b8
1/*
2 * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25# include "incls/_precompiled.incl"
26# include "incls/_vm_version_solaris_sparc.cpp.incl"
27
28# include <sys/auxv.h>
29# include <sys/auxv_SPARC.h>
30# include <sys/systeminfo.h>
31
32// We need to keep these here as long as we have to build on Solaris
33// versions before 10.
34#ifndef SI_ARCHITECTURE_32
35#define SI_ARCHITECTURE_32      516     /* basic 32-bit SI_ARCHITECTURE */
36#endif
37
38#ifndef SI_ARCHITECTURE_64
39#define SI_ARCHITECTURE_64      517     /* basic 64-bit SI_ARCHITECTURE */
40#endif
41
42static void do_sysinfo(int si, const char* string, int* features, int mask) {
43  char   tmp;
44  size_t bufsize = sysinfo(si, &tmp, 1);
45
46  // All SI defines used below must be supported.
47  guarantee(bufsize != -1, "must be supported");
48
49  char* buf = (char*) malloc(bufsize);
50
51  if (buf == NULL)
52    return;
53
54  if (sysinfo(si, buf, bufsize) == bufsize) {
55    // Compare the string.
56    if (strcmp(buf, string) == 0) {
57      *features |= mask;
58    }
59  }
60
61  free(buf);
62}
63
64int VM_Version::platform_features(int features) {
65  // getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are
66  // supported on Solaris 10 and later.
67  if (os::Solaris::supports_getisax()) {
68#ifndef PRODUCT
69    if (PrintMiscellaneous && Verbose)
70      tty->print_cr("getisax(2) supported.");
71#endif
72
73    // Check 32-bit architecture.
74    do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m);
75
76    // Check 64-bit architecture.
77    do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m);
78
79    // Extract valid instruction set extensions.
80    uint_t av;
81    uint_t avn = os::Solaris::getisax(&av, 1);
82    assert(avn == 1, "should only return one av");
83
84    if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
85    if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
86    if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
87    if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m;
88    if (av & AV_SPARC_POPC)   features |= hardware_popc_m;
89    if (av & AV_SPARC_VIS)    features |= vis1_instructions_m;
90    if (av & AV_SPARC_VIS2)   features |= vis2_instructions_m;
91  } else {
92    // getisax(2) failed, use the old legacy code.
93#ifndef PRODUCT
94    if (PrintMiscellaneous && Verbose)
95      tty->print_cr("getisax(2) not supported.");
96#endif
97
98    char   tmp;
99    size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
100    char*  buf     = (char*) malloc(bufsize);
101
102    if (buf != NULL) {
103      if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) {
104        // Figure out what kind of sparc we have
105        char *sparc_string = strstr(buf, "sparc");
106        if (sparc_string != NULL) {              features |= v8_instructions_m;
107          if (sparc_string[5] == 'v') {
108            if (sparc_string[6] == '8') {
109              if (sparc_string[7] == '-') {      features |= hardware_mul32_m;
110                                                 features |= hardware_div32_m;
111              } else if (sparc_string[7] == 'p') features |= generic_v9_m;
112              else                               features |= generic_v8_m;
113            } else if (sparc_string[6] == '9')   features |= generic_v9_m;
114          }
115        }
116
117        // Check for visualization instructions
118        char *vis = strstr(buf, "vis");
119        if (vis != NULL) {                       features |= vis1_instructions_m;
120          if (vis[3] == '2')                     features |= vis2_instructions_m;
121        }
122      }
123      free(buf);
124    }
125  }
126
127  // Determine the machine type.
128  do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
129
130  return features;
131}
132