pike.git / src / code / amd64.c

version» Context lines:

pike.git/src/code/amd64.c:645:    else    {    opcode( 0x83 );    modrm( 3,7,reg);    ib( imm32 );    }   }      static void cmp_reg_reg( enum amd64_reg reg1, enum amd64_reg reg2 )   { -  rex(1, reg1, 0, reg2); +  rex(1, reg2, 0, reg1);    opcode( 0x39 ); -  modrm( 3, reg1, reg2 ); +  modrm( 3, reg2, reg1 );   }      static int jmp_rel_imm32( int addr )   {    int rel = addr - (PIKE_PC + 5); // counts from the next instruction    int res;    opcode( 0xe9 );    res = PIKE_PC;    id( rel );    return res;
pike.git/src/code/amd64.c:899:    * PIKE_PC is not reliable as a marker since constant evaluations    * are also done using this code. So for now, waste ~20 bytes per    * function in the program code.    */    if( store_lines )    amd64_ins_branch_check_threads_etc(1);    func_start = PIKE_PC;   }      /* Called when the current function is done */ - void amd64_end_function(int no_pc) + void amd64_end_function(int UNUSED(no_pc))   {    branch_check_threads_update_etc = 0;   }         /* Machine code entry prologue.    *    * On entry:    * RDI: Pike_interpreter (ARG1_REG)    *
pike.git/src/code/amd64.c:1027:   {    LABELS();    if( reg == REG_RAX )    Pike_fatal("Using RAX in push_svaluep not supported\n" );    amd64_load_sp_reg();    mov_mem_reg(reg, OFFSETOF(svalue, type), REG_RAX);    mov_mem_reg(reg, OFFSETOF(svalue, u.refs), REG_RCX);    mov_reg_mem(REG_RAX, sp_reg, spoff*sizeof(struct svalue)+OFFSETOF(svalue, type));    and_reg_imm(REG_RAX, 0x1f);    mov_reg_mem(REG_RCX, sp_reg, spoff*sizeof(struct svalue)+OFFSETOF(svalue, u.refs)); -  cmp_reg32_imm(REG_RAX, MAX_REF_TYPE); -  jg(&label_A); +  cmp_reg32_imm(REG_RAX, MIN_REF_TYPE); +  jl(&label_A);    add_imm_mem( 1, REG_RCX, OFFSETOF(pike_string, refs));    LABEL_A;   }      static void amd64_push_svaluep(int reg)   {    amd64_push_svaluep_to( reg, 0 );    amd64_add_sp( 1 );   }   
pike.git/src/code/amd64.c:1089:   }      static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref )   {    LABELS();    if( src == REG_RAX )    Pike_fatal("Clobbering RAX for free-svalue\n");    /* load type -> RAX */    mov_sval_type( src, REG_RAX );    -  /* if RAX > MAX_REF_TYPE+1 */ -  cmp_reg32_imm( REG_RAX,MAX_REF_TYPE); -  jg( &label_A ); +  and_reg_imm(REG_RAX, ~(MIN_REF_TYPE - 1));    -  +  /* if RAX != MIN_REF_TYPE */ +  cmp_reg32_imm( REG_RAX,MIN_REF_TYPE); +  jne( &label_A ); +     /* Load pointer to refs -> RAX */    mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);    /* if( !--*RAX ) */    add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), -1);    if( !guaranteed_ref )    {    /* We need to see if refs got to 0. */    jnz( &label_A );    /* if so, call really_free_svalue */    if( src != ARG1_REG )    mov_reg_reg( src, ARG1_REG );    amd64_call_c_function(really_free_svalue);    }    LABEL_A;   }    - /* Type already in RAX */ + /* Type already in register. Note: Clobbers the type register. */   static void amd64_free_svalue_type(enum amd64_reg src, enum amd64_reg type,    int guaranteed_ref )   {    LABELS(); -  /* if type > MAX_REF_TYPE+1 */ +  /* if type < MIN_REF_TYPE+1 */    if( src == REG_RAX )    Pike_fatal("Clobbering RAX for free-svalue\n");    -  cmp_reg32_imm(type,MAX_REF_TYPE); -  jg( &label_A ); +  and_reg_imm(type, ~(MIN_REF_TYPE - 1));    -  +  cmp_reg32_imm(type,MIN_REF_TYPE); +  jne( &label_A ); +     /* Load pointer to refs -> RAX */    mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);    /* if( !--*RAX ) */    add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), -1);    if( !guaranteed_ref )    {    /* We need to see if refs got to 0. */    jnz( &label_A );    /* if so, call really_free_svalue */    if( src != ARG1_REG )
pike.git/src/code/amd64.c:1146:      void amd64_ref_svalue( enum amd64_reg src, int already_have_type )   {    LABELS();    if( src == REG_RAX ) Pike_fatal("Clobbering src in ref_svalue\n");    if( !already_have_type )    mov_sval_type( src, REG_RAX );    else    and_reg_imm( REG_RAX, 0x1f );    -  /* if RAX > MAX_REF_TYPE+1 */ -  cmp_reg32_imm(REG_RAX, MAX_REF_TYPE ); -  jg( &label_A ); +  /* if RAX > MIN_REF_TYPE+1 */ +  cmp_reg32_imm(REG_RAX, MIN_REF_TYPE ); +  jl( &label_A );    /* Load pointer to refs -> RAX */    mov_mem_reg( src, OFFSETOF(svalue, u.refs), REG_RAX);    /* *RAX++ */    add_mem32_imm( REG_RAX, OFFSETOF(pike_string,refs), 1);    LABEL_A;   }      void amd64_assign_local( int b )   {    amd64_load_fp_reg();
pike.git/src/code/amd64.c:1413:    add_mem_imm( REG_RAX, 0, 0x80 );    }    mov_imm_reg( (ptrdiff_t)branch_check_threads_etc, REG_RAX );    jmp_reg(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    add_mem8_imm( REG_RSP, 0, 1 );    jno( &label_B ); -  + #endif    call_rel_imm32( branch_check_threads_update_etc ); -  + #ifndef USE_VALGRIND    LABEL_B; -  + #endif    }   }         void amd64_init_interpreter_state(void)   {    instrs[F_CATCH - F_OFFSET].address = inter_return_opcode_F_CATCH;   }      static void amd64_return_from_function()
pike.git/src/code/amd64.c:1922:    amd64_load_fp_reg();    /* Note: really mem16, but we & with PIKE_FRAME_RETURN_INTERNAL anyway */    mov_mem32_reg( fp_reg, OFFSETOF(pike_frame, flags), REG_RAX );    and_reg_imm( REG_RAX, PIKE_FRAME_RETURN_INTERNAL);    jnz( &label_A );    /* So, it is just a normal return. */    LABEL_B;    /* Actually return */    flush_dirty_regs();    amd64_return_from_function(); -  +  /* */    LABEL_A; -  amd64_call_c_opcode(addr,flags); - #if 0 -  /* Can this happen? +  /* We should jump to the given address. */ +  mov_mem32_reg( fp_reg, OFFSETOF(pike_frame, flags), REG_RAX ); +  and_reg_imm( REG_RAX, PIKE_FRAME_RETURN_POP ); +  jnz( &label_C ); +  amd64_call_c_function( low_return ); +  jmp( &label_D );    -  It seems to work without it, and from the code it looks like it -  should never happen, so.. -  */ -  cmp_reg_imm(REG_RAX, -1); -  je(&label_B); - #endif -  jmp_reg(REG_RAX); +  LABEL_C; +  amd64_call_c_function( low_return_pop ); +  +  LABEL_D; +  fp_reg = -1; +  amd64_load_fp_reg(); +  mov_mem_reg( fp_reg, OFFSETOF(pike_frame, return_addr), REG_RAX ); +  jmp_reg( REG_RAX );    }    return; -  +     case F_CLEAR_STRING_SUBTYPE:    ins_debug_instr_prologue(b, 0, 0);    amd64_load_sp_reg();    mov_mem32_reg(sp_reg, OFFSETOF(svalue, type) - sizeof(struct svalue),    REG_RAX);    /* NB: We only care about subtype 1! */    cmp_reg32_imm(REG_RAX, (1<<16)|PIKE_T_STRING);    jne(&label_A);    and_reg_imm(REG_RAX, 0x1f);    mov_reg_mem32(REG_RAX,
pike.git/src/code/amd64.c:2069:    return jnz_imm_rel32(0);       case F_FOREACH:    START_JUMP();    /* -4: array    -3: lvalue[0]    -2: lvalue[1]    -1: counter    */    amd64_load_sp_reg(); +  mov_mem8_reg( sp_reg, -4*sizeof(struct svalue), REG_RBX ); +  cmp_reg32_imm( REG_RBX, PIKE_T_ARRAY ); +  jne(&label_D);    mov_mem_reg( sp_reg, -1*sizeof(struct svalue)+8, REG_RAX );    mov_mem_reg( sp_reg, -4*sizeof(struct svalue)+8, REG_RBX );    mov_mem32_reg( REG_RBX, OFFSETOF(array,size), REG_RCX );    cmp_reg_reg( REG_RAX, REG_RCX );    je(&label_A);       /* increase counter */    add_mem_imm( sp_reg, -1*(int)sizeof(struct svalue)+8, 1 );       /* get item */
pike.git/src/code/amd64.c:2102:    pop( REG_RDX );       /* Assign new value. */    mov_mem_reg( REG_RBX, 0, REG_RAX );    mov_mem_reg( REG_RBX, 8, REG_RCX );    mov_reg_mem( REG_RAX, REG_RDX, 0 );    mov_reg_mem( REG_RCX, REG_RDX, 8 );       /* inc refs? */    and_reg_imm( REG_RAX, 0x1f ); -  cmp_reg32_imm(REG_RAX, MAX_REF_TYPE); -  jg( &label_B ); +  cmp_reg32_imm(REG_RAX, MIN_REF_TYPE); +  jl( &label_B );    add_imm_mem( 1, REG_RCX, OFFSETOF(pike_string, refs));    jmp( &label_B );    -  +  LABEL_D; +  /* Bad arg 1. Let the C opcode throw the error. */ +  amd64_call_c_opcode(instrs[off].address, flags); +  /* NOT_REACHED */ +     LABEL_C;    add_reg_imm_reg( sp_reg, -3*sizeof(struct svalue), ARG1_REG );    mov_reg_reg( REG_RBX, ARG2_REG );    amd64_call_c_function( assign_lvalue );    jmp(&label_B);       LABEL_A;    mov_imm_reg( 0, REG_RBX );    LABEL_B;    test_reg(REG_RBX);
pike.git/src/code/amd64.c:2182:    shl_reg32_reg(REG_RBX, REG_RCX);    and_reg_imm(REG_RBX, (BIT_FUNCTION|BIT_OBJECT|BIT_FLOAT));    jnz( &label_A );       mov_mem_reg( sp_reg, -sizeof(struct svalue)+8, REG_RBX );    sub_reg_mem( REG_RBX, sp_reg, -sizeof(struct svalue)*2+8);    /* RBX will now be 0 if they are equal.*/       /* Optimization: The types are equal, pop_stack can be greatly    * simplified if they are <= max_ref_type */ -  cmp_reg32_imm( REG_RCX,MAX_REF_TYPE+1); -  jl( &label_B ); +  cmp_reg32_imm( REG_RCX,MIN_REF_TYPE); +  jge( &label_B );    /* cheap pop. We know that both are > max_ref_type */    amd64_add_sp( -2 );    jmp( &label_D );       LABEL_A; /* Fallback - call opcode. */    amd64_call_c_opcode( instrs[F_BRANCH_WHEN_NE-F_OFFSET].address,    instrs[F_BRANCH_WHEN_NE-F_OFFSET].flags );    amd64_load_sp_reg();    /* Opcode returns 0 if equal, -1 if not. */    mov_reg_reg(REG_RAX, REG_RBX);
pike.git/src/code/amd64.c:2336:    LABELS();    ins_debug_instr_prologue(a-F_OFFSET, b, 0);    amd64_load_sp_reg();    mov_mem8_reg( sp_reg, -1*sizeof(struct svalue), REG_RAX );    cmp_reg32_imm( REG_RAX, PIKE_T_ARRAY );    jne( &label_A );       mov_mem_reg( sp_reg, -1*sizeof(struct svalue)+8, REG_RDX ); /* u.array */    /* -> arr[sizeof(arr)-b] */    mov_mem32_reg( REG_RDX, OFFSETOF(array,size), REG_RCX ); -  mov_imm_reg( b, REG_RBX); -  cmp_reg_reg( REG_RCX, REG_RBX ); -  jg( &label_A ); /* b > RBX, index outside array */ -  shl_reg_imm( REG_RBX, 4 ); +  cmp_reg32_imm( REG_RCX, b ); +  jle( &label_A ); /* RCX <= b, index outside array */ +  mov_imm_reg( b * sizeof(struct svalue), REG_RBX);    add_reg_mem( REG_RBX, REG_RDX, OFFSETOF(array,item) );       /* This overwrites the array. */    amd64_push_svaluep_to( REG_RBX, -1 );       /* We know it's an array. */    add_mem32_imm( REG_RDX, OFFSETOF(array,refs), -1);    jnz( &label_C );    mov_reg_reg( REG_RDX, ARG1_REG );    amd64_call_c_function(really_free_array);
pike.git/src/code/amd64.c:2389:    jne( &label_A );       /* Array and int index. */    mov_mem32_reg( REG_RCX, OFFSETOF(array,size), REG_RDX );    cmp_reg32_imm( REG_RBX, 0 ); jge( &label_D );    /* less than 0, add size */    add_reg_reg( REG_RBX, REG_RDX );       LABEL_D;    cmp_reg32_imm( REG_RBX, 0 ); jl( &label_B ); // <0 -  cmp_reg_reg( REG_RBX, REG_RCX); jge( &label_B ); // >size +  cmp_reg_reg( REG_RBX, REG_RCX); jge( &label_B ); // >=size       /* array, index inside array. push item, swap, pop, done */    mov_mem_reg( REG_RCX, OFFSETOF(array,item), REG_RCX );    shl_reg_imm( REG_RBX, 4 );    add_reg_reg( REG_RBX, REG_RCX );    amd64_push_svaluep_to( REG_RBX, -1 );    jmp( &label_C );       LABEL_A;   #if 0
pike.git/src/code/amd64.c:3007:    ins_debug_instr_prologue(a-F_OFFSET, b, c);    amd64_load_fp_reg();    mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);    add_reg_imm( ARG1_REG,b*sizeof(struct svalue) );    mov_reg_reg( ARG1_REG, REG_RBX );    amd64_free_svalue(ARG1_REG, 0);    mov_imm_mem(c, REG_RBX, OFFSETOF(svalue, u.integer));    mov_imm_mem32(PIKE_T_INT, REG_RBX, OFFSETOF(svalue, type));    return;    +  case F_LOCAL_2_GLOBAL: +  ins_debug_instr_prologue(a-F_OFFSET, b, 0); +  amd64_load_fp_reg(); +  amd64_load_sp_reg(); +  mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), ARG3_REG ); +  add_reg_imm( ARG3_REG, c*sizeof(struct svalue) ); +  mov_mem_reg(fp_reg, OFFSETOF(pike_frame, current_object), ARG1_REG); +  mov_mem_reg(fp_reg, OFFSETOF(pike_frame,context), ARG2_REG); +  mov_mem16_reg(ARG2_REG, OFFSETOF(inherit, identifier_level), ARG2_REG); +  add_reg_imm( ARG2_REG, b ); +  amd64_call_c_function( object_low_set_index ); +  return; +     case F_LOCAL_2_LOCAL:    ins_debug_instr_prologue(a-F_OFFSET, b, c);    if( b != c )    {    amd64_load_fp_reg();    mov_mem_reg( fp_reg, OFFSETOF(pike_frame, locals), REG_RBX );    add_reg_imm( REG_RBX, b*sizeof(struct svalue) );    /* RBX points to dst. */    amd64_free_svalue( REG_RBX, 0 );    /* assign rbx[0] = rbx[c-b] */
pike.git/src/code/amd64.c:3054:    ins_debug_instr_prologue(a-F_OFFSET, b, c);    amd64_load_fp_reg();    amd64_load_sp_reg();    mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), ARG1_REG);    add_reg_imm(ARG1_REG, b*sizeof(struct svalue));    jmp(&label_A);    LABEL_B;    amd64_push_int(0, c);    LABEL_A;    cmp_reg_reg(sp_reg, ARG1_REG); -  jg(&label_B); +  jl(&label_B);    }    return;       case F_INIT_FRAME:    ins_debug_instr_prologue(a-F_OFFSET, b, c);    amd64_load_fp_reg();       if(OFFSETOF(pike_frame, num_locals) != OFFSETOF(pike_frame, num_args)-2 )    Pike_fatal("This code does not with unless num_args\n"    "directly follows num_locals in struct pike_frame\n");