diff --git a/src/code/amd64.c b/src/code/amd64.c index 1459e36c8dd32da2fecb40cfb3dd1a869394e492..05721cb45e264de2f7f018e89dd98eb99cfbd0e7 100644 --- a/src/code/amd64.c +++ b/src/code/amd64.c @@ -387,6 +387,11 @@ static void mov_imm_reg( long imm, enum amd64_reg reg ) } } +/* static void mov_ptr_reg( void *x, enum amd64_reg reg ) */ +/* { */ +/* mov_imm_reg( (long)x, reg ); */ +/* } */ + static void mov_mem128_reg( enum amd64_reg from_reg, int offset, enum amd64_reg to_reg ) { if( from_reg > 7 ) @@ -542,25 +547,25 @@ static void add_mem_imm( enum amd64_reg reg, int offset, int imm32 ) low_add_mem_imm( 1, reg, offset, imm32 ); } -static void add_mem8_imm( enum amd64_reg reg, int offset, int imm32 ) -{ - int r2 = imm32 == -1 ? 1 : 0; - if( !imm32 ) return; - rex( 0, 0, 0, reg ); +/* static void add_mem8_imm( enum amd64_reg reg, int offset, int imm32 ) */ +/* { */ +/* int r2 = imm32 == -1 ? 1 : 0; */ +/* if( !imm32 ) return; */ +/* rex( 0, 0, 0, reg ); */ - if( imm32 == 1 || imm32 == -1 ) - opcode( 0xfe ); /* INCL r/m8 */ - else if( imm32 >= -128 && imm32 < 128 ) - opcode( 0x80 ); /* ADD imm8,r/m32 */ - else - Pike_fatal("Not sensible"); +/* if( imm32 == 1 || imm32 == -1 ) */ +/* opcode( 0xfe ); /\* INCL r/m8 *\/ */ +/* else if( imm32 >= -128 && imm32 < 128 ) */ +/* opcode( 0x80 ); /\* ADD imm8,r/m32 *\/ */ +/* else */ +/* Pike_fatal("Not sensible"); */ - offset_modrm_sib( offset, r2, reg ); - if( imm32 != 1 && !r2 ) - { - ib( imm32 ); - } -} +/* offset_modrm_sib( offset, r2, reg ); */ +/* if( imm32 != 1 && !r2 ) */ +/* { */ +/* ib( imm32 ); */ +/* } */ +/* } */ static void sub_reg_imm( enum amd64_reg reg, int imm32 ) { @@ -2809,25 +2814,10 @@ void ins_f_byte_with_arg(unsigned int a, INT32 b) */ mov_imm_reg( 1, ARG1_REG ); } + /* Get function pointer */ -#if 0 - amd64_load_fp_reg(); - /* Ok.. This is.. interresting. - Let's trust that the efun really is constant, ok? - */ - mov_mem_reg( fp_reg, OFFSETOF(pike_frame,context), P_REG_RAX ); - mov_mem_reg( P_REG_RAX, OFFSETOF(inherit,prog), P_REG_RAX ); - mov_mem_reg( P_REG_RAX, OFFSETOF(program,constants), P_REG_RAX ); - add_reg_imm( P_REG_RAX, b*sizeof(struct program_constant) + - OFFSETOF(program_constant,sval) ); - mov_mem_reg( P_REG_RAX, OFFSETOF( svalue, u.efun ), P_REG_RAX ); - mov_mem_reg( P_REG_RAX, OFFSETOF( callable, function), P_REG_RAX ); - call_reg( P_REG_RAX ); - sp_reg = -1; -#else amd64_call_c_opcode(Pike_compiler->new_program->constants[b].sval.u.efun->function, I_UPDATE_SP); -#endif return; case F_CONSTANT: @@ -3004,6 +2994,24 @@ void ins_f_byte_with_2_args(unsigned int a, INT32 b, INT32 c) LABEL_C; return; } + +#if 0 + /* this is a: nonworking, and b: not really all that more efficient anyway.. */ + case F_APPLY_N: + mov_imm_reg( APPLY_SVALUE_STRICT, ARG1_REG ); + mov_imm_reg( c, ARG2_REG ); + mov_ptr_reg( &((Pike_fp->context->prog->constants + b)->sval), ARG3_REG ); + clear_reg( ARG4_REG ); + amd64_call_c_opcode(mega_apply, I_UPDATE_SP); + return; +#endif + case F_CALL_BUILTIN_N: + mov_imm_reg( c, ARG1_REG ); + amd64_call_c_opcode(Pike_compiler->new_program->constants[b].sval.u.efun->function, + I_UPDATE_SP); + return; + + case F_ADD_LOCALS_AND_POP: { LABELS(); diff --git a/src/code/amd64.h b/src/code/amd64.h index efcaaaf7682cf10b537796ac43839590236bacc2..3f20dda9323d0359866d7a6a79aa336298941b05 100644 --- a/src/code/amd64.h +++ b/src/code/amd64.h @@ -2,6 +2,7 @@ #define OPCODE_INLINE_BRANCH #define OPCODE_RETURN_JUMPADDR #define OPCODE_INLINE_RETURN +#define USE_APPLY_N #if defined(_M_X64) && !defined(__GNUC__) diff --git a/src/docode.c b/src/docode.c index c263f8f82e2d6863ae7e2490b2594180948f89fd..17dae960e0359be78645859e19af894da538bec3 100644 --- a/src/docode.c +++ b/src/docode.c @@ -1902,6 +1902,7 @@ static int do_docode2(node *n, int flags) case F_APPLY: if(CAR(n)->token == F_CONSTANT) { + int args = count_args(CDR(n)); if(TYPEOF(CAR(n)->u.sval) == T_FUNCTION) { if(SUBTYPEOF(CAR(n)->u.sval) == FUNCTION_BUILTIN) /* driver fun? */ @@ -1909,13 +1910,21 @@ static int do_docode2(node *n, int flags) if(!CAR(n)->u.sval.u.efun->docode || !CAR(n)->u.sval.u.efun->docode(n)) { - if(count_args(CDR(n))==1) + if(args==1) { do_docode(CDR(n),0); tmp1=store_constant(& CAR(n)->u.sval, !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), CAR(n)->name); emit1(F_CALL_BUILTIN1, DO_NOT_WARN((INT32)tmp1)); +#ifdef USE_APPLY_N + }else if(args>0){ + do_docode(CDR(n),0); + tmp1=store_constant(& CAR(n)->u.sval, + !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), + CAR(n)->name); + emit2(F_CALL_BUILTIN_N, DO_NOT_WARN((INT32)tmp1), args); +#endif }else{ emit0(F_MARK); PUSH_CLEANUP_FRAME(do_pop_mark, 0); @@ -1929,23 +1938,35 @@ static int do_docode2(node *n, int flags) } if(n->type == void_type_string) return 0; - return 1; }else{ if(CAR(n)->u.sval.u.object == Pike_compiler->fake_object) return do_lfun_call(SUBTYPEOF(CAR(n)->u.sval), CDR(n)); } } - - emit0(F_MARK); - PUSH_CLEANUP_FRAME(do_pop_mark, 0); - do_docode(CDR(n),0); - tmp1=store_constant(& CAR(n)->u.sval, - !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), - CAR(n)->name); - emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1)); - POP_AND_DONT_CLEANUP; - +#ifdef USE_APPLY_N + if( args <= 1 ) +#endif + { + emit0(F_MARK); + PUSH_CLEANUP_FRAME(do_pop_mark, 0); + do_docode(CDR(n),0); + tmp1=store_constant(& CAR(n)->u.sval, + !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), + CAR(n)->name); + emit1(F_APPLY, DO_NOT_WARN((INT32)tmp1)); + POP_AND_DONT_CLEANUP; + } +#ifdef USE_APPLY_N + else + { + do_docode(CDR(n),0); + tmp1=store_constant(& CAR(n)->u.sval, + !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), + CAR(n)->name); + emit2(F_APPLY_N, DO_NOT_WARN((INT32)tmp1), args); + } +#endif return 1; } else if(CAR(n)->token == F_IDENTIFIER) diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 9a62d7955473189c3fa131d86c30a4697b4c385d..42fbc6825af83ff7ceb1354d1efadfae337bd206 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -2493,6 +2493,15 @@ OPCODE1(F_CALL_BUILTIN1, "call builtin 1", I_UPDATE_ALL, { DO_CALL_BUILTIN(1); }); +OPCODE2(F_CALL_BUILTIN_N, "call builtin N", I_UPDATE_ALL, { + FAST_CHECK_THREADS_ON_CALL(); + DO_CALL_BUILTIN(arg2); +}); + +OPCODE2( F_APPLY_N, "apply N", I_UPDATE_ALL, { + mega_apply( APPLY_SVALUE_STRICT, arg2, &((Pike_fp->context->prog->constants + arg1)->sval), 0 ); +}); + OPCODE1(F_CALL_BUILTIN1_AND_POP, "call builtin1 & pop", I_UPDATE_ALL, { FAST_CHECK_THREADS_ON_CALL(); DO_CALL_BUILTIN(1);