From 0902c5271401a01d4f4a80bf5841c6ba77b28f46 Mon Sep 17 00:00:00 2001 From: edwin Date: Sun, 19 Mar 2006 19:46:11 +0000 Subject: [PATCH] * src/vm/jit/code.c (code_get_stack_frame_size): Implement stack alignment for MIPS. * src/vm/jit/mips/md.c (md_patch_replacement_point): Added. * src/vm/jit/mips/codegen.c (codegen): Handle replacement points. 8-byte align blocks that start with replacement points. * src/vm/jit/mips/asmpart.S (asm_replacement_out): Added. (asm_replacement_in): Likewise. * src/vm/jit/replace.c (replace_activate_replacement_point): Activated for MIPS. (replace_deactivate_replacement_poin): Likewise. (replace_me): Likewise. (replace_read_executionstate): MIPS also keeps returnAddress in ITMP1. (replace_write_executionstate): Likewise. * doc/stack_frames.txt: Documented MIPS stack frames. * src/vm/jit/powerpc/asmpart.S (asm_replacement_out): Fixed comment. --- doc/stack_frames.txt | 33 +++++- src/vm/jit/code.c | 15 ++- src/vm/jit/mips/asmpart.S | 222 ++++++++++++++++++++++++++++++++++- src/vm/jit/mips/codegen.c | 75 +++++++++++- src/vm/jit/mips/md.c | 39 +++++- src/vm/jit/powerpc/asmpart.S | 4 +- src/vm/jit/replace.c | 10 +- 7 files changed, 383 insertions(+), 15 deletions(-) diff --git a/doc/stack_frames.txt b/doc/stack_frames.txt index 16e0abc49..7855d10e9 100644 --- a/doc/stack_frames.txt +++ b/doc/stack_frames.txt @@ -39,7 +39,7 @@ x86_64 stack frames ,--memory address rising | -V >>>> sp in method (after initial sub) <<<< +V >>>> sp in method (after initial sub) (16-byte aligned in non-leaf methods) <<<< | | u8[] v arguments for calling methods \__ rd->memuse slots V u8[] v local variable slots allocated on stack / @@ -50,7 +50,7 @@ V u8[0..1] alignment dummy slot (in non-leaf methods | u8[] ^ callee-saved float registers V u8[] ^ callee-saved integer registers | -| >>>> sp on method entry, stack base for replacement <<<< +| >>>> sp on method entry, stack base for replacement (16-byte aligned) <<<< V | u8 return address | u8[] arguments on stack @@ -61,6 +61,8 @@ V alpha stack frames ------------------ +XXX currently the stack on alpha is not 16-byte aligned! + ,--memory address rising | V >>>> sp in method (after initial sub) <<<< @@ -83,3 +85,30 @@ V | V + +mips stack frames +----------------- + +,--memory address rising +| +V >>>> sp in method (after initial sub) (16-byte aligned) <<<< +| +| u8[] v arguments for calling methods \__ rd->memuse slots +V u8[] v local variable slots allocated on stack / +| +| u8 synchronized object / saved return value (only for synched methods) +| u8[0..1] alignment dummy-slot (to ensure 16-byte alignment of sp) +V +| u8[] ^ callee-saved float registers +| u8[] ^ callee-saved integer registers +V +| >>>> !!!replacement code regards this point as stack base!!! <<<< +| +V u8 ^ saved return address (only for non-leaf methods) +| +| >>>> sp on method entry (16-byte aligned) <<<< +V +| u8[] arguments on stack +| +V + diff --git a/src/vm/jit/code.c b/src/vm/jit/code.c index 5297c32e0..dc7cd96c6 100644 --- a/src/vm/jit/code.c +++ b/src/vm/jit/code.c @@ -151,6 +151,8 @@ int code_get_stack_frame_size(codeinfo *code) assert(code); + /* slots allocated by register allocator plus saved registers */ + #ifdef HAS_4BYTE_STACKSLOT count = code->memuse + code->savedintcount + 2*code->savedfltcount; #else @@ -158,14 +160,25 @@ int code_get_stack_frame_size(codeinfo *code) #endif /* add slots needed in synchronized methods */ + count += code_get_sync_slot_count(code); + /* keep stack aligned */ + #if defined(__X86_64__) - /* keep stack 16-byte aligned */ + /* the x86_64 codegen only aligns the stack in non-leaf methods */ if (!code->isleafmethod || opt_verbosecall) count |= 1; /* even when return address is added */ #endif + /* XXX align stack on alpha */ +#if defined(__MIPS__) + if (code->isleafmethod) + count = (count + 1) & ~1; + else + count |= 1; /* even when return address is added */ +#endif + #if defined(__POWERPC__) /* keep stack 16-byte aligned */ count = (count + 3) & ~3; diff --git a/src/vm/jit/mips/asmpart.S b/src/vm/jit/mips/asmpart.S index 3382ceade..20d546af3 100644 --- a/src/vm/jit/mips/asmpart.S +++ b/src/vm/jit/mips/asmpart.S @@ -27,8 +27,9 @@ Authors: Andreas Krall Changes: Christian Thalinger + Edwin Steiner - $Id: asmpart.S 4640 2006-03-16 17:24:18Z twisti $ + $Id: asmpart.S 4654 2006-03-19 19:46:11Z edwin $ */ @@ -61,6 +62,9 @@ .globl asm_wrapper_patcher + .globl asm_replacement_out + .globl asm_replacement_in + .globl asm_perform_threadswitch .globl asm_initialize_thread_stack .globl asm_switchstackandcall @@ -552,6 +556,221 @@ L_asm_wrapper_patcher_exception: .end asm_wrapper_patcher +/* asm_replacement_out ********************************************************* + + This code is jumped to from the replacement-out stubs that are executed + when a thread reaches an activated replacement point. + + The purpose of asm_replacement_out is to read out the parts of the + execution state that cannot be accessed from C code, store this state, + and then call the C function replace_me. + + Stack layout: + 16 start of stack inside method to replace + 0 rplpoint * info on the replacement point that was reached + + NOTE: itmp3 has been clobbered by the replacement-out stub! + +*******************************************************************************/ + +/* some room to accomodate changes of the stack frame size during replacement */ + /* XXX we should find a cleaner solution here */ +#define REPLACEMENT_ROOM 512 + +#define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf) + + .ent asm_replacement_out + +asm_replacement_out: + /* create stack frame */ + daddiu sp,sp,-REPLACEMENT_STACK_OFFSET + + /* save registers in execution state */ + sd $0 ,( 0*8+offes_intregs)(sp) + sd $1 ,( 1*8+offes_intregs)(sp) + sd $2 ,( 2*8+offes_intregs)(sp) + sd $3 ,( 3*8+offes_intregs)(sp) + sd $4 ,( 4*8+offes_intregs)(sp) + sd $5 ,( 5*8+offes_intregs)(sp) + sd $6 ,( 6*8+offes_intregs)(sp) + sd $7 ,( 7*8+offes_intregs)(sp) + sd $8 ,( 8*8+offes_intregs)(sp) + sd $9 ,( 9*8+offes_intregs)(sp) + sd $10,(10*8+offes_intregs)(sp) + sd $11,(11*8+offes_intregs)(sp) + sd $12,(12*8+offes_intregs)(sp) + sd $13,(13*8+offes_intregs)(sp) + sd $14,(14*8+offes_intregs)(sp) + sd $15,(15*8+offes_intregs)(sp) + sd $16,(16*8+offes_intregs)(sp) + sd $17,(17*8+offes_intregs)(sp) + sd $18,(18*8+offes_intregs)(sp) + sd $19,(19*8+offes_intregs)(sp) + sd $20,(20*8+offes_intregs)(sp) + sd $21,(21*8+offes_intregs)(sp) + sd $22,(22*8+offes_intregs)(sp) + sd $23,(23*8+offes_intregs)(sp) + sd $24,(24*8+offes_intregs)(sp) + sd $25,(25*8+offes_intregs)(sp) + sd $26,(26*8+offes_intregs)(sp) + sd $27,(27*8+offes_intregs)(sp) + sd $28,(28*8+offes_intregs)(sp) + sd $29,(29*8+offes_intregs)(sp) + sd $30,(30*8+offes_intregs)(sp) + sd $31,(31*8+offes_intregs)(sp) + + sdc1 $f0 ,( 0*8+offes_fltregs)(sp) + sdc1 $f1 ,( 1*8+offes_fltregs)(sp) + sdc1 $f2 ,( 2*8+offes_fltregs)(sp) + sdc1 $f3 ,( 3*8+offes_fltregs)(sp) + sdc1 $f4 ,( 4*8+offes_fltregs)(sp) + sdc1 $f5 ,( 5*8+offes_fltregs)(sp) + sdc1 $f6 ,( 6*8+offes_fltregs)(sp) + sdc1 $f7 ,( 7*8+offes_fltregs)(sp) + sdc1 $f8 ,( 8*8+offes_fltregs)(sp) + sdc1 $f9 ,( 9*8+offes_fltregs)(sp) + sdc1 $f10,(10*8+offes_fltregs)(sp) + sdc1 $f11,(11*8+offes_fltregs)(sp) + sdc1 $f12,(12*8+offes_fltregs)(sp) + sdc1 $f13,(13*8+offes_fltregs)(sp) + sdc1 $f14,(14*8+offes_fltregs)(sp) + sdc1 $f15,(15*8+offes_fltregs)(sp) + sdc1 $f16,(16*8+offes_fltregs)(sp) + sdc1 $f17,(17*8+offes_fltregs)(sp) + sdc1 $f18,(18*8+offes_fltregs)(sp) + sdc1 $f19,(19*8+offes_fltregs)(sp) + sdc1 $f20,(20*8+offes_fltregs)(sp) + sdc1 $f21,(21*8+offes_fltregs)(sp) + sdc1 $f22,(22*8+offes_fltregs)(sp) + sdc1 $f23,(23*8+offes_fltregs)(sp) + sdc1 $f24,(24*8+offes_fltregs)(sp) + sdc1 $f25,(25*8+offes_fltregs)(sp) + sdc1 $f26,(26*8+offes_fltregs)(sp) + sdc1 $f27,(27*8+offes_fltregs)(sp) + sdc1 $f28,(28*8+offes_fltregs)(sp) + sdc1 $f29,(29*8+offes_fltregs)(sp) + sdc1 $f30,(30*8+offes_fltregs)(sp) + sdc1 $f31,(31*8+offes_fltregs)(sp) + + /* calculate sp of method */ + daddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8) + sd itmp1,(offes_sp)(sp) + + /* store pv */ + sd pv,(offes_pv)(sp) + + /* call replace_me */ + ld a0,-(2*8)(itmp1) /* arg0: rplpoint * */ + move a1,sp /* arg1: execution state */ + jal replace_me /* call C function replace_me */ + jal abort /* NEVER REACHED */ + + .end asm_replacement_out + +/* asm_replacement_in ********************************************************** + + This code writes the given execution state and jumps to the replacement + code. + + This function never returns! + + NOTE: itmp3 is not restored! + + C prototype: + void asm_replacement_in(executionstate *es); + +*******************************************************************************/ + + .ent asm_replacement_in + +asm_replacement_in: + /* a0 == executionstate *es */ + + /* set new sp and pv */ + ld sp,(offes_sp)(a0) + ld pv,(offes_pv)(a0) + + /* copy registers from execution state */ + /* $0 is zero */ + ld $1 ,( 1*8+offes_intregs)(a0) + ld $2 ,( 2*8+offes_intregs)(a0) + ld $3 ,( 2*8+offes_intregs)(a0) + /* a0 is loaded below */ + ld $5 ,( 5*8+offes_intregs)(a0) + ld $6 ,( 6*8+offes_intregs)(a0) + ld $7 ,( 7*8+offes_intregs)(a0) + ld $8 ,( 8*8+offes_intregs)(a0) + ld $9 ,( 9*8+offes_intregs)(a0) + ld $10,(10*8+offes_intregs)(a0) + ld $11,(11*8+offes_intregs)(a0) + ld $12,(12*8+offes_intregs)(a0) + ld $13,(13*8+offes_intregs)(a0) + ld $14,(14*8+offes_intregs)(a0) + ld $15,(15*8+offes_intregs)(a0) + ld $16,(16*8+offes_intregs)(a0) + ld $17,(17*8+offes_intregs)(a0) + ld $18,(18*8+offes_intregs)(a0) + ld $19,(19*8+offes_intregs)(a0) + ld $20,(20*8+offes_intregs)(a0) + ld $21,(21*8+offes_intregs)(a0) + ld $22,(22*8+offes_intregs)(a0) + ld $23,(23*8+offes_intregs)(a0) + ld $24,(24*8+offes_intregs)(a0) + ld $25,(25*8+offes_intregs)(a0) + ld $26,(26*8+offes_intregs)(a0) + ld $27,(27*8+offes_intregs)(a0) + ld $28,(28*8+offes_intregs)(a0) + /* $29 is sp */ + /* $30 is pv */ + ld $31,(31*8+offes_intregs)(a0) + + ldc1 $f0 ,( 0*8+offes_fltregs)(a0) + ldc1 $f1 ,( 1*8+offes_fltregs)(a0) + ldc1 $f2 ,( 2*8+offes_fltregs)(a0) + ldc1 $f3 ,( 3*8+offes_fltregs)(a0) + ldc1 $f4 ,( 4*8+offes_fltregs)(a0) + ldc1 $f5 ,( 5*8+offes_fltregs)(a0) + ldc1 $f6 ,( 6*8+offes_fltregs)(a0) + ldc1 $f7 ,( 7*8+offes_fltregs)(a0) + ldc1 $f8 ,( 8*8+offes_fltregs)(a0) + ldc1 $f9 ,( 9*8+offes_fltregs)(a0) + ldc1 $f10,(10*8+offes_fltregs)(a0) + ldc1 $f11,(11*8+offes_fltregs)(a0) + ldc1 $f12,(12*8+offes_fltregs)(a0) + ldc1 $f13,(13*8+offes_fltregs)(a0) + ldc1 $f14,(14*8+offes_fltregs)(a0) + ldc1 $f15,(15*8+offes_fltregs)(a0) + ldc1 $f16,(16*8+offes_fltregs)(a0) + ldc1 $f17,(17*8+offes_fltregs)(a0) + ldc1 $f18,(18*8+offes_fltregs)(a0) + ldc1 $f19,(19*8+offes_fltregs)(a0) + ldc1 $f20,(20*8+offes_fltregs)(a0) + ldc1 $f21,(21*8+offes_fltregs)(a0) + ldc1 $f22,(22*8+offes_fltregs)(a0) + ldc1 $f23,(23*8+offes_fltregs)(a0) + ldc1 $f24,(24*8+offes_fltregs)(a0) + ldc1 $f25,(25*8+offes_fltregs)(a0) + ldc1 $f26,(26*8+offes_fltregs)(a0) + ldc1 $f27,(27*8+offes_fltregs)(a0) + ldc1 $f28,(28*8+offes_fltregs)(a0) + ldc1 $f29,(29*8+offes_fltregs)(a0) + ldc1 $f30,(30*8+offes_fltregs)(a0) + ldc1 $f31,(31*8+offes_fltregs)(a0) + + /* load new pc */ + + ld itmp3,offes_pc(a0) + + /* load a0 */ + + ld a0,(4*8+offes_intregs)(a0) + + /* jump to new code */ + + jr itmp3 + + .end asm_replacement_in + /******************* function asm_initialize_thread_stack ********************** * * * u1* asm_initialize_thread_stack (void *func, u1 *stack); * @@ -729,4 +948,5 @@ compare_and_swap: * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */ diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index 7972ae4f1..19fa69dd6 100644 --- a/src/vm/jit/mips/codegen.c +++ b/src/vm/jit/mips/codegen.c @@ -35,7 +35,7 @@ This module generates MIPS machine code for a sequence of intermediate code commands (ICMDs). - $Id: codegen.c 4640 2006-03-16 17:24:18Z twisti $ + $Id: codegen.c 4654 2006-03-19 19:46:11Z edwin $ */ @@ -66,6 +66,7 @@ #include "vm/jit/jit.h" #include "vm/jit/patcher.h" #include "vm/jit/reg.h" +#include "vm/jit/replace.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" @@ -93,6 +94,7 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd) methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ builtintable_entry *bte; methoddesc *md; + rplpoint *replacementpoint; { s4 i, p, t, l; @@ -371,10 +373,30 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd) /* end of header generation */ + replacementpoint = cd->code->rplpoints; + /* walk through all basic blocks */ for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) { + /* handle replacement points */ + + if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) { + + /* 8-byte align pc */ + if ((ptrint)mcodeptr & 4) { + M_NOP; + } + + replacementpoint->pc = (u1*)(ptrint)((u1*)mcodeptr - cd->mcodebase); + replacementpoint++; + + assert(cd->lastmcodeptr <= (u1*)mcodeptr); + cd->lastmcodeptr = (u1*)cd->mcodeptr + 2*4; /* br + delay slot */ + } + + /* store relative start of block */ + bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase); if (bptr->flags >= BBREACHED) { @@ -4090,6 +4112,57 @@ gen_method: M_JMP(REG_ITMP3); M_NOP; } + + /* generate replacement-out stubs */ + + { + int i; + + replacementpoint = cd->code->rplpoints; + for (i=0; icode->rplpointcount; ++i, ++replacementpoint) { + /* check code segment size */ + + MCODECHECK(100); + + /* note start of stub code */ + + replacementpoint->outcode = (u1*) (ptrint)((u1*)mcodeptr - cd->mcodebase); + + /* make machine code for patching */ + + tmpmcodeptr = mcodeptr; + mcodeptr = (s4*) &(replacementpoint->mcode); + + disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1; + if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) { + *exceptionptr = + new_internalerror("Jump offset is out of range: %d > +/-%d", + disp, 0x00007fff); + return false; + } + M_BR(disp); + M_NOP; /* delay slot */ + + mcodeptr = tmpmcodeptr; + + /* create stack frame - 16-byte aligned */ + + M_ASUB_IMM(REG_SP, 2 * 8, REG_SP); + + /* push address of `rplpoint` struct */ + + disp = dseg_addaddress(cd, replacementpoint); + M_ALD(REG_ITMP3, REG_PV, disp); + M_AST(REG_ITMP3, REG_SP, 0 * 8); + + /* jump to replacement function */ + + disp = dseg_addaddress(cd, asm_replacement_out); + M_ALD(REG_ITMP3, REG_PV, disp); + M_JMP(REG_ITMP3); + M_NOP; /* delay slot */ + } + } } codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase)); diff --git a/src/vm/jit/mips/md.c b/src/vm/jit/mips/md.c index 7836913ca..06daee023 100644 --- a/src/vm/jit/mips/md.c +++ b/src/vm/jit/mips/md.c @@ -26,9 +26,9 @@ Authors: Christian Thalinger - Changes: + Changes: Edwin Steiner - $Id: md.c 4640 2006-03-16 17:24:18Z twisti $ + $Id: md.c 4654 2006-03-19 19:46:11Z edwin $ */ @@ -45,6 +45,8 @@ #include "toolbox/logging.h" #include "vm/global.h" #include "vm/jit/stacktrace.h" +#include "vm/options.h" /* XXX debug */ +#include "vm/jit/disass.h" /* XXX debug */ void docacheflush(u1 *p, long bytelen) @@ -193,7 +195,7 @@ u1 *md_codegen_findmethod(u1 *ra) #if SIZEOF_VOID_P == 8 assert((mcode >> 16) == 0x6739); -#else +#else assert((mcode >> 16) == 0x2739); #endif @@ -258,6 +260,36 @@ void md_dcacheflush(u1 *addr, s4 nbytes) } +/* md_patch_replacement_point ************************************************** + + Patch the given replacement point. + +*******************************************************************************/ + +void md_patch_replacement_point(rplpoint *rp) +{ + u8 mcode; + + /* save the current machine code */ + mcode = *(u8*)rp->pc; + + /* write the new machine code */ + *(u8*)(rp->pc) = rp->mcode; + + /* store saved mcode */ + rp->mcode = mcode; + + { + u1* u1ptr = rp->pc; + DISASSINSTR(u1ptr); + DISASSINSTR(u1ptr); + fflush(stdout); + } + + /* flush instruction cache */ + md_icacheflush(rp->pc,2*4); +} + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where @@ -269,4 +301,5 @@ void md_dcacheflush(u1 *addr, s4 nbytes) * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */ diff --git a/src/vm/jit/powerpc/asmpart.S b/src/vm/jit/powerpc/asmpart.S index e556950c5..ca493baaa 100644 --- a/src/vm/jit/powerpc/asmpart.S +++ b/src/vm/jit/powerpc/asmpart.S @@ -31,7 +31,7 @@ Changes: Christian Thalinger Edwin Steiner - $Id: asmpart.S 4653 2006-03-18 04:14:17Z edwin $ + $Id: asmpart.S 4654 2006-03-19 19:46:11Z edwin $ */ @@ -861,7 +861,7 @@ L_asm_wrapper_patcher_exception: and then call the C function replace_me. Stack layout: - 8 start of stack inside method to replace + 16 start of stack inside method to replace 0 rplpoint * info on the replacement point that was reached NOTE: itmp3 has been clobbered by the replacement-out stub! diff --git a/src/vm/jit/replace.c b/src/vm/jit/replace.c index 447014312..d4a19c893 100644 --- a/src/vm/jit/replace.c +++ b/src/vm/jit/replace.c @@ -283,7 +283,7 @@ void replace_activate_replacement_point(rplpoint *rp,rplpoint *target) rp->target = target; -#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT) +#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT) md_patch_replacement_point(rp); #endif } @@ -311,7 +311,7 @@ void replace_deactivate_replacement_point(rplpoint *rp) rp->target = NULL; -#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT) +#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT) md_patch_replacement_point(rp); #endif } @@ -441,7 +441,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es, /* in some cases the top stack slot is passed in REG_ITMP1 */ if ( (rp->type == BBTYPE_EXH) -#if defined(__ALPHA__) || defined(__POWERPC__) +#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || (rp->type == BBTYPE_SBR) #endif ) @@ -635,7 +635,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es, /* in some cases the top stack slot is passed in REG_ITMP1 */ if ( (rp->type == BBTYPE_EXH) -#if defined(__ALPHA__) || defined(__POWERPC__) +#if defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || (rp->type == BBTYPE_SBR) #endif ) @@ -814,7 +814,7 @@ void replace_me(rplpoint *rp,executionstate *es) /* enter new code */ -#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT) +#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT) asm_replacement_in(es); #endif abort(); -- 2.25.1