vm_version_solaris_sparc.cpp revision 1879:f95d63e2154a
1/*
2 * Copyright (c) 2006, 2010, 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 "precompiled.hpp"
26#include "runtime/os.hpp"
27#include "vm_version_sparc.hpp"
28
29# include <sys/auxv.h>
30# include <sys/auxv_SPARC.h>
31# include <sys/systeminfo.h>
32
33// We need to keep these here as long as we have to build on Solaris
34// versions before 10.
35#ifndef SI_ARCHITECTURE_32
36#define SI_ARCHITECTURE_32      516     /* basic 32-bit SI_ARCHITECTURE */
37#endif
38
39#ifndef SI_ARCHITECTURE_64
40#define SI_ARCHITECTURE_64      517     /* basic 64-bit SI_ARCHITECTURE */
41#endif
42
43static void do_sysinfo(int si, const char* string, int* features, int mask) {
44  char   tmp;
45  size_t bufsize = sysinfo(si, &tmp, 1);
46
47  // All SI defines used below must be supported.
48  guarantee(bufsize != -1, "must be supported");
49
50  char* buf = (char*) malloc(bufsize);
51
52  if (buf == NULL)
53    return;
54
55  if (sysinfo(si, buf, bufsize) == bufsize) {
56    // Compare the string.
57    if (strcmp(buf, string) == 0) {
58      *features |= mask;
59    }
60  }
61
62  free(buf);
63}
64
65int VM_Version::platform_features(int features) {
66  // getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are
67  // supported on Solaris 10 and later.
68  if (os::Solaris::supports_getisax()) {
69
70    // Check 32-bit architecture.
71    do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m);
72
73    // Check 64-bit architecture.
74    do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m);
75
76    // Extract valid instruction set extensions.
77    uint_t av;
78    uint_t avn = os::Solaris::getisax(&av, 1);
79    assert(avn == 1, "should only return one av");
80
81#ifndef PRODUCT
82    if (PrintMiscellaneous && Verbose)
83      tty->print_cr("getisax(2) returned: " PTR32_FORMAT, av);
84#endif
85
86    if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
87    if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
88    if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
89    if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m;
90    if (av & AV_SPARC_POPC)   features |= hardware_popc_m;
91    if (av & AV_SPARC_VIS)    features |= vis1_instructions_m;
92    if (av & AV_SPARC_VIS2)   features |= vis2_instructions_m;
93
94    // Next values are not defined before Solaris 10
95    // but Solaris 8 is used for jdk6 update builds.
96#ifndef AV_SPARC_ASI_BLK_INIT
97#define AV_SPARC_ASI_BLK_INIT 0x0080  /* ASI_BLK_INIT_xxx ASI */
98#endif
99#ifndef AV_SPARC_FMAF
100#define AV_SPARC_FMAF 0x0100  /* Sparc64 Fused Multiply-Add */
101#endif
102    if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
103    if (av & AV_SPARC_FMAF)         features |= fmaf_instructions_m;
104  } else {
105    // getisax(2) failed, use the old legacy code.
106#ifndef PRODUCT
107    if (PrintMiscellaneous && Verbose)
108      tty->print_cr("getisax(2) is not supported.");
109#endif
110
111    char   tmp;
112    size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
113    char*  buf     = (char*) malloc(bufsize);
114
115    if (buf != NULL) {
116      if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) {
117        // Figure out what kind of sparc we have
118        char *sparc_string = strstr(buf, "sparc");
119        if (sparc_string != NULL) {              features |= v8_instructions_m;
120          if (sparc_string[5] == 'v') {
121            if (sparc_string[6] == '8') {
122              if (sparc_string[7] == '-') {      features |= hardware_mul32_m;
123                                                 features |= hardware_div32_m;
124              } else if (sparc_string[7] == 'p') features |= generic_v9_m;
125              else                               features |= generic_v8_m;
126            } else if (sparc_string[6] == '9')   features |= generic_v9_m;
127          }
128        }
129
130        // Check for visualization instructions
131        char *vis = strstr(buf, "vis");
132        if (vis != NULL) {                       features |= vis1_instructions_m;
133          if (vis[3] == '2')                     features |= vis2_instructions_m;
134        }
135      }
136      free(buf);
137    }
138  }
139
140  // Determine the machine type.
141  do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
142
143  return features;
144}
145