pike.git / src / code / amd64.c

version» Context lines:

pike.git/src/code/amd64.c:258:    modrm(3,reg1,reg2);   }      static void or_reg_reg( enum amd64_reg reg1, enum amd64_reg reg2 )   {    rex(1,reg1,0,reg2);    opcode( 0x09 );    modrm(3,reg1,reg2);   }    - static void and_reg_imm( enum amd64_reg reg, int imm32 ) + static void or_reg_imm( enum amd64_reg reg, INT_TYPE imm32 )   {    rex( 1, 0, 0, reg ); -  +  if( imm32 < -0x80 || imm32 > 0x7f ) +  { +  if( reg == P_REG_RAX ) +  { +  opcode( 0xd ); /* OR rax,imm32 */ +  id( imm32 ); +  } +  else +  { +  opcode( 0x81 ); /* OR REG,imm32 */ +  modrm( 3, 1, reg); +  id( imm32 ); +  } +  } +  else +  { +  add_to_program(0x83); /* OR REG,imm8 */ +  modrm( 3, 1, reg ); +  ib( imm32 ); +  } + }    -  + static void and_reg_imm( enum amd64_reg reg, INT_TYPE imm32 ) + { +  rex( 1, 0, 0, reg ); +     if( imm32 < -0x80 || imm32 > 0x7f )    {    if( reg == P_REG_RAX )    {    opcode( 0x25 ); /* AND rax,imm32 */    id( imm32 );    }    else    {    opcode( 0x81 ); /* AND REG,imm32 */
pike.git/src/code/amd64.c:362:    modrm( 3, 4, from_reg );    }    else    {    opcode( 0xc1 );    modrm( 3, 4, from_reg );    ib( shift );    }   }    - #if 0 +    static void shl_reg_reg( enum amd64_reg reg, enum amd64_reg sreg)   {    if( sreg != P_REG_RCX )    Pike_fatal("Not supported\n");       rex( 1, 0, 0, reg );    opcode( 0xd3 );    modrm( 3, 4, reg );   } - #endif +       static void shl_reg32_reg( enum amd64_reg reg, enum amd64_reg sreg)   {    if( sreg != P_REG_RCX )    Pike_fatal("Not supported\n");    rex( 0, 0, 0, reg );    opcode( 0xd3 );    modrm( 3, 4, reg );   }    - #if 0 - static void shl_reg_mem( enum amd64_reg reg, enum amd64_reg mem, int offset) - { -  if( reg == P_REG_RCX ) -  Pike_fatal("Not supported\n"); -  mov_mem8_reg( mem, offset, P_REG_RCX ); -  shl_reg_reg( reg, P_REG_RCX ); - } - #endif -  +    static void shr_mem_reg( enum amd64_reg reg, int off, enum amd64_reg sreg)   {    if( sreg != P_REG_RCX )    Pike_fatal("Not supported\n");       rex( 1, 0, 0, reg );    opcode( 0xd3 ); /* SAR r/m64,CL */    offset_modrm_sib(off, 7, reg );   /* modrm( 3, 7, reg ); */   }    -  +  + static void shr_reg_reg( enum amd64_reg reg, enum amd64_reg reg_rcx ) + { +  if( reg_rcx != P_REG_RCX ) +  Pike_fatal("Not supported\n"); +  +  rex( 1, 0, 0, reg ); +  opcode( 0xd3 ); /* SAR r/m64,CL */ +  modrm( 3, 7, reg ); + } +  +    static void shr_reg_imm( enum amd64_reg from_reg, int shift )   {    rex( 1, from_reg, 0, 0 );    if( shift == 1 )    {    opcode( 0xd1 ); /* SAR */    modrm( 3, 7, from_reg );    }    else    {
pike.git/src/code/amd64.c:546:   {    rex( 0, 0, 0, to_reg );    opcode( 0xc7 ); /* mov imm32 -> r/m32 (sign extend)*/    /* This does not work for rg&7 == 4 or 5. */    offset_modrm_sib( offset, 0, to_reg );    id( imm );   }      static void sub_reg_imm( enum amd64_reg reg, int imm32 );    + static void neg_mem( enum amd64_reg reg, int off ) + { +  rex( 1, 0, 0, reg ); +  opcode(0xf7); +  offset_modrm_sib( off, 3, reg ); + } +    static void add_reg_imm( enum amd64_reg reg, int imm32 )   {    if( !imm32 ) return;    if( imm32 < 0 )    {    /* This makes the disassembly easier to read. */    sub_reg_imm( reg, -imm32 );    return;    }   
pike.git/src/code/amd64.c:731:    opcode( 0x83 );    modrm( 3,7,reg);    ib( imm32 );    }   }      static void cmp_reg32_imm( enum amd64_reg reg, int imm32 )   {    if(!imm32)    { -  test_reg( reg ); +  test_reg32( reg );    return;    }    rex(0, 0, 0, reg);    if( imm32 > 0x7f || imm32 < -0x80 )    {    if( reg == P_REG_RAX )    {    opcode( 0x3d );    id( imm32 );    }
pike.git/src/code/amd64.c:1806:    mov_reg_mem( P_REG_RCX, P_REG_RBX, 8 );    /*    Note: For SVALUEPTR we know we do not have to free    the lvalue.    */    amd64_add_sp( -3 );    LABEL_B;    }    return;    +  case F_NEGATE: +  { +  LABELS(); +  ins_debug_instr_prologue(b, 0, 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_D; +  neg_mem(sp_reg, SVAL(-1).value ); +  LABEL_A; +  amd64_call_c_opcode(addr, flags); +  amd64_load_sp_reg(); +  jmp(&label_C); +  LABEL_B; +  neg_mem(sp_reg, SVAL(-1).value ); +  jo(&label_D); +  LABEL_C; +  } +  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_reg(P_REG_RAX); int == 0 */ +  /* 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 );    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;
pike.git/src/code/amd64.c:1839:    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_reg(P_REG_RAX); int == 0 */ +  /* 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 );    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;
pike.git/src/code/amd64.c:1864:    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_reg(P_REG_RAX); int == 0 */ +  /* test_reg32(P_REG_RAX); int == 0 */    jnz(&label_A);       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;    mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-2).type);    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); +  +  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; +  mov_imm_mem(PIKE_T_INT,sp_reg,SVAL(-2).type); +  mov_mem_reg( sp_reg, SVAL(-2).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_reg( P_REG_RBX, P_REG_RCX); +  mov_reg_reg( P_REG_RBX, P_REG_RDX ); +  shr_reg_reg( P_REG_RDX, P_REG_RCX ); +  cmp_reg_reg( P_REG_RDX, P_REG_RAX ); +  jne( &label_A ); +  mov_reg_mem( P_REG_RBX, sp_reg, SVAL(-2).value); +  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
pike.git/src/code/amd64.c:2759:    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_AND_INT: +  { +  LABELS(); +  ins_debug_instr_prologue(b, 0, 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_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_OR_INT: +  if( !b ) +  return; +  { +  LABELS(); +  ins_debug_instr_prologue(b, 0, 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); +  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_RSH_INT: +  if( b >= 0 && b <= 63 ) +  { +  LABELS(); +  ins_debug_instr_prologue(b, 0, 0); +  amd64_load_sp_reg(); +  mov_mem8_reg(sp_reg, -1*sizeof(struct svalue), 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); +  LABEL_A; +  update_arg1(b); +  amd64_call_c_opcode(instrs[a-F_OFFSET].address, +  instrs[a-F_OFFSET].flags); +  LABEL_C; +  return; +  } +  if(!b) return; +  if( b < 0 ) +  yyerror(">> with negative constant\n"); +  break; +  +  case F_SUBTRACT_INT:    case F_ADD_NEG_INT:    b = -b;    case F_ADD_INT:    {    LABELS();    ins_debug_instr_prologue(a-F_OFFSET, b, 0);    amd64_load_sp_reg();    mov_mem16_reg( sp_reg, -sizeof(struct svalue), P_REG_RAX );    cmp_reg32_imm( P_REG_RAX,PIKE_T_INT );    jne( &label_A );