pike.git / src / code / amd64.c

version» Context lines:

pike.git/src/code/amd64.c:1197:    amd64_ins_branch_check_threads_etc(1);    func_start = PIKE_PC;   }      /* Called when the current function is done */   void amd64_end_function(int UNUSED(no_pc))   {    branch_check_threads_update_etc = 0;   }    + #ifdef MACHINE_CODE_STACK_FRAMES + static void amd64_pop_internal_c_frame() + { +  /* C.f. amd64_ins_start_function() */ +  mov_reg_reg(P_REG_RBP, P_REG_RSP); +  pop(P_REG_RBP); +  add_reg_imm(P_REG_RSP, 8); + } + #endif /* MACHINE_CODE_STACK_FRAMES */    -  + static void amd64_load_fp_reg(void); +  + void amd64_ins_start_function(void) + { + #ifdef MACHINE_CODE_STACK_FRAMES +  LABELS(); +  amd64_load_fp_reg(); +  /* Note: really mem16, but we & with PIKE_FRAME_RETURN_INTERNAL anyway */ +  mov_mem32_reg( fp_reg, OFFSETOF(pike_frame, flags), P_REG_RAX ); +  and_reg32_imm( P_REG_RAX, PIKE_FRAME_RETURN_INTERNAL); +  jz( &label_A ); +  +  /* This is an internal frame (no entry prologue), so we'll insert a +  minimal frame that can be used to unwind the C stack. */ +  mov_mem_reg(fp_reg, OFFSETOF(pike_frame, next), P_REG_RAX); +  mov_mem_reg(P_REG_RAX, OFFSETOF(pike_frame, return_addr), P_REG_RAX); +  push(P_REG_RAX); +  push(P_REG_RBP); +  mov_reg_reg(P_REG_RSP, P_REG_RBP); +  +  LABEL_A; + #endif /* MACHINE_CODE_STACK_FRAMES */ + } +    /* Machine code entry prologue.    *    * On entry:    * RDI: Pike_interpreter (ARG1_REG)    *    * During interpreting:    * R15: Pike_interpreter    */   void amd64_ins_entry(void)   {
pike.git/src/code/amd64.c:1735:    }    mov_imm_reg( (ptrdiff_t)branch_check_threads_etc, P_REG_RAX );    jmp_reg(P_REG_RAX); /* ret in BCTE will return to desired point. */    amd64_align();    }    if( !code_only )    {    LABEL_A;    /* Use C-stack for counter. We have padding added in entry */   #ifndef USE_VALGRIND + #ifndef MACHINE_CODE_STACK_FRAMES +  /* FIXME: Counter disabled when internal stack frames are used +  since RSP won't point to the entry-level stack frame with +  padding. Dunno if there should be a counter for every internal +  frame too? But that would double C-stack usage per internal +  frame due to 16 byte alignment. */    add_mem8_imm( P_REG_RSP, 0, 1 );    jno( &label_B );   #endif -  + #endif    call_rel_imm32( branch_check_threads_update_etc );   #ifndef USE_VALGRIND    LABEL_B;   #endif    }   }         void amd64_init_interpreter_state(void)   {
pike.git/src/code/amd64.c:1799:    {    mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RAX );    mov_mem_reg(sp_reg, SVAL(-2).value, P_REG_RBX );    }   }      void ins_f_byte(unsigned int b)   {    int flags;    void *addr; -  INT32 rel_addr = 0; +     LABELS();       b-=F_OFFSET;   #ifdef PIKE_DEBUG    if(b>255)    Pike_error("Instruction too big %d\n",b);   #endif    maybe_update_pc();       flags = instrs[b].flags;
pike.git/src/code/amd64.c:2708:    mov_mem32_reg( fp_reg, OFFSETOF(pike_frame, flags), P_REG_RAX );    and_reg32_imm( P_REG_RAX, PIKE_FRAME_RETURN_POP );    jnz( &label_C );    amd64_call_c_function( low_return );    jmp( &label_D );       LABEL_C;    amd64_call_c_function( low_return_pop );       LABEL_D; + #ifdef MACHINE_CODE_STACK_FRAMES +  /* We know that this is a RETURN_INTERNAL frame, so we must pop +  the C stack. */ +  amd64_pop_internal_c_frame(); + #endif /* MACHINE_CODE_STACK_FRAMES */    fp_reg = -1;    amd64_load_fp_reg();    mov_mem_reg( fp_reg, OFFSETOF(pike_frame, return_addr), P_REG_RAX );    jmp_reg( P_REG_RAX );    }    return;       case F_CLEAR_STRING_SUBTYPE:    ins_debug_instr_prologue(b, 0, 0);    amd64_load_sp_reg();
pike.git/src/code/amd64.c:2729:    P_REG_RAX);    /* NB: We only care about subtype 1! */    cmp_reg32_imm(P_REG_RAX, (1<<16)|PIKE_T_STRING);    jne(&label_A);    and_reg32_imm(P_REG_RAX, 0x1f);    mov_reg_mem32(P_REG_RAX,    sp_reg, OFFSETOF(svalue, tu.t.type) - sizeof(struct svalue));    LABEL_A;    return;    } +  +  if (instrs[b].flags & I_RETURN) { + #ifdef MACHINE_CODE_STACK_FRAMES +  amd64_load_fp_reg(); +  /* Load flags prior to calling the C opcode (which typically pops +  the frame in I_RETURN instructions. Note: really mem16, but we +  & with PIKE_FRAME_RETURN_INTERNAL below. */ +  mov_mem32_reg(fp_reg, OFFSETOF(pike_frame, flags), P_REG_RBX); + #endif /* MACHINE_CODE_STACK_FRAMES */ +  } +     amd64_call_c_opcode(addr,flags);       if (instrs[b].flags & I_RETURN) {    LABELS();       if ((b + F_OFFSET) == F_RETURN_IF_TRUE) {    /* Kludge. We must check if the ret addr is    * PC + JUMP_EPILOGUE_SIZE. */    mov_rip_imm_reg(JUMP_EPILOGUE_SIZE, P_REG_RCX);    }    cmp_reg_imm(P_REG_RAX, -1);    jne(&label_A);    amd64_return_from_function();    LABEL_A;       if ((b + F_OFFSET) == F_RETURN_IF_TRUE) {    /* Kludge. We must check if the ret addr is    * orig_addr + JUMP_EPILOGUE_SIZE. */    cmp_reg_reg( P_REG_RAX, P_REG_RCX ); -  je( &label_B ); -  jmp_reg(P_REG_RAX); +  je( &label_C ); +  } +  + #ifdef MACHINE_CODE_STACK_FRAMES +  /* Check if we should pop C stack. The flags word of the frame +  prior to calling the C opcode is loaded into RBX above. */ +  and_reg32_imm(P_REG_RBX, PIKE_FRAME_RETURN_INTERNAL); +  jz( &label_B ); +  amd64_pop_internal_c_frame(); +     LABEL_B; -  + #endif /* MACHINE_CODE_STACK_FRAMES */ +  +  jmp_reg(P_REG_RAX); +  +  LABEL_C;    return;    } -  } +     if (flags & I_JUMP) {    jmp_reg(P_REG_RAX);    }   }      int amd64_ins_f_jump(unsigned int op, int backward_jump)   {    int flags;    void *addr;    int off = op - F_OFFSET;
pike.git/src/code/amd64.c:3994:    ins_f_byte_with_2_args(F_EXTERNAL, b, c);    return;       case F_CLEAR_N_LOCAL:    {    LABELS();    ins_debug_instr_prologue(a-F_OFFSET, b, c);    amd64_load_fp_reg();    mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX);    add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); -  if( c > 1 ) +  if( c > 1 ) { +  push(P_REG_RBP);    add_reg_imm_reg(P_REG_RBX, c*sizeof(struct svalue), P_REG_RBP ); -  +  }       LABEL_A;    amd64_free_svalue(P_REG_RBX, 0);    mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type));    mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer));    if( c > 1 )    {    add_reg_imm(P_REG_RBX, sizeof(struct svalue ) );    cmp_reg_reg( P_REG_RBX, P_REG_RBP );    jne(&label_A); -  +  pop(P_REG_RBP);    }    }    return;       case F_LOCAL_LOCAL_INDEX:    {    LABELS();    ins_debug_instr_prologue(a-F_OFFSET, b, c);    amd64_load_fp_reg();    mov_mem_reg( fp_reg, OFFSETOF(pike_frame,locals), P_REG_RDX);