pike.git / src / code / amd64.c

version» Context lines:

pike.git/src/code/amd64.c:872:   }      /* reg += reg2 */   static void add_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 )   {    rex(1,reg2,0,reg);    opcode( 0x1 );    modrm( 3, reg2, reg );   }    + /* reg *= reg2 */ + static void mul_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 ) + { + #if 0 +  /* 64b * 64b -> 128b +  This would actually not need an overflow check. +  instead, push high if not zero, push low, genreate gmp. +  but... Well. +  */ +  if( reg2 == P_REG_RAX ) +  { +  rex(1,0,0,reg); /* imul r/m64 */ +  opcode( 0xf7 ); +  modrm( 3,5,reg ); +  } +  else + #endif +  { +  rex(1,reg,0,reg2); +  opcode( 0xf ); +  opcode( 0xaf ); +  modrm( 3, reg, reg2 ); +  } + } +    /* reg += reg2 */   static void add_reg32_reg32( enum amd64_reg reg, enum amd64_reg reg2 )   {    rex(0,reg2,0,reg);    opcode( 0x1 );    modrm( 3, reg2, reg );   }      /* reg -= reg2 */   static void sub_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 )
pike.git/src/code/amd64.c:1651:    pop(P_REG_RBX);    pop(P_REG_R12);    pop(P_REG_R13);    pop(P_REG_R14);    pop(P_REG_R15);    pop(P_REG_RBP);    ret();    }   }    + static void if_not_two_int(struct label *to, int load) + { +  amd64_load_sp_reg(); +  mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX ); +  mov_mem8_reg(sp_reg, SVAL(-2).type, P_REG_RBX ); +  add_reg_reg(P_REG_RAX,P_REG_RBX); +  /* test_reg32(P_REG_RAX); int == 0 */ +  jnz(to); +  if( load ) +  { +  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.git/src/code/amd64.c:1883:    jz(&label_B);    LABEL_A;    amd64_call_c_opcode(addr, flags);    jmp(&label_C);    LABEL_B;    not_mem(sp_reg, SVAL(-1).value );    LABEL_C;    }    return;    +  case F_MULTIPLY: +  { +  if_not_two_int(&label_A,1); +  mul_reg_reg(P_REG_RBX,P_REG_RAX); +  jo(&label_A); +  mov_imm_mem(PIKE_T_INT, sp_reg, SVAL(-2).type); +  mov_reg_mem(P_REG_RBX, sp_reg, SVAL(-2).value); +  amd64_add_sp(-1); +  jmp(&label_B); +  LABEL_A; +  amd64_call_c_opcode(addr, flags); +  amd64_load_sp_reg(); +  LABEL_B; +  } +  return; +     case F_AND:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0); -  amd64_load_sp_reg(); -  mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX ); -  mov_mem8_reg(sp_reg, SVAL(-2).type, P_REG_RBX ); -  add_reg_reg(P_REG_RAX,P_REG_RBX); -  /* test_reg32(P_REG_RAX); int == 0 */ -  jnz(&label_A); -  -  mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RAX ); -  mov_mem_reg(sp_reg, SVAL(-2).value, P_REG_RBX ); +  if_not_two_int(&label_A,1);    and_reg_reg(P_REG_RBX,P_REG_RAX);    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-2).type);    mov_reg_mem(P_REG_RBX,sp_reg,SVAL(-2).value);    amd64_add_sp(-1);    jmp(&label_B);    LABEL_A;    amd64_call_c_opcode(addr, flags);    amd64_load_sp_reg();    LABEL_B;    }    return;       case F_OR:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0); -  amd64_load_sp_reg(); -  mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX ); -  mov_mem8_reg(sp_reg, SVAL(-2).type, P_REG_RBX ); -  add_reg32_reg32(P_REG_RAX,P_REG_RBX); -  /* test_reg32(P_REG_RAX); int == 0 */ -  jnz(&label_A); -  -  mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RAX ); -  mov_mem_reg(sp_reg, SVAL(-2).value, P_REG_RBX ); +  if_not_two_int(&label_A,1);    or_reg_reg(P_REG_RAX,P_REG_RBX);    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-2).type);    mov_reg_mem(P_REG_RBX,sp_reg,SVAL(-2).value);    amd64_add_sp(-1);    jmp(&label_B);    LABEL_A;    amd64_call_c_opcode(addr, flags);    amd64_load_sp_reg();    LABEL_B;    }    return;       case F_RSH:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0); -  amd64_load_sp_reg(); -  mov_mem8_reg(sp_reg, -1*sizeof(struct svalue), P_REG_RAX ); -  mov_mem8_reg(sp_reg, -2*sizeof(struct svalue), P_REG_RBX ); -  add_reg32_reg32(P_REG_RAX,P_REG_RBX); -  /* test_reg32(P_REG_RAX); int == 0 */ -  jnz(&label_A); -  +  if_not_two_int(&label_A,0);    mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RCX );    cmp_reg_imm(P_REG_RCX,0);    jl( &label_A );    cmp_reg_imm(P_REG_RCX,63);    jl( &label_B );    LABEL_A;    amd64_call_c_opcode(addr, flags);    amd64_load_sp_reg();    jmp(&label_C);    LABEL_B;
pike.git/src/code/amd64.c:1965:    shr_mem_reg( sp_reg, SVAL(-2).value, P_REG_RCX);    amd64_add_sp(-1);    LABEL_C;    }    return;       case F_LSH:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0); -  amd64_load_sp_reg(); -  mov_mem8_reg(sp_reg, -1*sizeof(struct svalue), P_REG_RAX ); -  mov_mem8_reg(sp_reg, -2*sizeof(struct svalue), P_REG_RBX ); -  add_reg32_reg32(P_REG_RAX,P_REG_RBX); -  /* test_reg32(P_REG_RAX); int == 0 */ -  jnz(&label_A); -  +  if_not_two_int(&label_A,0);    mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RCX );    cmp_reg_imm(P_REG_RCX,0);    jl( &label_A );    cmp_reg_imm(P_REG_RCX,63);    jl( &label_B );    LABEL_A;    amd64_call_c_opcode(addr, flags);    amd64_load_sp_reg();    jmp(&label_C);    LABEL_B;
pike.git/src/code/amd64.c:2005:    amd64_add_sp(-1);    LABEL_C;    }    return;    case F_ADD_INTS:    {    ins_debug_instr_prologue(b, 0, 0);    amd64_load_sp_reg();    mov_mem_reg( sp_reg, -sizeof(struct svalue)*2, P_REG_RAX );    add_reg_mem( P_REG_RAX, sp_reg, -sizeof(struct svalue ) ); - #if PIKE_T_INT != 0 - #error This code assumes PIKE_T_INT is 0. -  /* cmp_reg32_imm( P_REG_RAX, 0 ); */ - #endif +     jnz( &label_A );    /* So. Both are actually integers. */    mov_mem_reg( sp_reg,    -sizeof(struct svalue)+OFFSETOF(svalue,u.integer),    P_REG_RAX );       add_reg_mem( P_REG_RAX,    sp_reg,    -sizeof(struct svalue)*2+OFFSETOF(svalue,u.integer));   
pike.git/src/code/amd64.c:2163:    return;       case F_POP_VALUE:    {    ins_debug_instr_prologue(b, 0, 0);    amd64_load_sp_reg();    amd64_add_sp( -1 );    amd64_free_svalue( sp_reg, 0 );    }    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) */
pike.git/src/code/amd64.c:2875:    LABEL_B;    /* something else. */    update_arg1(b);    amd64_call_c_opcode(instrs[a-F_OFFSET].address,    instrs[a-F_OFFSET].flags);    LABEL_C;    /* done */    }    return;    +  case F_MULTIPLY_INT: +  { +  LABELS(); +  ins_debug_instr_prologue(a-F_OFFSET, b, 0); +  amd64_load_sp_reg(); +  mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX ); +  test_reg(P_REG_RAX); +  jnz(&label_A); +  +  /* FIXME: mul_reg_mem_imm actually exists as an instruction. */ +  mov_imm_reg(b, P_REG_RAX); +  mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RBX ); +  mul_reg_reg(P_REG_RBX,P_REG_RAX); +  jo(&label_A); +  +  mov_imm_mem(PIKE_T_INT, sp_reg, SVAL(-1).type); +  mov_reg_mem(P_REG_RBX, sp_reg, SVAL(-1).value); +  jmp(&label_B); +  LABEL_A; +  update_arg1(b); +  amd64_call_c_opcode(instrs[a-F_OFFSET].address, +  instrs[a-F_OFFSET].flags); +  LABEL_B; +  } +  return; +     case F_AND_INT:    {    LABELS(); -  ins_debug_instr_prologue(b, 0, 0); +  ins_debug_instr_prologue(a-F_OFFSET,b, 0);    amd64_load_sp_reg();    mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX );    test_reg(P_REG_RAX);    jnz(&label_A);       /* FIXME: and_mem_imm */    mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RAX );    and_reg_imm(P_REG_RAX,b);    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-1).type);    mov_reg_mem(P_REG_RAX,sp_reg,SVAL(-1).value);
pike.git/src/code/amd64.c:2903:    instrs[a-F_OFFSET].flags);    LABEL_B;    }    return;       case F_OR_INT:    if( !b )    return;    {    LABELS(); -  ins_debug_instr_prologue(b, 0, 0); +  ins_debug_instr_prologue(a-F_OFFSET, b, 0);    amd64_load_sp_reg();    mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX );    test_reg(P_REG_RAX);    jnz(&label_A);       /* FIXME: or_mem_imm */    mov_mem_reg(sp_reg, SVAL(-1).value, P_REG_RAX );    or_reg_imm(P_REG_RAX,b);    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-1).type);    mov_reg_mem(P_REG_RAX,sp_reg,SVAL(-1).value);
pike.git/src/code/amd64.c:2927:    amd64_call_c_opcode(instrs[a-F_OFFSET].address,    instrs[a-F_OFFSET].flags);    LABEL_B;    }    return;       case F_LSH_INT:    if( b > 0 && b <= 63 )    {    LABELS(); -  ins_debug_instr_prologue(b, 0, 0); +  ins_debug_instr_prologue(a-F_OFFSET, b, 0);    amd64_load_sp_reg();    mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX );    test_reg32(P_REG_RAX);    jz(&label_B);    LABEL_A;    update_arg1(b);    amd64_call_c_opcode(instrs[a-F_OFFSET].address,    instrs[a-F_OFFSET].flags);    jmp(&label_C);    LABEL_B;    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-1).type);    mov_mem_reg( sp_reg, SVAL(-1).value, P_REG_RBX);    /* ok. It would have been nice is sal set a    bit that stayed set when you shifted out a 1 bit. :)    */    mov_reg_reg( P_REG_RBX, P_REG_RAX ); -  shl_reg_imm( P_REG_RBX, P_REG_RCX); +  shl_reg_imm( P_REG_RBX, b); +     mov_reg_reg( P_REG_RBX, P_REG_RDX ); -  shr_reg_imm( P_REG_RDX, P_REG_RCX ); +  shr_reg_imm( P_REG_RDX, b );    cmp_reg_reg( P_REG_RDX, P_REG_RAX );    jne( &label_A );    mov_reg_mem( P_REG_RBX, sp_reg, SVAL(-1).value);    LABEL_C;    return;    }    if(!b) return;    if( b < 0 )    yyerror("<< with negative constant\n");    break;    case F_RSH_INT:    if( b > 0 && b <= 63 )    {    LABELS(); -  ins_debug_instr_prologue(b, 0, 0); +  ins_debug_instr_prologue(a-F_OFFSET, b, 0);    amd64_load_sp_reg();    mov_mem8_reg(sp_reg, SVAL(-1).type, P_REG_RAX );    test_reg(P_REG_RAX);    jnz(&label_A);    mov_mem_reg( sp_reg, SVAL(-1).value, P_REG_RAX);    /* FIXME: shr_mem_imm */    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-1).type);    shr_reg_imm( P_REG_RAX, b);    mov_reg_mem( P_REG_RAX, sp_reg, SVAL(-1).value);    jmp(&label_B);