Hi Alex, On 09/27/13 02:48, Alexander Graf wrote: > This adds handling for the b and bl instructions. > > Signed-off-by: Alexander Graf <ag...@suse.de> > --- > target-arm/translate-a64.c | 61 > ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 61 insertions(+) > > diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c > index 73ccade..267fd4d 100644 > --- a/target-arm/translate-a64.c > +++ b/target-arm/translate-a64.c > @@ -133,6 +133,58 @@ static void real_unallocated_encoding(DisasContext *s) > real_unallocated_encoding(s); \ > } while (0) > > +static int get_bits(uint32_t inst, int start, int len) > +{ > + return (inst >> start) & ((1 << len) - 1); > +} > +
do you think it makes sense to reuse extract32 from bitops here? > +static int get_sbits(uint32_t inst, int start, int len) > +{ > + int r = get_bits(inst, start, len); > + if (r & (1 << (len - 1))) { > + /* Extend the MSB 1 to the higher bits */ > + r |= -1 & ~((1ULL << len) - 1); > + } > + return r; > +} > + sextract32? > +static TCGv_i64 cpu_reg(int reg) > +{ > + if (reg == 31) { > + /* XXX leaks temps */ > + return tcg_const_i64(0); ... > + } else { > + return cpu_X[reg]; > + } > +} > + > +static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) > +{ > + TranslationBlock *tb; > + > + tb = s->tb; > + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { > + tcg_gen_goto_tb(n); > + gen_a64_set_pc_im(dest); > + tcg_gen_exit_tb((tcg_target_long)tb + n); > + } else { > + gen_a64_set_pc_im(dest); > + tcg_gen_exit_tb(0); > + } > +} > + > +static void handle_b(DisasContext *s, uint32_t insn) > +{ > + uint64_t addr = s->pc - 4 + (get_sbits(insn, 0, 26) << 2); > + > + if (get_bits(insn, 31, 1)) { > + /* BL */ > + tcg_gen_movi_i64(cpu_reg(30), s->pc); > + } > + gen_goto_tb(s, 0, addr); > + s->is_jmp = DISAS_TB_JUMP; > +} > + > void disas_a64_insn(CPUARMState *env, DisasContext *s) > { > uint32_t insn; > @@ -141,12 +193,21 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s) > s->insn = insn; > s->pc += 4; > > + /* One-off branch instruction layout */ > + switch (insn >> 26) { > + case 0x25: > + case 0x5: > + handle_b(s, insn); > + goto insn_done; > + } > + > switch ((insn >> 24) & 0x1f) { > default: > unallocated_encoding(s); > break; > } > > +insn_done: > if (unlikely(s->singlestep_enabled) && (s->is_jmp == DISAS_TB_JUMP)) { > /* go through the main loop for single step */ > s->is_jmp = DISAS_JUMP; > Ciao, Claudio