pike.git / src / code / amd64.c

version» Context lines:

pike.git/src/code/amd64.c:1:   /*    * Machine code generator for AMD64.    */      #include "operators.h"   #include "constants.h"   #include "object.h"   #include "builtin_functions.h" + #include "bignum.h"      /* These come from linux include files. */   #ifdef REG_RBX   #undef REG_RAX   #undef REG_RBX   #undef REG_RCX   #undef REG_RDX   #undef REG_RSP   #undef REG_RBP   #undef REG_RSI
pike.git/src/code/amd64.c:958:   }      /* 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 ) + /* reg *= reg2 res in rdx:rax */ + static void mul_rax_reg_reg128( enum amd64_reg reg )   { - #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 +  +  + /* reg *= reg2 */ + static void mul_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 )   {    rex(1,reg,0,reg2);    opcode( 0xf );    opcode( 0xaf );    modrm( 3, reg, reg2 );   } - } +       /* reg /= reg2 */   static void div_reg_reg( enum amd64_reg reg, enum amd64_reg reg2 )   {    if( reg != P_REG_RAX ) Pike_error("Not supported, reg1 must be RAX\n");    if( reg2 == P_REG_RDX ) Pike_error("Clobbers RAX+RDX\n");    rex(1,0,0,0);    opcode(0x99);    /*    *cqo:
pike.git/src/code/amd64.c:2108:    jmp(&label_B);    LABEL_A;    amd64_call_c_opcode(addr, flags);    amd64_load_sp_reg();    LABEL_B;    }    return;    case F_MULTIPLY:    {    LABELS(); -  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); +  if_not_two_int(&label_C,1);    amd64_add_sp(-1); -  +  mul_rax_reg_reg128(P_REG_RBX); +  jo(&label_A); +  mov_imm_mem(PIKE_T_INT, sp_reg, SVAL(-1).type); /* Only needed for UNDEFINED*x -> 0 */    jmp(&label_B); -  LABEL_A; +  LABEL_C;    amd64_call_c_opcode(addr, flags);    amd64_load_sp_reg(); -  +  jmp(&label_D); +  LABEL_A; +  /* overflows signed. upper 64 in edx, lower in eax. */ +  mov_reg_reg( P_REG_RAX, ARG1_REG ); +  mov_reg_reg( P_REG_RDX, ARG2_REG ); /* (on unix, not generated, arg2 is rdx) */ +  amd64_call_c_function(create_double_bignum); +  mov_imm_mem(PIKE_T_OBJECT, sp_reg, SVAL(-1).type);    LABEL_B; -  +  mov_reg_mem(P_REG_RAX, sp_reg, SVAL(-1).value); +  LABEL_D;    }    return;       case F_AND:    {    LABELS();    ins_debug_instr_prologue(b, 0, 0);    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);