@ -536,7 +536,7 @@ typedef struct TCGHelperInfo {
void * func ;
const char * name ;
unsigned flags ;
unsigned siz emask;
unsigned typ emask;
} TCGHelperInfo ;
# include "exec/helper-proto.h"
@ -1395,13 +1395,13 @@ bool tcg_op_supported(TCGOpcode op)
void tcg_gen_callN ( void * func , TCGTemp * ret , int nargs , TCGTemp * * args )
{
int i , real_args , nb_rets , pi ;
unsigned siz emask, flags ;
unsigned typ emask, flags ;
TCGHelperInfo * info ;
TCGOp * op ;
info = g_hash_table_lookup ( helper_table , ( gpointer ) func ) ;
flags = info - > flags ;
siz emask = info - > siz emask;
typ emask = info - > typ emask;
# ifdef CONFIG_PLUGIN
/* detect non-plugin helpers */
@ -1414,36 +1414,41 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
& & ! defined ( CONFIG_TCG_INTERPRETER )
/* We have 64-bit values in one register, but need to pass as two
separate parameters . Split them . */
int orig_sizemask = siz emask ;
int orig_typemask = typ emask ;
int orig_nargs = nargs ;
TCGv_i64 retl , reth ;
TCGTemp * split_args [ MAX_OPC_PARAM ] ;
retl = NULL ;
reth = NULL ;
if ( sizemask ! = 0 ) {
for ( i = real_args = 0 ; i < nargs ; + + i ) {
int is_64bit = sizemask & ( 1 < < ( i + 1 ) * 2 ) ;
if ( is_64bit ) {
TCGv_i64 orig = temp_tcgv_i64 ( args [ i ] ) ;
TCGv_i32 h = tcg_temp_new_i32 ( ) ;
TCGv_i32 l = tcg_temp_new_i32 ( ) ;
tcg_gen_extr_i64_i32 ( l , h , orig ) ;
split_args [ real_args + + ] = tcgv_i32_temp ( h ) ;
split_args [ real_args + + ] = tcgv_i32_temp ( l ) ;
} else {
split_args [ real_args + + ] = args [ i ] ;
}
typemask = 0 ;
for ( i = real_args = 0 ; i < nargs ; + + i ) {
int argtype = extract32 ( orig_typemask , ( i + 1 ) * 3 , 3 ) ;
bool is_64bit = ( argtype & ~ 1 ) = = dh_typecode_i64 ;
if ( is_64bit ) {
TCGv_i64 orig = temp_tcgv_i64 ( args [ i ] ) ;
TCGv_i32 h = tcg_temp_new_i32 ( ) ;
TCGv_i32 l = tcg_temp_new_i32 ( ) ;
tcg_gen_extr_i64_i32 ( l , h , orig ) ;
split_args [ real_args + + ] = tcgv_i32_temp ( h ) ;
typemask | = dh_typecode_i32 < < ( real_args * 3 ) ;
split_args [ real_args + + ] = tcgv_i32_temp ( l ) ;
typemask | = dh_typecode_i32 < < ( real_args * 3 ) ;
} else {
split_args [ real_args + + ] = args [ i ] ;
typemask | = argtype < < ( real_args * 3 ) ;
}
nargs = real_args ;
args = split_args ;
sizemask = 0 ;
}
nargs = real_args ;
args = split_args ;
# elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for ( i = 0 ; i < nargs ; + + i ) {
int is_64bit = sizemask & ( 1 < < ( i + 1 ) * 2 ) ;
int is_signed = sizemask & ( 2 < < ( i + 1 ) * 2 ) ;
if ( ! is_64bit ) {
int argtype = extract32 ( typemask , ( i + 1 ) * 3 , 3 ) ;
bool is_32bit = ( argtype & ~ 1 ) = = dh_typecode_i32 ;
bool is_signed = argtype & 1 ;
if ( is_32bit ) {
TCGv_i64 temp = tcg_temp_new_i64 ( ) ;
TCGv_i64 orig = temp_tcgv_i64 ( args [ i ] ) ;
if ( is_signed ) {
@ -1462,7 +1467,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
if ( ret ! = NULL ) {
# if defined(__sparc__) && !defined(__arch64__) \
& & ! defined ( CONFIG_TCG_INTERPRETER )
if ( orig_sizemask & 1 ) {
if ( ( typemask & 6 ) = = dh_typecode_i64 ) {
/* The 32-bit ABI is going to return the 64-bit value in
the % o0 / % o1 register pair . Prepare for this by using
two return temporaries , and reassemble below . */
@ -1476,7 +1481,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
nb_rets = 1 ;
}
# else
if ( TCG_TARGET_REG_BITS < 64 & & ( sizemask & 1 ) ) {
if ( TCG_TARGET_REG_BITS < 64 & & ( typemask & 6 ) = = dh_typecode_i64 ) {
# ifdef HOST_WORDS_BIGENDIAN
op - > args [ pi + + ] = temp_arg ( ret + 1 ) ;
op - > args [ pi + + ] = temp_arg ( ret ) ;
@ -1497,7 +1502,9 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
real_args = 0 ;
for ( i = 0 ; i < nargs ; i + + ) {
int is_64bit = sizemask & ( 1 < < ( i + 1 ) * 2 ) ;
int argtype = extract32 ( typemask , ( i + 1 ) * 3 , 3 ) ;
bool is_64bit = ( argtype & ~ 1 ) = = dh_typecode_i64 ;
if ( TCG_TARGET_REG_BITS < 64 & & is_64bit ) {
# ifdef TCG_TARGET_CALL_ALIGN_ARGS
/* some targets want aligned 64 bit args */
@ -1542,7 +1549,9 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
& & ! defined ( CONFIG_TCG_INTERPRETER )
/* Free all of the parts we allocated above. */
for ( i = real_args = 0 ; i < orig_nargs ; + + i ) {
int is_64bit = orig_sizemask & ( 1 < < ( i + 1 ) * 2 ) ;
int argtype = extract32 ( orig_typemask , ( i + 1 ) * 3 , 3 ) ;
bool is_64bit = ( argtype & ~ 1 ) = = dh_typecode_i64 ;
if ( is_64bit ) {
tcg_temp_free_internal ( args [ real_args + + ] ) ;
tcg_temp_free_internal ( args [ real_args + + ] ) ;
@ -1550,7 +1559,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
real_args + + ;
}
}
if ( orig_sizemask & 1 ) {
if ( ( orig_typemask & 6 ) = = dh_typecode_i64 ) {
/* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
Note that describing these as TCGv_i64 eliminates an unnecessary
zero - extension that tcg_gen_concat_i32_i64 would create . */
@ -1560,8 +1569,10 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
}
# elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for ( i = 0 ; i < nargs ; + + i ) {
int is_64bit = sizemask & ( 1 < < ( i + 1 ) * 2 ) ;
if ( ! is_64bit ) {
int argtype = extract32 ( typemask , ( i + 1 ) * 3 , 3 ) ;
bool is_32bit = ( argtype & ~ 1 ) = = dh_typecode_i32 ;
if ( is_32bit ) {
tcg_temp_free_internal ( args [ i ] ) ;
}
}