2012-06-25
2012-06-25 14:10:12 by Per Hedbor <ph@opera.com>
-
622ebc558eadc49f0b83ad78a42c2e09b53688b5
(132 lines)
(+117/-15)
[
Show
| Annotate
]
Branch: 7.9
[compiler][amd64] More inline opcodes.
Added the various *CALL*BULTIN* opcodes.
13:
REG_RSP = 4, REG_RBP = 5, REG_RSI = 6, REG_RDI = 7,
REG_R8 = 8, REG_R9 = 9, REG_R10 = 10, REG_R11 = 11,
REG_R12 = 12, REG_R13 = 13, REG_R14 = 14, REG_R15 = 15,
- REG_INVALID = -1};
+ REG_INVALID = -1,
-
+ REG_XMM0 = 0, REG_XMM1 = 1, REG_XMM2 = 2, REG_XMM3 = 3,
+ REG_XMM4 = 4, REG_XMM5 = 5, REG_XMM6 = 6, REG_XMM7 = 7,
+ REG_XMM8 = 8, REG_XMM9 = 9, REG_XMM10=10, REG_XMM11=11,
+ REG_XMM12=12, REG_XMM13=13, REG_XMM14=14, REG_XMM15=15,
+ };
+
/* We reserve register r12 and above (as well as RSP, RBP and RBX). */
#define REG_BITMASK ((1 << REG_MAX) - 1)
#define REG_RESERVED (REG_RSP|REG_RBP|REG_RBX)
61:
if( dist > 0x7f || dist < -0x80 )
Pike_fatal("Branch too far\n");
Pike_compiler->new_program->program[l->offset[i]] = dist;
- /* fprintf( stderr, "assigning label @%x[%02x >%02x< %02x] -> %d\n", */
- /* l->offset[i], */
- /* Pike_compiler->new_program->program[l->offset[i]-1], */
- /* Pike_compiler->new_program->program[l->offset[i]], */
- /* Pike_compiler->new_program->program[l->offset[i]+1], */
- /* dist ); */
+
}
l->n_label_uses = 0;
l->addr = PIKE_PC;
378:
}
}
+ static void mov_mem128_reg( enum amd64_reg from_reg, int offset, enum amd64_reg to_reg )
+ {
+ if( from_reg > 7 )
+ Pike_fatal("Not supported\n");
+ rex(0,to_reg,0,from_reg);
+ opcode( 0x66 );
+ opcode( 0x0f );
+ opcode( 0x6f ); /* MOVDQA xmm,m128 */
+ offset_modrm_sib( offset, to_reg, from_reg );
+ }
+
+ static void mov_reg_mem128( enum amd64_reg from_reg, enum amd64_reg to_reg, int offset )
+ {
+ if( from_reg > 7 )
+ Pike_fatal("Not supported\n");
+ rex(0,from_reg,0,to_reg);
+ opcode( 0x66 );
+ opcode( 0x0f );
+ opcode( 0x7f ); /* MOVDQA m128,xmm */
+ offset_modrm_sib( offset, from_reg, to_reg );
+ }
+
static void low_mov_reg_mem(enum amd64_reg from_reg, enum amd64_reg to_reg, ptrdiff_t offset )
{
opcode( 0x89 );
1021:
static void mov_sval_type(enum amd64_reg src, enum amd64_reg dst )
{
mov_mem8_reg( src, OFFSETOF(svalue,type), dst);
- and_reg32_imm( dst, 0x1f );
+ /* and_reg32_imm( dst, 0x1f );*/
}
1255: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
static void ins_debug_instr_prologue (PIKE_INSTR_T instr, INT32 arg1, INT32 arg2)
{
- return;
+
int flags = instrs[instr].flags;
-
+ /* For now: It is very hard to read the disassembled source when
+ this is inserted */
+ if( !d_flag )
+ return;
+
maybe_update_pc();
if (flags & I_HASARG2)
1588:
case F_SWAP:
/*
pike_sp[-1] = pike_sp[-2]
-
- FIXME: Can be changed to
- use movlq (128-bit mov, sse2)
+
*/
amd64_load_sp_reg();
-
+ add_reg_imm_reg( sp_reg, -2*sizeof(struct svalue), REG_RCX );
+ mov_mem128_reg( REG_RCX, 0, REG_XMM0 );
+ mov_mem128_reg( REG_RCX, 16, REG_XMM1 );
+ mov_reg_mem128( REG_XMM1, REG_RCX, 0 );
+ mov_reg_mem128( REG_XMM0, REG_RCX, 16 );
+ #if 0
add_reg_imm_reg( sp_reg, -2*sizeof(struct svalue), REG_R10);
mov_mem_reg( REG_R10, 0, REG_RAX );
mov_mem_reg( REG_R10, 8, REG_RCX );
1604:
mov_reg_mem(REG_RAX, REG_R10,sizeof(struct svalue));
mov_reg_mem(REG_RCX, REG_R10,8+sizeof(struct svalue));
/* save done. */
+ #endif
return;
case F_POP_VALUE:
1713:
cmp_reg_reg(REG_RBX, sp_reg);
jl(&label_B);
return;
- #ifndef PIKE_DEBUG
+
/* If we are compiling with debug, F_RETURN does extra checks */
-
+
case F_RETURN:
- #endif
+
case F_DUMB_RETURN:
{
LABELS();
1759:
LABEL_A;
return;
}
-
+
amd64_call_c_opcode(addr,flags);
if (instrs[b].flags & I_RETURN) {
1982:
maybe_update_pc();
addr=instrs[off].address;
amd64_call_c_opcode(addr, flags);
+
amd64_load_sp_reg();
test_reg(REG_RAX);
2300:
ins_f_byte_with_arg(F_DEC_LOCAL_AND_POP, b);
return;
+ case F_CALL_BUILTIN_AND_POP:
+ ins_f_byte_with_arg( F_CALL_BUILTIN, b );
+ ins_f_byte( F_POP_VALUE );
+ return;
+
+ case F_MARK_CALL_BUILTIN_AND_RETURN:
+ ins_f_byte_with_arg( F_MARK_CALL_BUILTIN, b );
+ ins_f_byte( F_DUMB_RETURN );
+ return;
+
+ case F_MARK_CALL_BUILTIN_AND_POP:
+ ins_f_byte_with_arg( F_MARK_CALL_BUILTIN, b );
+ ins_f_byte( F_POP_VALUE );
+ return;
+
+ case F_CALL_BUILTIN1_AND_POP:
+ ins_f_byte_with_arg( F_CALL_BUILTIN1, b );
+ ins_f_byte( F_POP_VALUE );
+ return;
+
+ case F_CALL_BUILTIN_AND_RETURN:
+ ins_f_byte_with_arg( F_CALL_BUILTIN, b );
+ ins_f_byte( F_DUMB_RETURN );
+ return;
+
+ case F_CALL_BUILTIN:
+ ins_debug_instr_prologue(a-F_OFFSET, b, 0);
+
+ amd64_load_mark_sp_reg();
+ amd64_load_sp_reg();
+
+ mov_mem_reg( mark_sp_reg, -sizeof(struct svalue*), REG_RAX );
+ amd64_add_mark_sp( -1 );
+ mov_reg_reg( sp_reg, ARG1_REG );
+ sub_reg_reg( ARG1_REG, REG_RAX );
+ shr_reg_imm( ARG1_REG, 4 );
+ /* arg1 = (sp_reg - *--mark_sp)/16 (sizeof(svalue)) */
+
+ case F_MARK_CALL_BUILTIN:
+ if(a == F_MARK_CALL_BUILTIN )
+ {
+ ins_debug_instr_prologue(a-F_OFFSET, b, 0);
+ mov_imm_reg( 0, ARG1_REG );
+ }
+
+ case F_CALL_BUILTIN1:
+ if(a == F_CALL_BUILTIN1 )
+ {
+ ins_debug_instr_prologue(a-F_OFFSET, b, 0);
+ mov_imm_reg( 1, ARG1_REG );
+ }
+ /* Get function pointer */
+ #if 0
+ amd64_load_fp_reg();
+ /* Ok.. This is.. interresting.
+ Let's trust that the efun really is constant, ok?
+ */
+ mov_mem_reg( fp_reg, OFFSETOF(pike_frame,context), REG_RAX );
+ mov_mem_reg( REG_RAX, OFFSETOF(inherit,prog), REG_RAX );
+ mov_mem_reg( REG_RAX, OFFSETOF(program,constants), REG_RAX );
+ add_reg_imm( REG_RAX, b*sizeof(struct program_constant) +
+ OFFSETOF(program_constant,sval) );
+ mov_mem_reg( REG_RAX, OFFSETOF( svalue, u.efun ), REG_RAX );
+ mov_mem_reg( REG_RAX, OFFSETOF( callable, function), REG_RAX );
+ call_reg( REG_RAX );
+ sp_reg = -1;
+ #else
+ amd64_call_c_opcode(Pike_compiler->new_program->constants[b].sval.u.efun->function,
+ I_UPDATE_SP);
+ #endif
+ return;
+
case F_CONSTANT:
ins_debug_instr_prologue(a-F_OFFSET, b, 0);
amd64_load_fp_reg();