Signed-off-by: Michael Rolnik <mrol...@gmail.com> --- target-arc/Makefile.objs | 1 + target-arc/translate-inst.c | 170 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 30 ++++++++ 3 files changed, 201 insertions(+) create mode 100644 target-arc/translate-inst.c create mode 100644 target-arc/translate-inst.h
diff --git a/target-arc/Makefile.objs b/target-arc/Makefile.objs index a3475dd..6fdb000 100644 --- a/target-arc/Makefile.objs +++ b/target-arc/Makefile.objs @@ -21,6 +21,7 @@ obj-y += translate.o obj-y += helper.o obj-y += cpu.o +obj-y += translate-inst.o obj-y += gdbstub.o obj-y += decode.o obj-$(CONFIG_SOFTMMU) += machine.o diff --git a/target-arc/translate-inst.c b/target-arc/translate-inst.c new file mode 100644 index 0000000..50119bf --- /dev/null +++ b/target-arc/translate-inst.c @@ -0,0 +1,170 @@ +/* + * QEMU ARC CPU + * + * Copyright (c) 2016 Michael Rolnik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR dest PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ + +/* + see http://me.bios.io/images/d/dd/ARCompactISA_ProgrammersReference.pdf +*/ + +#include "translate.h" +#include "qemu/bitops.h" +#include "tcg/tcg.h" +#include "translate-inst.h" + +static void gen_add_Cf(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t1 = tcg_temp_new_i32(); + TCGv t2 = tcg_temp_new_i32(); + TCGv t3 = tcg_temp_new_i32(); + + tcg_gen_and_tl(t1, src1, src2); /* t1 = src1 & src2 */ + tcg_gen_andc_tl(t2, src1, dest);/* t2 = src1 & ~dest */ + tcg_gen_andc_tl(t3, src2, dest);/* t3 = src2 & ~dest */ + tcg_gen_or_tl(t1, t1, t2); /* t1 = t1 | t2 | t3 */ + tcg_gen_or_tl(t1, t1, t3); + + tcg_gen_shri_tl(cpu_Cf, t1, 31);/* Cf = t1(31) */ + + tcg_temp_free_i32(t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + +static void gen_add_Vf(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t1 = tcg_temp_new_i32(); + TCGv t2 = tcg_temp_new_i32(); + + /* + + src1 & src2 & ~dest | ~src1 & ~src2 & dest = (src1 ^ dest) & ~(src1 ^ src2) + + */ + tcg_gen_xor_tl(t1, src1, dest); /* t1 = src1 ^ dest */ + tcg_gen_xor_tl(t2, src1, src2); /* t2 = src1 ^ src2 */ + tcg_gen_andc_tl(t1, t1, t2); /* t1 = (src1 ^ src2) & ~(src1 ^ src2) */ + + tcg_gen_shri_tl(cpu_Vf, t1, 31);/* Vf = t1(31) */ + + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + +/* + ADC +*/ +int arc_gen_ADC(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) +{ + TCGv rslt = dest; + + if (TCGV_EQUAL(dest, src1) || TCGV_EQUAL(dest, src2)) { + rslt = tcg_temp_new_i32(); + } + + tcg_gen_add_tl(rslt, src1, src2); + tcg_gen_add_tl(rslt, rslt, cpu_Cf); + + if (ctx->opt.f) { + tcg_gen_setcond_tl(TCG_COND_EQ, cpu_Zf, rslt, ctx->zero); + tcg_gen_shri_tl(cpu_Nf, rslt, 31); + gen_add_Cf(rslt, src1, src2); + gen_add_Vf(rslt, src1, src2); + } + + if (!TCGV_EQUAL(dest, rslt)) { + tcg_gen_mov_tl(dest, rslt); + tcg_temp_free_i32(rslt); + } + + return BS_NONE; +} + +/* + ADD +*/ +int arc_gen_ADD(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) +{ + TCGv rslt = dest; + + if (TCGV_EQUAL(dest, src1) || TCGV_EQUAL(dest, src2)) { + rslt = tcg_temp_new_i32(); + } + + tcg_gen_add_tl(rslt, src1, src2); + + if (ctx->opt.f) { + tcg_gen_setcond_tl(TCG_COND_EQ, cpu_Zf, rslt, ctx->zero); + tcg_gen_shri_tl(cpu_Nf, rslt, 31); + gen_add_Cf(rslt, src1, src2); + gen_add_Vf(rslt, src1, src2); + } + + if (!TCGV_EQUAL(dest, rslt)) { + tcg_gen_mov_tl(dest, rslt); + tcg_temp_free_i32(rslt); + } + + return BS_NONE; +} + +/* + ADD1 +*/ +int arc_gen_ADD1(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new_i32(); + + tcg_gen_shli_tl(t0, src2, 1); + arc_gen_ADD(ctx, dest, src1, t0); + + tcg_temp_free_i32(t0); + + return BS_NONE; +} + +/* + ADD2 +*/ +int arc_gen_ADD2(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new_i32(); + + tcg_gen_shli_tl(t0, src2, 2); + arc_gen_ADD(ctx, dest, src1, t0); + + tcg_temp_free_i32(t0); + + return BS_NONE; +} + +/* + ADD3 +*/ +int arc_gen_ADD3(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new_i32(); + + tcg_gen_shli_tl(t0, src2, 3); + arc_gen_ADD(ctx, dest, src1, t0); + + tcg_temp_free_i32(t0); + + return BS_NONE; +} + diff --git a/target-arc/translate-inst.h b/target-arc/translate-inst.h new file mode 100644 index 0000000..08e23c7 --- /dev/null +++ b/target-arc/translate-inst.h @@ -0,0 +1,30 @@ +/* + * QEMU ARC CPU + * + * Copyright (c); 2016 Michael Rolnik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option); any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR dest PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ + +#include "translate.h" +#include "qemu/bitops.h" +#include "tcg/tcg.h" + +int arc_gen_ADC(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2); +int arc_gen_ADD(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2); +int arc_gen_ADD1(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2); +int arc_gen_ADD2(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2); +int arc_gen_ADD3(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2); + -- 2.4.9 (Apple Git-60)