pike.git / src / code / amd64.c

version» Context lines:

pike.git/src/code/amd64.c:38:   #define REG_RDI MISSING_P_   #define REG_R8 MISSING_P_   #define REG_R9 MISSING_P_   #define REG_R10 MISSING_P_   #define REG_R11 MISSING_P_   #define REG_R12 MISSING_P_   #define REG_R13 MISSING_P_   #define REG_R14 MISSING_P_   #define REG_R15 MISSING_P_    + struct soff { int off; int type; int value; };    -  + static struct soff SVAL(int i) + { +  struct soff res; +  res.off = res.type = i*sizeof(struct svalue); +  res.value = res.type + 8; +  return res; + } +    /* Register encodings */   enum amd64_reg {P_REG_RAX = 0, P_REG_RBX = 3, P_REG_RCX = 1, P_REG_RDX = 2,    P_REG_RSP = 4, P_REG_RBP = 5, P_REG_RSI = 6, P_REG_RDI = 7,    P_REG_R8 = 8, P_REG_R9 = 9, P_REG_R10 = 10, P_REG_R11 = 11,    P_REG_R12 = 12, P_REG_R13 = 13, P_REG_R14 = 14, P_REG_R15 = 15,    P_REG_INVALID = -1,       P_REG_XMM0 = 0, P_REG_XMM1 = 1, P_REG_XMM2 = 2, P_REG_XMM3 = 3,    P_REG_XMM4 = 4, P_REG_XMM5 = 5, P_REG_XMM6 = 6, P_REG_XMM7 = 7,    P_REG_XMM8 = 8, P_REG_XMM9 = 9, P_REG_XMM10=10, P_REG_XMM11=11,
pike.git/src/code/amd64.c:207:    add_to_program(0x58 + (reg & 0x07));   }      static void mov_reg_reg(enum amd64_reg from_reg, enum amd64_reg to_reg )   {    rex( 1, from_reg, 0, to_reg );    opcode( 0x89 );    modrm( 3, from_reg, to_reg );   }    + static void mov_reg32_reg(enum amd64_reg from_reg, enum amd64_reg to_reg ) + { +  rex( 0, from_reg, 0, to_reg ); +  opcode( 0x89 ); +  modrm( 3, from_reg, to_reg ); + } +    #define PUSH_INT(X) ins_int((INT32)(X), (void (*)(char))add_to_program)   static void low_mov_mem_reg(enum amd64_reg from_reg, ptrdiff_t offset,    enum amd64_reg to_reg)   {    opcode( 0x8b );    offset_modrm_sib(offset, to_reg, from_reg );   }      static void mov_mem_reg( enum amd64_reg from_reg, ptrdiff_t offset, enum amd64_reg to_reg )   {
pike.git/src/code/amd64.c:1071:    mov_mem_reg(Pike_interpreter_reg,    OFFSETOF(Pike_interpreter_struct, mark_stack_pointer),    PIKE_MARK_SP_REG);    mark_sp_reg = PIKE_MARK_SP_REG;    }   }         static void mov_sval_type(enum amd64_reg src, enum amd64_reg dst )   { -  mov_mem8_reg( src, OFFSETOF(svalue, tu.t.type), dst); +  mov_mem8_reg( src, SVAL(0).type, dst);   /* and_reg32_imm( dst, 0x1f );*/   }         #if 0   static void svalue_is_referenced(enum amd64_reg in, struct label *not )   {    /* bit 4 set, and no higher bit set (all with 8bit values). */    /* aka: type & 248 == 8. Incidentally, 248 is equal to -8 in signed 8bit*/    and_reg_imm(in,-8);
pike.git/src/code/amd64.c:1111:      static void update_arg2(INT32 value)   {    mov_imm_reg(value, ARG2_REG);    /* FIXME: Alloc stack space on NT. */   }      static void amd64_add_sp( int num )   {    amd64_load_sp_reg(); -  add_reg_imm( sp_reg, sizeof(struct svalue)*num); +  add_reg_imm( sp_reg, num * sizeof(struct svalue));    dirty_regs |= 1 << PIKE_SP_REG;    flush_dirty_regs(); /* FIXME: Need to change LABEL handling to remove this */   }      static void amd64_add_mark_sp( int num )   {    amd64_load_mark_sp_reg(); -  add_reg_imm( mark_sp_reg, sizeof(struct svalue*)*num); +  add_reg_imm( mark_sp_reg, num * sizeof(struct svalue*));    dirty_regs |= 1 << PIKE_MARK_SP_REG;    flush_dirty_regs(); /* FIXME: Need to change LABEL handling to remove this */   }      /* Note: Uses RAX and RCX internally. reg MUST not be P_REG_RAX. */   static void amd64_push_svaluep_to(int reg, int spoff)   {    LABELS();    if( reg == P_REG_RAX )    Pike_fatal("Using RAX in push_svaluep not supported\n" );    amd64_load_sp_reg();    mov_mem_reg(reg, OFFSETOF(svalue, tu.t.type), P_REG_RAX);    mov_mem_reg(reg, OFFSETOF(svalue, u.refs), P_REG_RCX); -  mov_reg_mem(P_REG_RAX, sp_reg, -  spoff*sizeof(struct svalue)+OFFSETOF(svalue, tu.t.type)); -  mov_reg_mem(P_REG_RCX, sp_reg, -  spoff*sizeof(struct svalue)+OFFSETOF(svalue, u.refs)); +  mov_reg_mem(P_REG_RAX, sp_reg, SVAL(spoff).type); +  mov_reg_mem(P_REG_RCX, sp_reg, SVAL(spoff).value);    and_reg32_imm(P_REG_RAX, MIN_REF_TYPE);    jz(&label_A);    add_imm_mem( 1, P_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 );   }      static void amd64_push_int(INT64 value, int subtype)   {    amd64_load_sp_reg(); -  mov_imm_mem((subtype<<16) + PIKE_T_INT, sp_reg, OFFSETOF(svalue, tu.t.type)); -  mov_imm_mem(value, sp_reg, OFFSETOF(svalue, u.integer)); +  mov_imm_mem((subtype<<16) + PIKE_T_INT, sp_reg, SVAL(0).type); +  mov_imm_mem(value, sp_reg, SVAL(0).value);    amd64_add_sp( 1 );   }      static void amd64_push_int_reg(enum amd64_reg reg )   {    amd64_load_sp_reg();    mov_imm_mem( PIKE_T_INT, sp_reg, OFFSETOF(svalue, tu.t.type));    mov_reg_mem( reg, sp_reg, OFFSETOF(svalue, u.integer));    amd64_add_sp( 1 );   }
pike.git/src/code/amd64.c:1204:    }    amd64_add_mark_sp( 1 );   }      static void amd64_call_c_function(void *addr)   {    flush_dirty_regs();    call_imm(addr);   }    - static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref ) + static void amd64_free_svalue_off(enum amd64_reg src, int off, int guaranteed_ref )   {    LABELS();    if( src == P_REG_RAX )    Pike_fatal("Clobbering RAX for free-svalue\n");    /* load type -> RAX */ -  mov_sval_type( src, P_REG_RAX ); -  +  mov_mem8_reg( src, off, P_REG_RAX );    and_reg_imm(P_REG_RAX, MIN_REF_TYPE);    jz( &label_A );       /* Load pointer to refs -> RAX */ -  mov_mem_reg( src, OFFSETOF(svalue, u.refs), P_REG_RAX); +  mov_mem_reg( src,off+OFFSETOF(svalue, u.refs), P_REG_RAX);    /* if( !--*RAX ) */    add_mem32_imm( P_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 ); +  add_reg_imm_reg( src, off, ARG1_REG );    amd64_call_c_function(really_free_svalue);    }    LABEL_A;   }    -  + static void amd64_free_svalue(enum amd64_reg src, int guaranteed_ref ) + { +  amd64_free_svalue_off(src,0,guaranteed_ref); + } +    /* 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 < MIN_REF_TYPE+1 */    if( src == P_REG_RAX )    Pike_fatal("Clobbering RAX for free-svalue\n");       and_reg32_imm(type, MIN_REF_TYPE);
pike.git/src/code/amd64.c:1529: Inside #if undefined(USE_VALGRIND)
   call_rel_imm32( branch_check_threads_update_etc );   #ifndef USE_VALGRIND    LABEL_B;   #endif    }   }         void amd64_init_interpreter_state(void)   { + #ifdef PIKE_DEBUG +  if( PIKE_T_INT != 0 ) +  Pike_fatal("assumption failed: pike_t_int == 0\n"); +  if( sizeof(struct svalue) != 16 ) +  Pike_fatal("assumption failed: sizeof svalue != 16\n"); +  if( OFFSETOF(svalue,tu.t.type) != 0 ) +  Pike_fatal("assumption failed: offsetof(svalue.tu.t.type) != 0\n"); +  if( OFFSETOF(svalue,u.integer) != 8 ) +  Pike_fatal("assumption failed: offsetof(svalue.u.integer) != 8\n"); + #endif    instrs[F_CATCH - F_OFFSET].address = inter_return_opcode_F_CATCH;   }      static void amd64_return_from_function()   {    if( ret_for_func )    {    jmp_rel_imm( ret_for_func );    }    else
pike.git/src/code/amd64.c:1918:    }    return;    case F_CATCH:    {    /* Special argument for the F_CATCH instruction. */    addr = inter_return_opcode_F_CATCH;    mov_rip_imm_reg(0, ARG1_REG); /* Address for the POINTER. */    rel_addr = PIKE_PC;    }    break; +  +  /* sp-1 = undefinedp(sp-1) */ +  case F_UNDEFINEDP: +  { +  LABELS(); +  ins_debug_instr_prologue(b, 0, 0); +  amd64_load_sp_reg(); +  +  mov_mem32_reg( sp_reg, SVAL(-1).type, P_REG_RAX ); +  cmp_reg32_imm( P_REG_RAX, 1<<16 | PIKE_T_INT ); +  jne( &label_A ); +  mov_imm_mem( 1, sp_reg,SVAL(-1).value); +  jmp( &label_B ); +  LABEL_A; +  amd64_free_svalue_off( sp_reg, SVAL(-1).off,0 ); +  mov_imm_mem( 0, sp_reg,SVAL(-1).value); +  LABEL_B; +  mov_imm_mem( PIKE_T_INT, sp_reg,SVAL(-1).type); +  } +  return; +     case F_ZERO_TYPE:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0);    amd64_load_sp_reg();    mov_mem32_reg( sp_reg, -sizeof(struct svalue), P_REG_RAX );    /* Rax now has type + subtype. */ -  mov_reg_reg( P_REG_RAX, P_REG_RBX ); -  and_reg_imm( P_REG_RAX, 0x1f ); +  mov_reg32_reg( P_REG_RAX, P_REG_RBX ); +  and_reg32_imm( P_REG_RAX, 0x1f );    cmp_reg32_imm( P_REG_RAX, PIKE_T_INT );    jne( &label_A );    /* It is an integer. */    shr_reg_imm( P_REG_RBX, 16 );    /* subtype in RBX. */    mov_imm_mem( PIKE_T_INT, sp_reg, -sizeof(struct svalue) );    mov_reg_mem( P_REG_RBX, sp_reg,    -sizeof(struct svalue)+OFFSETOF(svalue,u.integer) );    jmp( &label_B );    LABEL_A;
pike.git/src/code/amd64.c:2094:    /* If we are compiling with debug, F_RETURN does extra checks */       case F_RETURN:    case F_DUMB_RETURN:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0);    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_reg_imm( P_REG_RAX, PIKE_FRAME_RETURN_INTERNAL); +  and_reg32_imm( P_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;    /* We should jump to the given address. */    mov_mem32_reg( fp_reg, OFFSETOF(pike_frame, flags), P_REG_RAX ); -  and_reg_imm( P_REG_RAX, PIKE_FRAME_RETURN_POP ); +  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;    fp_reg = -1;    amd64_load_fp_reg();
pike.git/src/code/amd64.c:2129:    return;       case F_CLEAR_STRING_SUBTYPE:    ins_debug_instr_prologue(b, 0, 0);    amd64_load_sp_reg();    mov_mem32_reg(sp_reg, OFFSETOF(svalue, tu.t.type) - sizeof(struct svalue),    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_reg_imm(P_REG_RAX, 0x1f); +  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;    }    amd64_call_c_opcode(addr,flags);       if (instrs[b].flags & I_RETURN) {    LABELS();