pike.git/
src/
code/
amd64.c
Branch:
Tag:
Non-build tags
All tags
No tags
2014-08-28
2014-08-28 19:21:09 by Per Hedbor <ph@opera.com>
ad0d7e3b552932c0552aecbda4c6440cbba91aa5 (
114
lines) (+
111
/-
3
)
[
Show
|
Annotate
]
Branch:
8.0
Added F_AND, F_OR and F_RSH opcodes
251:
modrm(3,reg1,reg2); }
+
static void and_reg_reg( enum amd64_reg reg1, enum amd64_reg reg2 )
+
{
+
rex(1,reg1,0,reg2);
+
opcode( 0x23 );
+
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 ) { rex( 1, 0, 0, reg );
386:
} #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_imm( enum amd64_reg from_reg, int shift ) { rex( 1, from_reg, 0, 0 );
815:
modrm( 3, reg2, reg ); }
+
/* 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 ) {
1779:
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_reg(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_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_reg(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_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_reg(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 );
+
amd64_add_sp(-1);
+
cmp_reg_imm(P_REG_RCX,63);
+
jle( &label_B );
+
mov_imm_reg(P_REG_RCX,63);
+
LABEL_B;
+
shr_mem_reg(sp_reg,SVAL(-1).value, P_REG_RCX);
+
jmp(&label_C);
+
LABEL_A;
+
amd64_call_c_opcode(addr, flags);
+
amd64_load_sp_reg();
+
LABEL_C;
+
}
+
return;
case F_ADD_INTS: { ins_debug_instr_prologue(b, 0, 0);
2049:
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_
reg
_
reg
(P_REG_RAX,P_REG_RBX);
-
test_reg32(P_REG_RAX);
/*
int == 0 */
+
add_
reg32
_
reg32
(P_REG_RAX,P_REG_RBX);
+
/*
test_reg32(P_REG_RAX); int == 0 */
jnz(&label_A); #ifdef PIKE_DEBUG