Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/sparc/vm/args.cc
32285 views
/*1* Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include <stdio.h>25#include <string.h>2627static const int R_O0_num = 1000;28static const int R_I0_num = 2000;29static const int R_F0_num = 3000;30static const int R_F1_num = R_F0_num + 1;31static const int R_F2_num = R_F0_num + 2;32static const int STACK_num= 4000;3334static bool LP64 = false;35static bool LONGS_IN_ONE_ENTRY = false;3637static const int Op_RegI = 'I';38static const int Op_RegP = 'P';39static const int Op_RegF = 'F';40static const int Op_RegD = 'D';41static const int Op_RegL = 'L';42static const int SPARC_ARGS_IN_REGS_NUM=6;4344static void print_reg( int reg ) {45if( reg == 0 )46printf("__"); // halve's47else if( reg >= STACK_num && reg < STACK_num+100 )48printf("S%d_",reg - STACK_num);49else if( reg >= R_F0_num && reg < R_F0_num+100 )50printf("F%d_",reg - R_F0_num);51else if( reg >= R_O0_num && reg < R_O0_num+100 ) {52if( LONGS_IN_ONE_ENTRY ) {53reg -= R_O0_num;54printf("O%d",reg>>1);55printf(reg&1 ? "H" : "L");56} else57printf("O%d_",reg - R_O0_num);58} else59printf("Wretched: %d\n", reg);60}6162static void print_convention( int *sig, const char *s, int length ) {63// Print it out64for( int i = 0; i < length; i++) {65if( sig[i] == 0 ) continue; // do not print 'halves'66print_reg( sig[i] & 0xFFFF );67int reg = sig[i] >> 16;68if( reg ) {69printf(":");70print_reg( reg );71} else {72printf(" ");73}74printf(" ");75}76printf("\n");77}7879static int INT_SCALE( int x ) {80return LONGS_IN_ONE_ENTRY ? (x<<1) : x;81}8283static void java_convention( int *sig, const char *s, int length ) {84if( LP64 && !LONGS_IN_ONE_ENTRY ) {85printf("LP64 and 2-reg longs not supported\n");86return;87}88for( int i = 0; i < length; i++ )89sig[i] = s[i]; // Reset sig array90bool is_outgoing = true;9192int int_base = (is_outgoing ? R_O0_num : R_I0_num);9394// Convention is to pack the first 6 int/oop args into the first 695// registers (I0-I5), extras spill to the stack. Then pack the first96// 32 float args into F0-F31, extras spill to the stack. Then pad97// all register sets to align. Then put longs and doubles into the98// same registers as they fit, else spill to the stack.99int int_reg_max = SPARC_ARGS_IN_REGS_NUM;100int flt_reg_max = 32;101102// Count int/oop and float args. See how many stack slots we'll need103// and where the longs & doubles will go.104int int_reg_cnt = 0;105int flt_reg_cnt = 0;106int stk_reg_pairs = 0;107for( int i = 0; i < length; i++) {108switch( sig[i] ) {109case Op_RegL: // Longs-in-1-reg compete with int args110if( LONGS_IN_ONE_ENTRY ) {111if( int_reg_cnt < int_reg_max ) int_reg_cnt++;112}113break;114case Op_RegP:115if( int_reg_cnt < int_reg_max ) int_reg_cnt++;116else if( !LP64 ) stk_reg_pairs++;117break;118case Op_RegI:119if( int_reg_cnt < int_reg_max ) int_reg_cnt++;120else stk_reg_pairs++;121break;122case Op_RegF:123if( flt_reg_cnt < flt_reg_max ) flt_reg_cnt++;124else stk_reg_pairs++;125break;126}127}128129// This is where the longs/doubles start on the stack.130stk_reg_pairs = (stk_reg_pairs+1) & ~1; // Round131132int int_reg_pairs = (int_reg_cnt+1) & ~1; // 32-bit 2-reg longs only133int flt_reg_pairs = (flt_reg_cnt+1) & ~1;134135int stk_reg = 0;136int int_reg = 0;137int flt_reg = 0;138139// Now do the signature layout140for( int i = 0; i < length; i++) {141int tmp = sig[i];142if( tmp == Op_RegP )143tmp = LP64 ? Op_RegL : Op_RegI; // Treat ptrs and ints or long accordingly144switch( tmp ) {145case Op_RegI:146// case Op_RegP:147if( int_reg < int_reg_max) tmp = INT_SCALE(int_reg++) + int_base;148else tmp = STACK_num + stk_reg++;149sig[i] = tmp;150break;151152case Op_RegL:153if( sig[i] != Op_RegP && sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; }154// case Op_RegP:155if( LONGS_IN_ONE_ENTRY ) {156if( int_reg < int_reg_max ) {157tmp = INT_SCALE(int_reg++) + int_base;158} else {159tmp = STACK_num + stk_reg_pairs;160stk_reg_pairs += 2;161}162} else {163if( int_reg_pairs < int_reg_max ) {164tmp = int_reg_pairs + int_base;165int_reg_pairs += 2;166} else {167tmp = STACK_num + stk_reg_pairs;168stk_reg_pairs += 2;169}170}171sig[i] = tmp | (tmp+1)<<16; // Smear to pair172break;173174case Op_RegF:175sig[i] = (flt_reg < flt_reg_max) ? (R_F0_num + flt_reg++) : STACK_num + stk_reg++;176break;177case Op_RegD:178if( sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; }179if( flt_reg_pairs < flt_reg_max ) {180tmp = R_F0_num + flt_reg_pairs;181flt_reg_pairs += 2;182} else {183tmp = STACK_num + stk_reg_pairs;184stk_reg_pairs += 2;185}186sig[i] = tmp | (tmp+1)<<16; // Smear to pair187break;188case 'h': sig[i] = 0; break;189default:190printf("Bad character: %c\n", sig[i] );191return;192}193}194195printf("java ");196printf(LP64 ? "LP64 " : "LP32 ");197printf(LONGS_IN_ONE_ENTRY ? "long1: " : "long2: ");198print_convention(sig,s,length);199}200201static int int_stk_helper( int i ) {202if( i < 6 ) return R_O0_num + (LONGS_IN_ONE_ENTRY ? i<<1 : i);203else return STACK_num + (LP64 ? i<<1 : i);204}205206static void native_convention( int *sig, const char *s, int length ) {207if( LP64 && !LONGS_IN_ONE_ENTRY ) {208printf("LP64 and 2-reg longs not supported\n");209return;210}211for( int i = 0; i < length; i++ )212sig[i] = s[i]; // Reset sig array213214// The native convention is V8 if !LP64, which means the V8 convention is215// used both with and without LONGS_IN_ONE_ENTRY, an unfortunate split. The216// same actual machine registers are used, but they are named differently in217// the LONGS_IN_ONE_ENTRY mode. The LP64 convention is the V9 convention218// which is slightly more sane.219220if( LP64 ) {221// V9 convention: All things "as-if" on double-wide stack slots.222// Hoist any int/ptr/long's in the first 6 to int regs.223// Hoist any flt/dbl's in the first 16 dbl regs.224int j = 0; // Count of actual args, not HALVES225for( int i=0; i<length; i++, j++ ) {226int tmp;227switch( sig[i] ) {228case Op_RegI:229sig[i] = int_stk_helper( j );230break;231case Op_RegL:232if( sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; }233case Op_RegP:234tmp = int_stk_helper( j );235sig[i] = tmp | ((tmp+1) << 16); // Smear to pair236break;237case Op_RegF: // V9ism: floats go in ODD registers238sig[i] = ((j < 16) ? R_F1_num : (STACK_num + 1)) + (j<<1);239break;240case Op_RegD: // V9ism: doubles go in EVEN/ODD regs241tmp = ((j < 16) ? R_F0_num : STACK_num) + (j<<1);242sig[i] = tmp | ((tmp+1) << 16); // Smear to pair243break;244case 'h': sig[i] = 0; j--; break; // Do not count HALVES245default:246printf("Bad character: %c\n", sig[i] );247return;248}249}250251} else {252// V8 convention: first 6 things in O-regs, rest on stack.253// Alignment is willy-nilly.254for( int i=0; i<length; i++ ) {255int tmp;256switch( sig[i] ) {257case Op_RegI:258case Op_RegP:259case Op_RegF:260sig[i] = int_stk_helper( i );261break;262case Op_RegL:263case Op_RegD:264if( sig[i+1] != 'h' ) { printf("expecting (h)alf, found %c\n", sig[i+1]); return; }265tmp = int_stk_helper( i );266sig[i] = tmp | (int_stk_helper( i+1 ) << 16);267break;268case 'h': sig[i] = 0; break;269default:270printf("Bad character: %c\n", sig[i] );271return;272}273}274}275276printf("natv ");277printf(LP64 ? "LP64 " : "LP32 ");278printf(LONGS_IN_ONE_ENTRY ? "long1: " : "long2: ");279print_convention(sig,s,length);280}281282int main( int argc, char **argv ) {283284if( argc != 2 ) {285printf("Usage: args IPFLhDh... (Java argument string)\n");286printf("Returns argument layout\n");287return -1;288}289290const char *s = argv[1];291int length = strlen(s);292int sig[1000];293294LP64 = false; LONGS_IN_ONE_ENTRY = false;295java_convention( sig, s, length );296LP64 = false; LONGS_IN_ONE_ENTRY = true;297java_convention( sig, s, length );298LP64 = true ; LONGS_IN_ONE_ENTRY = true;299java_convention( sig, s, length );300301LP64 = false; LONGS_IN_ONE_ENTRY = false;302native_convention( sig, s, length );303LP64 = false; LONGS_IN_ONE_ENTRY = true;304native_convention( sig, s, length );305LP64 = true ; LONGS_IN_ONE_ENTRY = true;306native_convention( sig, s, length );307}308309310311