core/x86/mangle.c
/* Returns the amount of data pushed.  Does NOT fix up the xsp value pushed
 * to be the value prior to any pushes for x64 as no caller needs that
 * currently (they all build a dr_mcontext_t and have to do further xsp
 * fixups anyway).
 * Includes xmm0-5 for PR 264138.
 * If stack_align16 is true, assumes the stack pointer is currently aligned
 * on a 16-byte boundary.
 */
Returns the amount of data pushed.  Does NOT fix up the xsp value pushed
to be the value prior to any pushes for x64 as no caller needs that
currently (they all build a dr_mcontext_t and have to do further xsp
fixups anyway).
Returns the amount of data pushed . Does NOT fix up the xsp value pushed to be the value prior to any pushes for x64 as no caller needs that currently ( they all build a dr_mcontext_t and have to do further xsp fixups anyway ) .
uint
insert_push_all_registers(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
                          bool stack_align16)
{
    PRE(ilist, instr, INSTR_CREATE_lea
        (dcontext, opnd_create_reg(REG_XSP),
         OPND_CREATE_MEM_lea(REG_XSP, REG_NULL, 0, - XMM_SLOTS_SIZE)));
    if (preserve_xmm_caller_saved()) {
        int i;
        uint opcode = (proc_has_feature(FEATURE_SSE2) ?
                       (stack_align16 ? OP_movdqa : OP_movdqu) :
                       (stack_align16 ? OP_movaps : OP_movups));
        ASSERT(proc_has_feature(FEATURE_SSE));
        for (i=0; i<NUM_XMM_SAVED; i++) {
            PRE(ilist, instr, instr_create_1dst_1src
                (dcontext, opcode,
                 opnd_create_base_disp(REG_XSP, REG_NULL, 0, i*XMM_REG_SIZE, OPSZ_16),
                 opnd_create_reg(REG_XMM0 + (reg_id_t)i)));
        }
        ASSERT(i*XMM_REG_SIZE == XMM_SAVED_SIZE);
        ASSERT(XMM_SAVED_SIZE <= XMM_SLOTS_SIZE);
    }
#ifdef X64
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R15)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R14)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R13)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R12)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R11)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R10)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R9)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_R8)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RAX)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RCX)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RDX)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RBX)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RSP)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RBP)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RSI)));
    PRE(ilist, instr, INSTR_CREATE_push(dcontext, opnd_create_reg(REG_RDI)));
    return 16*XSP_SZ + XMM_SLOTS_SIZE;
#else
    PRE(ilist, instr, INSTR_CREATE_pusha(dcontext));
    return 8*XSP_SZ + XMM_SLOTS_SIZE;
#endif
}
uint insert_push_all_registers ( dcontext_t * dcontext , instrlist_t * ilist , instr_t * instr , bool stack_align16 ) { PRE ( ilist , instr , INSTR_CREATE_lea ( dcontext , opnd_create_reg ( REG_XSP ) , OPND_CREATE_MEM_lea ( REG_XSP , REG_NULL , 0 , - XMM_SLOTS_SIZE ) ) ) ; if ( preserve_xmm_caller_saved ( ) ) { int i ; uint opcode = ( proc_has_feature ( FEATURE_SSE2 ) ? ( stack_align16 ? OP_movdqa : OP_movdqu ) : ( stack_align16 ? OP_movaps : OP_movups ) ) ; ASSERT ( proc_has_feature ( FEATURE_SSE ) ) ; for ( i = 0 ; i < NUM_XMM_SAVED ; i ++ ) { PRE ( ilist , instr , instr_create_1dst_1src ( dcontext , opcode , opnd_create_base_disp ( REG_XSP , REG_NULL , 0 , i * XMM_REG_SIZE , OPSZ_16 ) , opnd_create_reg ( REG_XMM0 + ( reg_id_t ) i ) ) ) ; } ASSERT ( i * XMM_REG_SIZE == XMM_SAVED_SIZE ) ; ASSERT ( XMM_SAVED_SIZE <= XMM_SLOTS_SIZE ) ; } #ifdef X64 PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R15 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R14 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R13 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R12 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R11 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R10 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R9 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_R8 ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RAX ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RCX ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RDX ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RBX ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RSP ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RBP ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RSI ) ) ) ; PRE ( ilist , instr , INSTR_CREATE_push ( dcontext , opnd_create_reg ( REG_RDI ) ) ) ; return 16 * XSP_SZ + XMM_SLOTS_SIZE ; #else PRE ( ilist , instr , INSTR_CREATE_pusha ( dcontext ) ) ; return 8 * XSP_SZ + XMM_SLOTS_SIZE ; #endif }
Returns the amount of data pushed.
Returns the amount of data pushed .
/* PR 264138: we must preserve xmm0-5 if on a 64-bit kernel */ /* PR 266305: see discussion in emit_fcache_enter_shared on
         * which opcode is better.  Note that the AMD optimization
         * guide says to use movlps+movhps for unaligned stores, but
         * for simplicity and smaller code I'm using movups anyway.
         */ /* keep dr_mcontext_t order */ /* we do NOT match pusha xsp value */