📄 translate.c.svn-base
字号:
{ /* This helps us re-schedule the micro-code to insns in delay-slots before the actual jump. */ dc->delayed_branch = 2; dc->delayed_pc = dc->pc + offset; dc->bcc = cond; if (cond != CC_A) { gen_tst_cc (dc, cond); gen_op_evaluate_bcc (); } gen_op_movl_T0_im (dc->delayed_pc); gen_op_movl_btarget_T0 ();}/* Dynamic jumps, when the dest is in a live reg for example. */void cris_prepare_dyn_jmp (DisasContext *dc){ /* This helps us re-schedule the micro-code to insns in delay-slots before the actual jump. */ dc->delayed_branch = 2; dc->dyn_jmp = 1; dc->bcc = CC_A;}void cris_prepare_jmp (DisasContext *dc, uint32_t dst){ /* This helps us re-schedule the micro-code to insns in delay-slots before the actual jump. */ dc->delayed_branch = 2; dc->delayed_pc = dst; dc->dyn_jmp = 0; dc->bcc = CC_A;}void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign){ if (size == 1) { if (sign) gen_op_ldb_T0_T0(dc); else gen_op_ldub_T0_T0(dc); } else if (size == 2) { if (sign) gen_op_ldw_T0_T0(dc); else gen_op_lduw_T0_T0(dc); } else { gen_op_ldl_T0_T0(dc); }}void gen_store_T0_T1 (DisasContext *dc, unsigned int size){ /* Remember, operands are flipped. CRIS has reversed order. */ if (size == 1) { gen_op_stb_T0_T1(dc); } else if (size == 2) { gen_op_stw_T0_T1(dc); } else gen_op_stl_T0_T1(dc);}/* sign extend T1 according to size. */static void gen_sext_T1_T0(int size){ if (size == 1) gen_op_extb_T1_T0(); else if (size == 2) gen_op_extw_T1_T0();}static void gen_sext_T1_T1(int size){ if (size == 1) gen_op_extb_T1_T1(); else if (size == 2) gen_op_extw_T1_T1();}static void gen_sext_T0_T0(int size){ if (size == 1) gen_op_extb_T0_T0(); else if (size == 2) gen_op_extw_T0_T0();}static void gen_zext_T0_T0(int size){ if (size == 1) gen_op_zextb_T0_T0(); else if (size == 2) gen_op_zextw_T0_T0();}static void gen_zext_T1_T0(int size){ if (size == 1) gen_op_zextb_T1_T0(); else if (size == 2) gen_op_zextw_T1_T0();}static void gen_zext_T1_T1(int size){ if (size == 1) gen_op_zextb_T1_T1(); else if (size == 2) gen_op_zextw_T1_T1();}#if DISAS_CRISstatic char memsize_char(int size){ switch (size) { case 1: return 'b'; break; case 2: return 'w'; break; case 4: return 'd'; break; default: return 'x'; break; }}#endifstatic unsigned int memsize_z(DisasContext *dc){ return dc->zsize + 1;}static unsigned int memsize_zz(DisasContext *dc){ switch (dc->zzsize) { case 0: return 1; case 1: return 2; default: return 4; }}static void do_postinc (DisasContext *dc, int size){ if (!dc->postinc) return; gen_movl_T0_reg[dc->op1](); gen_op_addl_T0_im(size); gen_movl_reg_T0[dc->op1]();}static void dec_prep_move_r(DisasContext *dc, int rs, int rd, int size, int s_ext){ gen_movl_T0_reg[rs](); gen_op_movl_T1_T0(); if (s_ext) gen_sext_T1_T1(size); else gen_zext_T1_T1(size);}/* Prepare T0 and T1 for a register alu operation. s_ext decides if the operand1 should be sign-extended or zero-extended when needed. */static void dec_prep_alu_r(DisasContext *dc, int rs, int rd, int size, int s_ext){ dec_prep_move_r(dc, rs, rd, size, s_ext); gen_movl_T0_reg[rd](); if (s_ext) gen_sext_T0_T0(size); else gen_zext_T0_T0(size);}/* Prepare T0 and T1 for a memory + alu operation. s_ext decides if the operand1 should be sign-extended or zero-extended when needed. */static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize){ unsigned int rs, rd; uint32_t imm; int is_imm; int insn_len = 2; rs = dc->op1; rd = dc->op2; is_imm = rs == 15 && dc->postinc; /* Load [$rs] onto T1. */ if (is_imm) { insn_len = 2 + memsize; if (memsize == 1) insn_len++; imm = ldl_code(dc->pc + 2); if (memsize != 4) { if (s_ext) { imm = sign_extend(imm, (memsize * 8) - 1); } else { if (memsize == 1) imm &= 0xff; else imm &= 0xffff; } } DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n", imm, rd, s_ext, memsize)); gen_op_movl_T1_im (imm); dc->postinc = 0; } else { gen_movl_T0_reg[rs](); gen_load_T0_T0(dc, memsize, 0); gen_op_movl_T1_T0(); if (s_ext) gen_sext_T1_T1(memsize); else gen_zext_T1_T1(memsize); } /* put dest in T0. */ gen_movl_T0_reg[rd](); return insn_len;}#if DISAS_CRISstatic const char *cc_name(int cc){ static char *cc_names[16] = { "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ls", "hi", "ge", "lt", "gt", "le", "a", "p" }; assert(cc < 16); return cc_names[cc];}#endifstatic unsigned int dec_bccq(DisasContext *dc){ int32_t offset; int sign; uint32_t cond = dc->op2; int tmp; offset = EXTRACT_FIELD (dc->ir, 1, 7); sign = EXTRACT_FIELD(dc->ir, 0, 0); offset *= 2; offset |= sign << 8; tmp = offset; offset = sign_extend(offset, 8); /* op2 holds the condition-code. */ cris_cc_mask(dc, 0); cris_prepare_cc_branch (dc, offset, cond); return 2;}static unsigned int dec_addoq(DisasContext *dc){ uint32_t imm; dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7); imm = sign_extend(dc->op1, 7); DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2)); cris_cc_mask(dc, 0); /* Fetch register operand, */ gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(imm); crisv32_alu_op(dc, CC_OP_ADD, REG_ACR, 4); return 2;}static unsigned int dec_addq(DisasContext *dc){ DIS(fprintf (logfile, "addq %u, $r%u\n", dc->op1, dc->op2)); dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); cris_cc_mask(dc, CC_MASK_NZVC); /* Fetch register operand, */ gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(dc->op1); crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); return 2;}static unsigned int dec_moveq(DisasContext *dc){ uint32_t imm; dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); imm = sign_extend(dc->op1, 5); DIS(fprintf (logfile, "moveq %d, $r%u\n", imm, dc->op2)); cris_cc_mask(dc, 0); gen_op_movl_T1_im(imm); crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); return 2;}static unsigned int dec_subq(DisasContext *dc){ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); DIS(fprintf (logfile, "subq %u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); /* Fetch register operand, */ gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(dc->op1); crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); return 2;}static unsigned int dec_cmpq(DisasContext *dc){ uint32_t imm; dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); imm = sign_extend(dc->op1, 5); DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(imm); crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4); return 2;}static unsigned int dec_andq(DisasContext *dc){ uint32_t imm; dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); imm = sign_extend(dc->op1, 5); DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(imm); crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4); return 2;}static unsigned int dec_orq(DisasContext *dc){ uint32_t imm; dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); imm = sign_extend(dc->op1, 5); DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(imm); crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4); return 2;}static unsigned int dec_btstq(DisasContext *dc){ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2)); cris_evaluate_flags(dc); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(dc->op1); crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); cris_update_cc_op(dc, CC_OP_FLAGS); gen_op_movl_flags_T0(); dc->flags_live = 1; return 2;}static unsigned int dec_asrq(DisasContext *dc){ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(dc->op1); crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4); return 2;}static unsigned int dec_lslq(DisasContext *dc){ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); DIS(fprintf (logfile, "lslq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(dc->op1); crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4); return 2;}static unsigned int dec_lsrq(DisasContext *dc){ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); DIS(fprintf (logfile, "lsrq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op2](); gen_op_movl_T1_im(dc->op1); crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4); return 2;}static unsigned int dec_move_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "move.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_move_r(dc, dc->op1, dc->op2, size, 0); crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, size); return 2;}static unsigned int dec_scc_r(DisasContext *dc){ int cond = dc->op2; DIS(fprintf (logfile, "s%s $r%u\n", cc_name(cond), dc->op1)); if (cond != CC_A) { gen_tst_cc (dc, cond); gen_op_movl_T1_T0(); } else gen_op_movl_T1_im(1); cris_cc_mask(dc, 0); crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4); return 2;}static unsigned int dec_and_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "and.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); crisv32_alu_op(dc, CC_OP_AND, dc->op2, size); return 2;}static unsigned int dec_lz_r(DisasContext *dc){ DIS(fprintf (logfile, "lz $r%u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); crisv32_alu_op(dc, CC_OP_LZ, dc->op2, 4); return 2;}static unsigned int dec_lsl_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); gen_op_andl_T1_im(63); crisv32_alu_op(dc, CC_OP_LSL, dc->op2, size); return 2;}static unsigned int dec_lsr_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); gen_op_andl_T1_im(63); crisv32_alu_op(dc, CC_OP_LSR, dc->op2, size); return 2;}static unsigned int dec_asr_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1); gen_op_andl_T1_im(63); crisv32_alu_op(dc, CC_OP_ASR, dc->op2, size); return 2;}static unsigned int dec_muls_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZV); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1); gen_sext_T0_T0(size); crisv32_alu_op(dc, CC_OP_MULS, dc->op2, 4); return 2;}static unsigned int dec_mulu_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZV); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); gen_zext_T0_T0(size); crisv32_alu_op(dc, CC_OP_MULU, dc->op2, 4); return 2;}static unsigned int dec_dstep_r(DisasContext *dc){ DIS(fprintf (logfile, "dstep $r%u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); gen_movl_T0_reg[dc->op1](); gen_op_movl_T1_T0(); gen_movl_T0_reg[dc->op2](); crisv32_alu_op(dc, CC_OP_DSTEP, dc->op2, 4); return 2;}static unsigned int dec_xor_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); BUG_ON(size != 4); /* xor is dword. */ cris_cc_mask(dc, CC_MASK_NZ); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); crisv32_alu_op(dc, CC_OP_XOR, dc->op2, 4); return 2;}static unsigned int dec_bound_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); /* TODO: needs optmimization. */ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); /* rd should be 4. */ gen_movl_T0_reg[dc->op2](); crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4); return 2;}static unsigned int dec_cmp_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); crisv32_alu_op(dc, CC_OP_CMP, dc->op2, size); return 2;}static unsigned int dec_abs_r(DisasContext *dc){ DIS(fprintf (logfile, "abs $r%u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0); gen_op_absl_T1_T1(); crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); return 2;}static unsigned int dec_add_r(DisasContext *dc){ int size = memsize_zz(dc); DIS(fprintf (logfile, "add.%c $r%u, $r%u\n", memsize_char(size), dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); crisv32_alu_op(dc, CC_OP_ADD, dc->op2, size); return 2;}static unsigned int dec_addc_r(DisasContext *dc){ DIS(fprintf (logfile, "addc $r%u, $r%u\n", dc->op1, dc->op2)); cris_evaluate_flags(dc); cris_cc_mask(dc, CC_MASK_NZVC); dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4); return 2;}static unsigned int dec_mcp_r(DisasContext *dc){ DIS(fprintf (logfile, "mcp $p%u, $r%u\n", dc->op2, dc->op1)); cris_evaluate_flags(dc); cris_cc_mask(dc, CC_MASK_RNZV); gen_movl_T0_preg[dc->op2](); gen_op_movl_T1_T0(); gen_movl_T0_reg[dc->op1](); crisv32_alu_op(dc, CC_OP_MCP, dc->op1, 4); return 2;}#if DISAS_CRISstatic char * swapmode_name(int mode, char *modename) { int i = 0; if (mode & 8) modename[i++] = 'n'; if (mode & 4)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -