ARC cores
cover ARC cores
This series of patches adds ARC target to QEMU. It indends to support
- ARCtangent-A5 processor
- ARC 600 processor
- ARC 700 processor
All instructions except ASLS are implemented. Not fully tested yet. However I was able to execute correctly recursive fibonacci calculation. Reset vector is assumed to be some hardcoded value which worked for my test. I am planning to get FreeRTOS for ARC, once I get it, I will able to verify and complete interrupt support.
Michael Rolnik (29):
target-arc: initial commit
target-arc: ADC, ADD, ADD1, ADD2, ADD3
target-arc: SUB, SUB1, SUB2, SUB3, SBC, RSUB, CMP
target-arc: AND, OR, XOR, BIC, TST
target-arc: ASL(m), ASR(m), LSR(m), ROR(m)
target-arc: EX, LD, ST, SYNC, PREFETCH
target-arc: MAX, MIN
target-arc: MOV, EXT, SEX, SWAP
target-arc: NEG, ABS, NOT
target-arc: POP, PUSH
target-arc: BCLR, BMSK, BSET, BTST, BXOR
target-arc: RLC, RRC
target-arc: NORM, NORMW
target-arc: MPY, MPYH, MPYHU, MPYU
target-arc: MUL64, MULU64, DIVAW
target-arc: BBIT0, BBIT1, BR
target-arc: B, BL
target-arc: J, JL
target-arc: LR, SR
target-arc: ADDS, ADDSDW, SUBS, SUBSDW
target-arc: ABSS, ABSSW, NEGS, NEGSW, RND16, SAT16
target-arc: ASLS, ASRS
target-arc: FLAG, BRK, SLEEP
target-arc: NOP, UNIMP
target-arc: TRAP, SWI
target-arc: RTIE
target-arc: LP
target-arc: decode
target-arc: sample board
.gitignore | 2 + MAINTAINERS | 6 + arch_init.c | 2 + configure | 5 + default-configs/arc-softmmu.mak | 0 hw/arc/Makefile.objs | 21 + hw/arc/sample.c | 80 ++ include/sysemu/arch_init.h | 1 + target-arc/Makefile.objs | 28 + target-arc/cpu-qom.h | 84 ++ target-arc/cpu.c | 269 ++++ target-arc/cpu.h | 174 +++ target-arc/decode.c | 2212 ++++++++++++++++++++++++++++++ target-arc/gdbstub.c | 138 ++ target-arc/helper.c | 74 + target-arc/helper.h | 29 + target-arc/machine.c | 35 + target-arc/machine.h | 21 + target-arc/op_helper.c | 443 ++++++ target-arc/translate-inst.c | 2855 +++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 175 +++ target-arc/translate.c | 424 ++++++ target-arc/translate.h | 223 +++ 23 files changed, 7301 insertions(+) create mode 100644 default-configs/arc-softmmu.mak create mode 100644 hw/arc/Makefile.objs create mode 100644 hw/arc/sample.c create mode 100644 target-arc/Makefile.objs create mode 100644 target-arc/cpu-qom.h create mode 100644 target-arc/cpu.c create mode 100644 target-arc/cpu.h create mode 100644 target-arc/decode.c create mode 100644 target-arc/gdbstub.c create mode 100644 target-arc/helper.c create mode 100644 target-arc/helper.h create mode 100644 target-arc/machine.c create mode 100644 target-arc/machine.h create mode 100644 target-arc/op_helper.c create mode 100644 target-arc/translate-inst.c create mode 100644 target-arc/translate-inst.h create mode 100644 target-arc/translate.c create mode 100644 target-arc/translate.h
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 1/29 target-arc: initial commit
--- .gitignore | 2 + MAINTAINERS | 5 + arch_init.c | 2 + configure | 5 + default-configs/arc-softmmu.mak | 0 include/sysemu/arch_init.h | 1 + target-arc/Makefile.objs | 26 +++ target-arc/cpu-qom.h | 84 ++++++++ target-arc/cpu.c | 269 +++++++++++++++++++++++++ target-arc/cpu.h | 174 +++++++++++++++++ target-arc/decode.c | 7 + target-arc/gdbstub.c | 138 +++++++++++++ target-arc/helper.c | 74 +++++++ target-arc/helper.h | 21 ++ target-arc/machine.c | 35 ++++ target-arc/machine.h | 21 ++ target-arc/translate.c | 424 ++++++++++++++++++++++++++++++++++++++++ target-arc/translate.h | 223 +++++++++++++++++++++ 18 files changed, 1511 insertions(+) create mode 100644 default-configs/arc-softmmu.mak create mode 100644 target-arc/Makefile.objs create mode 100644 target-arc/cpu-qom.h create mode 100644 target-arc/cpu.c create mode 100644 target-arc/cpu.h create mode 100644 target-arc/decode.c create mode 100644 target-arc/gdbstub.c create mode 100644 target-arc/helper.c create mode 100644 target-arc/helper.h create mode 100644 target-arc/machine.c create mode 100644 target-arc/machine.h create mode 100644 target-arc/translate.c create mode 100644 target-arc/translate.h
.gitignore +2 -0
@@ -58,6 +58,8 @@ /fsdev/virtfs-proxy-helper *.[1-9] *.a +*.swp +*.swo *.aux *.cp *.dvi
MAINTAINERS +5 -0
@@ -99,6 +99,11 @@ F: hw/alpha/ F: tests/tcg/alpha/ F: disas/alpha.c +ARC +M: Michael Rolnik <[email protected]> +S: Maintained +F: target-arc/ + ARM M: Peter Maydell <[email protected]> L: [email protected]
arch_init.c +2 -0
@@ -80,6 +80,8 @@ int graphic_depth = 32;#define QEMU_ARCH QEMU_ARCH_UNICORE32#elif defined(TARGET_TRICORE )#define QEMU_ARCH QEMU_ARCH_TRICORE +#elif defined(TARGET_ARC ) +#define QEMU_ARCH QEMU_ARCH_ARC#endif const uint32_t arch_type =QEMU_ARCH ;
configure +5 -0
@@ -5672,6 +5672,8 @@ case "$target_name" in ;; alpha) ;; + arc) + ;; arm|armeb) TARGET_ARCH=arm bflt="yes"
@@ -5874,6 +5876,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do disas_config "ARM_A64" fi ;; + arc) + disas_config "ARC" + ;; arm) disas_config "ARM" if test -n "${cxx}"; then
default-configs/arc-softmmu.mak new file +0 -0
include/sysemu/arch_init.h +1 -0
@@ -23,6 +23,7 @@ enum {QEMU_ARCH_UNICORE32 = (1 <<14 ),QEMU_ARCH_MOXIE = (1 <<15 ),QEMU_ARCH_TRICORE = (1 <<16 ), + QEMU_ARCH_ARC = (1 << 16), };extern const uint32_t arch_type;
target-arc/Makefile.objs new file +26 -0
@@ -0,0 +1,26 @@ +# +# 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 A 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> +# + +obj-y += translate.o +obj-y += helper.o +obj-y += cpu.o +obj-y += gdbstub.o +obj-y += decode.o +obj-$(CONFIG_SOFTMMU) += machine.o
target-arc/cpu-qom.h new file +84 -0
84 lines not on this page · raw message
target-arc/cpu.c new file +269 -0
269 lines not on this page · raw message
target-arc/cpu.h new file +174 -0
174 lines not on this page · raw message
target-arc/decode.c new file +7 -0
@@ -0,0 +1,7 @@ +#include "translate.h" + +int arc_decode (DisasCtxt *ctx) +{ +return BS_STOP ; +} +
target-arc/gdbstub.c new file +138 -0
138 lines not on this page · raw message
target-arc/helper.c new file +74 -0
74 lines not on this page · raw message
target-arc/helper.h new file +21 -0
@@ -0,0 +1,21 @@ +/* +* 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 A 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> +*/ + +DEF_HELPER_1 (debug, void, env)
target-arc/machine.c new file +35 -0
@@ -0,0 +1,35 @@ +/* +* 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 A 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 "qemu/osdep.h" +#include "hw/hw.h" +#include "cpu.h" +#include "hw/boards.h" +#include "machine.h" +#include "migration/qemu-file.h" + +const VMStateDescription vms_arc_cpu = { + .name ="cpu" , + .version_id =0 , + .minimum_version_id =0 , + .fields = (VMStateField []) { +VMSTATE_END_OF_LIST () + } +};
target-arc/machine.h new file +21 -0
@@ -0,0 +1,21 @@ +/* +* 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 A 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> +*/ + +extern const VMStateDescription vmstate_arc_cpu;
target-arc/translate.c new file +424 -0
424 lines not on this page · raw message
target-arc/translate.h new file +223 -0
223 lines not on this page · raw message
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 01/29] target-arc: initial commit
target-arc/cpu.h line 63
Quoted 2 lines · Michael Rolnik
target-arc/cpu.h new file +2
-0+#define CPU_IMM (env) ((env)->r[62]) +#define CPU_PCL (env) ((env)->r[63])
You don't need to represent these as actual registers. These are better considered placeholder regnums to be filled in with actual values during translation.
Quoted 9 lines
target-arc/cpu.h new file +9
-0+struct CPUARCState { +uint32_t r[64 ]; + +struct { +uint32_t Lf; +uint32_t Zf;/* zero */ +uint32_t Nf;/* negative */ +uint32_t Cf;/* carry */ +uint32_t Vf;/* overflow */
target-arc/cpu.h line 84
Quoted 10 lines
target-arc/cpu.h new file +10
-0+uint32_t Uf; + +uint32_t DEf; +uint32_t AEf; +uint32_t A2f;/* interrupt 1 is active */ +uint32_t A1f;/* interrupt 2 is active */ +uint32_t E2f;/* interrupt 1 mask */ +uint32_t E1f;/* interrupt 2 mask */ +uint32_t Hf;/* halt */ + } stat, stat_l1, stat_l2, stat_er;
There is no reason to represent each bit as a whole word, and even less to have four copies.
Only the current NZCV bits are relevant for expansion to a word, and even then you should consider not canonicalizing N, Z and V to a pure boolean value.
target-arc/cpu.h line 90
Quoted 6 lines
target-arc/cpu.h new file +6
-0+ +struct { +uint32_t S2; +uint32_t S1; +uint32_t CS; + } macmod;
Does CS really need to be represented at all? It appears to me to be a field that you write to that clears S1 and S2.
target-arc/gdbstub.c line 78
Quoted 5 lines
target-arc/gdbstub.c new file +5
-0+switch (n) { + case 0x00 ... 0x3f: { + val = env->r[n]; +break ; + }
Please use the proper format for all switch statements.
switch (n) {
case 0x00 ... 0x3f:
val = env->r[n];
break;target-arc/translate.c line 37
Quoted 12 lines
target-arc/translate.c new file +12
-0+ +TCGv_env cpu_env; + +TCGv cpu_gp;/* Global Pointer */ +TCGv cpu_fp;/* Frame Pointer */ +TCGv cpu_sp;/* Stack Pointer */ +TCGv cpu_ilink1;/* Level 1 interrupt link register */ +TCGv cpu_ilink2;/* Level 2 interrupt link register */ +TCGv cpu_blink;/* Branch link register */ +TCGv cpu_mlo;/* Multiply low 32 bits, read only */ +TCGv cpu_mmi;/* Multiply middle 32 bits, read only */ +TCGv cpu_mhi;/* Multiply high 32 bits, read only */
Why are these separate variables? They overlap cpu_r[N]. If you want them as names for clarity in translation, #define seems good enough.
target-arc/translate.c line 258
Quoted 3 lines
target-arc/translate.c new file +3
-0+int arc_gen_INVALID (DisasCtxt *ctx) +{ +printf ("invalid inst @:%08x\n" , ctx->cpc);
No printf. It's not useful, even temporarily.
target-arc/translate.c line 295
Quoted 8 lines
target-arc/translate.c new file +8
-0+ ctx.zero =tcg_const_local_i32 (0 ); + ctx.one =tcg_const_local_i32 (1 ); + ctx.msb32 =tcg_const_local_i32 (0x80000000 ); + ctx.msb16 =tcg_const_local_i32 (0x00008000 ); + ctx.smax16 =tcg_const_local_i32 (0x7fffffff ); + ctx.smax32 =tcg_const_local_i32 (0x00007fff ); + ctx.smax5 =tcg_const_local_i32 (0x0000001f ); + ctx.smin5 =tcg_const_local_i32 (0xffffffe1 );
Why are you creating all of these? Creating local temps containing immediates is a horrible waste.
Quoted 1 line
+ if (ctx.npc ==
env->lpe) {
You can't look at the contents of ENV during translation.
You'll need to implement this feature similar to how it's done for xtensa. See helper_wsr_lbeg, helper_wsr_lend, and gen_check_loop_end.
r~
Re: [Qemu-devel] [PATCH RFC v1 01/29] target-arc: initial commit
Hello,
Quoted 5 lines · Richard Henderson
Quoted 1 line
+ if (ctx.npc ==
env->lpe) {You can't look at the contents of ENV during translation.
You'll need to implement this feature similar to how it's done for xtensa. See
helper_wsr_lbeg,helper_wsr_lend, andgen_check_loop_end.
I think it's fairly expensive solution, as it allows to have only one TB with zero overhead loop at a time. I'm looking at ways to optimize it, perhaps recording lbeg in the TB's cs_base.
Signature · 2 lines
Thanks. -- Max
Re: [Qemu-devel] [PATCH RFC v1 01/29] target-arc: initial commit
Quoted 4 lines · Max Filippov
Hello,
Quoted 1 line · Richard Henderson
Quoted 1 line
+ if (ctx.npc ==
env->lpe) {
Quoted 9 lines
Quoted 4 lines
You can't look at the contents of ENV during translation.
You'll need to implement this feature similar to how it's done for xtensa. See
helper_wsr_lbeg,helper_wsr_lend, andgen_check_loop_end.I think it's fairly expensive solution, as it allows to have only one TB with zero overhead loop at a time. I'm looking at ways to optimize it, perhaps recording lbeg in the TB's
cs_base.
It may be expensive, but at least it works. Unlike the mechanism quoted above, which doesn't work at all.
r~
RFC PATCH 2/29 target-arc: ADC, ADD, ADD1, ADD2, ADD3
In reply to Michael Rolnik--- 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
target-arc/Makefile.objs +1 -0
@@ -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
target-arc/translate-inst.c new file +170 -0
170 lines not on this page · raw message
target-arc/translate-inst.h new file +30 -0
@@ -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); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 02/29] target-arc: ADC, ADD, ADD1, ADD2, ADD3
Quoted 8 lines · Michael Rolnik
Signed-off-by Michael Rolnik <[email protected]>--- 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
Please don't split translate.c into translate-inst.* and decode.c like you did for AVR. Since you're not generating any source from a template, there's even less call for it here than before.
target-arc/translate-inst.c line 42
Quoted 13 lines
target-arc/translate-inst.c new file +13
-0+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) */
I've shown you before how to generate a carry bit from tcg_gen_add2_tl.
target-arc/translate-inst.c line 78
Quoted 7 lines
target-arc/translate-inst.c new file +7
-0+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 (); + }
It would be cleaner to simply always use a temporary. The tcg optimizer will generate the same code either way.
r~
RFC PATCH 3/29 target-arc: SUB, SUB1, SUB2, SUB3, SBC, RSUB, CMP
In reply to Michael Rolnik--- target-arc/translate-inst.c | 165 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 8 +++ 2 files changed, 173 insertions(+)
target-arc/translate-inst.c +165 -0
@@ -66,6 +66,44 @@ static void gen_add_Vf(TCGv dest, TCGv src1, TCGv src2)tcg_temp_free_i32 (t1); } +static void gen_sub_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_not_tl (t1, src1);/* t1 = ~src1 */ +tcg_gen_and_tl (t2, t1, src2);/* t2 = ~src1 & src2 */ +tcg_gen_or_tl (t3, t1, src2);/* t3 = (~src1 | src2) & dest */ +tcg_gen_and_tl (t3, t3, dest); +tcg_gen_or_tl (t2, t2, t3);/* t2 = ~src1 & src2 +| ~src1 & dest +| dest & src2 */ +tcg_gen_shri_tl (cpu_Cf, t2,31 );/* Cf = t2(31) */ + +tcg_temp_free_i32 (t3); +tcg_temp_free_i32 (t2); +tcg_temp_free_i32 (t1); +} + +static void gen_sub_Vf (TCGv dest,TCGv src1,TCGv src2) +{ +TCGv t1 =tcg_temp_new_i32 (); +TCGv t2 =tcg_temp_new_i32 (); + +/* +t1 = src1 & ~src2 & ~dest +| ~src1 & src2 & dest += (src1 ^ dest) & (src1 ^ dest)*/ +tcg_gen_xor_tl (t1, src1, dest); +tcg_gen_xor_tl (t2, src1, src2); +tcg_gen_and_tl (t1, t1, t2); +tcg_gen_shri_tl (cpu_Vf, t1,31 );/* Vf = t1(31) */ + +tcg_temp_free_i32 (t2); +tcg_temp_free_i32 (t1); +} +/* ADC */
@@ -168,3 +206,130 @@ int arc_gen_ADD3(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +SUB +*/ +int arc_gen_SUB (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_sub_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_sub_Cf (rslt, src1, src2); +gen_sub_Vf (rslt, src1, src2); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +SBC +*/ +int arc_gen_SBC (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_sub_tl (rslt, src1, src2); +tcg_gen_sub_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_sub_Cf (rslt, src1, src2); +gen_sub_Vf (rslt, src1, src2); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +/* +SUB1 +*/ +int arc_gen_SUB1 (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv t0 =tcg_temp_new_i32 (); + +tcg_gen_shli_tl (t0, src2,1 ); +arc_gen_SUB (ctx, dest, src1, t0); + +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +SUB2 +*/ +int arc_gen_SUB2 (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv t0 =tcg_temp_new_i32 (); + +tcg_gen_shli_tl (t0, src2,2 ); +arc_gen_SUB (ctx, dest, src1, t0); + +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +SUB3 +*/ +int arc_gen_SUB3 (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv t0 =tcg_temp_new_i32 (); + +tcg_gen_shli_tl (t0, src2,3 ); +arc_gen_SUB (ctx, dest, src1, t0); + +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +RSUB +*/ +int arc_gen_RSUB (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +return arc_gen_SUB (ctx, dest, src2, src1); +} + +/* +CMP +*/ +int arc_gen_CMP (DisasCtxt *ctx,TCGv src1,TCGv src2) +{ +TCGv rslt =tcg_temp_new_i32 (); + +tcg_gen_sub_tl (rslt, src1, src2); + +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +gen_sub_Cf (rslt, src1, src2); +gen_sub_Vf (rslt, src1, src2); + +tcg_temp_free_i32 (rslt); + +return BS_NONE ; +}
target-arc/translate-inst.h +8 -0
@@ -28,3 +28,11 @@ 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); +int arc_gen_SUB (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SUB1 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SUB2 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SUB3 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SBC (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_RSUB (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_CMP (DisasCtxt *c,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 03/29] target-arc: SUB, SUB1, SUB2, SUB3, SBC, RSUB, CMP
Quoted 4 lines · Michael Rolnik
target-arc/translate-inst.c +4
-0+static void gen_sub_Cf (TCGv dest,TCGv src1,TCGv src2) +{ +TCGv t1 =tcg_temp_new_i32 (); +TCGv t2 =tcg_temp_new_i32 ();
target-arc/translate-inst.c static void gen_add_Vf(TCGv dest, TCGv src1, TCGv src2) · line 82
Quoted 10 lines
target-arc/translate-inst.c +10
-0+TCGv t3 =tcg_temp_new_i32 (); + +tcg_gen_not_tl (t1, src1);/* t1 = ~src1 */ +tcg_gen_and_tl (t2, t1, src2);/* t2 = ~src1 & src2 */ +tcg_gen_or_tl (t3, t1, src2);/* t3 = (~src1 | src2) & dest */ +tcg_gen_and_tl (t3, t3, dest); +tcg_gen_or_tl (t2, t2, t3);/* t2 = ~src1 & src2 +| ~src1 & dest +| dest & src2 */ +tcg_gen_shri_tl (cpu_Cf, t2,31 );/* Cf = t2(31) */
Again, this can be done with tcg_gen_sub2_tl.
r~
RFC PATCH 4/29 target-arc: AND, OR, XOR, BIC, TST
In reply to Michael Rolnik--- target-arc/translate-inst.c | 119 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 6 +++ 2 files changed, 125 insertions(+)
target-arc/translate-inst.c +119 -0
@@ -333,3 +333,122 @@ int arc_gen_CMP(DisasCtxt *ctx, TCGv src1, TCGv src2)return BS_NONE ; } + +/* +TST +*/ +int arc_gen_TST (DisasCtxt *ctx,TCGv src1,TCGv src2) +{ +TCGv temp =tcg_temp_new_i32 (); + + ctx->opt.f =1 ; +arc_gen_AND (ctx, temp, src1, src2); +tcg_temp_free_i32 (temp); + +return BS_NONE ; +} + +/* +AND +*/ +int arc_gen_AND (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_and_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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +OR +*/ +int arc_gen_OR (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_or_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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +BIC +*/ +int arc_gen_BIC (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_andc_tl (rslt, src1, src2);/* 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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +XOR +*/ +int arc_gen_XOR (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_xor_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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +6 -0
@@ -36,3 +36,9 @@ int arc_gen_SBC(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_RSUB (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_CMP (DisasCtxt *c,TCGv src1,TCGv src2); +int arc_gen_AND (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_OR (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_BIC (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_XOR (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_TST (DisasCtxt *c,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 04/29] target-arc: AND, OR, XOR, BIC, TST
Quoted 9 lines · Michael Rolnik
target-arc/translate-inst.c +9
-0+int arc_gen_AND (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_and_tl (rslt, src1, src2);
target-arc/translate-inst.c int arc_gen_CMP(DisasCtxt *ctx, TCGv src1, TCGv src2) · line 372
Quoted 10 lines
target-arc/translate-inst.c +10
-0+ +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + }
There is no reason for this rslt temporary stuff.
Unlike with add & sub, src1 & src2 are not used after the operation, for any of the logical operations.
r~
RFC PATCH 5/29 target-arc: ASL(m), ASR(m), LSR(m), ROR(m)
In reply to Michael Rolnik--- target-arc/translate-inst.c | 212 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 9 ++ 2 files changed, 221 insertions(+)
target-arc/translate-inst.c +212 -0
@@ -452,3 +452,215 @@ int arc_gen_XOR(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +ASL +*/ +int arc_gen_ASL (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +arc_gen_ADD (ctx, dest, src1, src1); + +return BS_NONE ; +} + +/* +ASLm +*/ +int arc_gen_ASLm (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv t0 =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (t0, src2,31 ); +tcg_gen_shl_tl (rslt, src1, t0); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_rotl_tl (cpu_Cf, src1, t0); +tcg_gen_andi_tl (cpu_Cf, cpu_Cf,1 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +ASR +*/ +int arc_gen_ASR (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_sari_tl (rslt, src1,1 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_andi_tl (cpu_Cf, src1,1 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +ASRm +*/ +int arc_gen_ASRm (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv t0 =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (t0, src2,31 ); +tcg_gen_sar_tl (rslt, src1, t0); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_rotr_tl (cpu_Cf, src1, src2); +tcg_gen_shri_tl (cpu_Cf, cpu_Cf,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +LSR +*/ +int arc_gen_LSR (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_shri_tl (rslt, src1,1 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_movi_tl (cpu_Nf,0 ); +tcg_gen_andi_tl (cpu_Cf, src1,1 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +LSRm +*/ +int arc_gen_LSRm (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv t0 =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (t0, src2,31 ); +tcg_gen_shr_tl (rslt, src1, t0); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_rotr_tl (cpu_Cf, src1, t0); +tcg_gen_shri_tl (cpu_Cf, cpu_Cf,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +ROR +*/ +int arc_gen_ROR (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_rotri_tl (rslt, src1,1 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Cf, cpu_Nf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +RORm +*/ +int arc_gen_RORm (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (rslt, src2,0x1f ); +tcg_gen_rotr_tl (rslt, src1, rslt); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Cf, cpu_Nf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +9 -0
@@ -42,3 +42,12 @@ int arc_gen_BIC(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_XOR (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_TST (DisasCtxt *c,TCGv src1,TCGv src2); +int arc_gen_ASL (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_ASLm (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_ASR (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_ASRm (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_LSR (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_LSRm (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_ROR (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_RORm (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 6/29 target-arc: EX, LD, ST, SYNC, PREFETCH
In reply to Michael Rolnik--- target-arc/translate-inst.c | 230 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 10 ++ 2 files changed, 240 insertions(+)
target-arc/translate-inst.c +230 -0
@@ -664,3 +664,233 @@ int arc_gen_RORm(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +EX +*/ +int arc_gen_EX (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv temp =tcg_temp_new_i32 (); + +tcg_gen_mov_tl (temp, dest); + +tcg_gen_qemu_ld_tl (dest, src1, ctx->memidx,MO_UL ); +tcg_gen_qemu_st_tl (temp, src1, ctx->memidx,MO_UL ); + +tcg_temp_free_i32 (temp); + +return BS_NONE ; +} + +/* +LD +*/ +int arc_gen_LD (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv addr =tcg_temp_new_i32 (); + +/* address */ +switch (ctx->opt.aa) { +case 0x00 : { +tcg_gen_add_tl (addr, src1, src2); + }break ; + +case 0x01 : { +tcg_gen_add_tl (addr, src1, src2); + }break ; + +case 0x02 : { +tcg_gen_mov_tl (addr, src1); + }break ; + +case 0x03 : { +if (ctx->opt.zz ==0x02 ) { +tcg_gen_shli_tl (addr, src2,1 ); + }else if (ctx->opt.zz ==0x00 ) { +tcg_gen_shli_tl (addr, src2,2 ); + }else { +assert (!"bad format" ); + } + +tcg_gen_add_tl (addr, src1, addr); + }break ; + } + +/* memory read */ +switch (ctx->opt.zz) { +case 0x00 : { +tcg_gen_qemu_ld_tl (dest, addr, ctx->memidx,MO_UL ); + }break ; + +case 0x01 : { +if (ctx->opt.x) { +tcg_gen_qemu_ld_tl (dest, addr, ctx->memidx,MO_SB ); + }else { +tcg_gen_qemu_ld_tl (dest, addr, ctx->memidx,MO_UB ); + } + }break ; + +case 0x02 : { +if (ctx->opt.x) { +tcg_gen_qemu_ld_tl (dest, addr, ctx->memidx,MO_SW ); + }else { +tcg_gen_qemu_ld_tl (dest, addr, ctx->memidx,MO_UW ); + } + }break ; + +case 0x03 : { +assert (!"reserved" ); + }break ; + } + +/* address write back */ +if (ctx->opt.aa ==0x01 || ctx->opt.aa ==0x02 ) { +tcg_gen_add_tl (src1, src1, src2); + } + +tcg_temp_free_i32 (addr); + +return BS_NONE ; +} + +/* +LDB +*/ +int arc_gen_LDB (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ + + ctx->opt.zz =1 ;/* byte */ + ctx->opt.x =0 ;/* no sign extension */ + ctx->opt.aa =0 ;/* no address write back */ + ctx->opt.di =0 ;/* cached data memory access */ + +return arc_gen_LD (ctx, dest, src1, src2); +} + +/* +LDW +*/ +int arc_gen_LDW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ + + ctx->opt.zz =2 ;/* word */ + ctx->opt.x =0 ;/* no sign extension */ + ctx->opt.aa =0 ;/* no address write back */ + ctx->opt.di =0 ;/* cached data memory access */ + +return arc_gen_LD (ctx, dest, src1, src2); +} + +/* +ST +*/ +int arc_gen_ST (DisasCtxt *ctx,TCGv src1,TCGv src2,TCGv src3) +{ +TCGv addr =tcg_temp_new_i32 (); + +/* address */ +switch (ctx->opt.aa) { +case 0x00 : { +tcg_gen_add_tl (addr, src2, src3); + }break ; + +case 0x01 : { +tcg_gen_add_tl (addr, src2, src3); + }break ; + +case 0x02 : { +tcg_gen_mov_tl (addr, src2); + }break ; + +case 0x03 : { +if (ctx->opt.zz ==0x02 ) { +tcg_gen_shli_tl (addr, src3,1 ); + }else if (ctx->opt.zz ==0x00 ) { +tcg_gen_shli_tl (addr, src3,2 ); + }else { +assert (!"bad format" ); + } + +tcg_gen_add_tl (addr, src2, addr); + }break ; + } + +/* write */ +switch (ctx->opt.zz) { +case 0x00 : { +tcg_gen_qemu_st_tl (src1, addr, ctx->memidx,MO_UL ); + }break ; + +case 0x01 : { +tcg_gen_qemu_st_tl (src1, addr, ctx->memidx,MO_UB ); + }break ; + +case 0x02 : { +tcg_gen_qemu_st_tl (src1, addr, ctx->memidx,MO_UW ); + }break ; + +case 0x03 : { +assert (!"reserved" ); + }break ; + } + +/* address write back */ +if (ctx->opt.aa ==0x01 || ctx->opt.aa ==0x02 ) { +tcg_gen_add_tl (src2, src2, src3); + } + +tcg_temp_free_i32 (addr); + +return BS_NONE ; +} + +/* +STB +*/ +int arc_gen_STB (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ + + ctx->opt.zz =1 ;/* byte */ + ctx->opt.x =0 ;/* no sign extension */ + ctx->opt.aa =0 ;/* no address write back */ + ctx->opt.di =0 ;/* cached data memory access */ + +return arc_gen_ST (ctx, dest, src1, src2); +} + +/* +STW +*/ +int arc_gen_STW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ + + ctx->opt.zz =2 ;/* word */ + ctx->opt.x =0 ;/* no sign extension */ + ctx->opt.aa =0 ;/* no address write back */ + ctx->opt.di =0 ;/* cached data memory access */ + +return arc_gen_ST (ctx, dest, src1, src2); +} + +/* +PREFETCH +*/ +int arc_gen_PREFETCH (DisasCtxt *ctx,TCGv src1,TCGv src2) +{ +TCGv temp =tcg_temp_new_i32 (); + +arc_gen_LD (ctx, temp, src1, src2); + +tcg_temp_free_i32 (temp); + +return BS_NONE ; +} + +/* +SYNC +*/ +int arc_gen_SYNC (DisasCtxt *ctx) +{ +/* nothing to do*/ + +return BS_NONE ; +}
target-arc/translate-inst.h +10 -0
@@ -51,3 +51,13 @@ int arc_gen_LSRm(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_ROR (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_RORm (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_EX (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_LD (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_LDW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_LDB (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_ST (DisasCtxt *c,TCGv src1,TCGv src2,TCGv src3); +int arc_gen_STW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_STB (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_PREFETCH (DisasCtxt *c,TCGv src1,TCGv src2); +int arc_gen_SYNC (DisasCtxt *c); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 06/29] target-arc: EX, LD, ST, SYNC, PREFETCH
Quoted 17 lines · Michael Rolnik
Signed-off-by Michael Rolnik <[email protected]>--- target-arc/translate-inst.c | 230 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 10 ++ 2 files changed, 240 insertions(+)target-arc/translate-inst.c +3
-0@@ -664,3 +664,233 @@ int arc_gen_RORm(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +EX +*/
target-arc/translate-inst.c int arc_gen_RORm(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) · line 679
Quoted 10 lines
target-arc/translate-inst.c +10
-0+int arc_gen_EX (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv temp =tcg_temp_new_i32 (); + +tcg_gen_mov_tl (temp, dest); + +tcg_gen_qemu_ld_tl (dest, src1, ctx->memidx,MO_UL ); +tcg_gen_qemu_st_tl (temp, src1, ctx->memidx,MO_UL ); + +tcg_temp_free_i32 (temp);
You need to load into temp and store directly from dest. Otherwise you incorrectly clobber dest when the page is read-only.
target-arc/translate-inst.c int arc_gen_RORm(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) · line 692
Quoted 6 lines
target-arc/translate-inst.c +6
-0+int arc_gen_LD (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv addr =tcg_temp_new_i32 (); + +/* address */ +switch (ctx->opt.aa) {
You should have a common subroutine for computing addresses. And probably for implementing all loads and all stores. Use TCGMemOp to distinguish the cases.
target-arc/translate-inst.c int arc_gen_RORm(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) · line 881
Quoted 5 lines
target-arc/translate-inst.c +5
-0+int arc_gen_PREFETCH (DisasCtxt *ctx,TCGv src1,TCGv src2) +{ +TCGv temp =tcg_temp_new_i32 (); + +arc_gen_LD (ctx, temp, src1, src2);
A prefetch should be implemented as a NOP. Otherwise you'll generate exceptions when you shouldn't.
r~
RFC PATCH 7/29 target-arc: MAX, MIN
In reply to Michael Rolnik--- target-arc/translate-inst.c | 29 +++++++++++++++++++++++++++++ target-arc/translate-inst.h | 3 +++ 2 files changed, 32 insertions(+)
target-arc/translate-inst.c +29 -0
@@ -894,3 +894,32 @@ int arc_gen_SYNC(DisasCtxt *ctx)return BS_NONE ; } + +/* +MAX +*/ +int arc_gen_MAX (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +if (ctx->opt.f) { +arc_gen_CMP (ctx, src1, src2); + } + +tcg_gen_movcond_tl (TCG_COND_GEU , dest, src1, src2, src1, src2); + +return BS_NONE ; +} + +/* +MIN +*/ +int arc_gen_MIN (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +if (ctx->opt.f) { +arc_gen_CMP (ctx, src1, src2); + } + +tcg_gen_movcond_tl (TCG_COND_GEU , dest, src1, src2, src2, src1); + +return BS_NONE ; +} +
target-arc/translate-inst.h +3 -0
@@ -61,3 +61,6 @@ int arc_gen_STB(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2);int arc_gen_PREFETCH (DisasCtxt *c,TCGv src1,TCGv src2);int arc_gen_SYNC (DisasCtxt *c); +int arc_gen_MAX (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MIN (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 07/29] target-arc: MAX, MIN
target-arc/translate-inst.c int arc_gen_SYNC(DisasCtxt *ctx) · line 907
Quoted 7 lines · Michael Rolnik
target-arc/translate-inst.c +7
-0+int arc_gen_MAX (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +if (ctx->opt.f) { +arc_gen_CMP (ctx, src1, src2); + } + +tcg_gen_movcond_tl (TCG_COND_GEU , dest, src1, src2, src1, src2);
These are supposed to be signed comparisons.
r~
RFC PATCH 8/29 target-arc: MOV, EXT, SEX, SWAP
In reply to Michael Rolnik--- target-arc/translate-inst.c | 156 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 7 ++ 2 files changed, 163 insertions(+)
target-arc/translate-inst.c +156 -0
@@ -923,3 +923,159 @@ int arc_gen_MIN(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +MOV +*/ +int arc_gen_MOV (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_mov_tl (rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +EXTB +*/ +int arc_gen_EXTB (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_ext8u_tl (rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_movi_tl (cpu_Nf,0 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +EXTW +*/ +int arc_gen_EXTW (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_ext16u_tl (rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_movi_tl (cpu_Nf,0 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +SEXB +*/ +int arc_gen_SEXB (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_ext8s_tl (rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +SEXW +*/ +int arc_gen_SEXW (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_ext16s_tl (rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +SWAP +*/ +int arc_gen_SWAP (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_rotli_tl (rslt, src1,16 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +7 -0
@@ -64,3 +64,10 @@ int arc_gen_SYNC(DisasCtxt *c);int arc_gen_MAX (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_MIN (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MOV (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_EXTB (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_EXTW (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_SEXB (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_SEXW (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_SWAP (DisasCtxt *c,TCGv dest,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 9/29 target-arc: NEG, ABS, NOT
In reply to Michael Rolnik--- target-arc/translate-inst.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 +++ 2 files changed, 72 insertions(+)
target-arc/translate-inst.c +68 -0
@@ -1079,3 +1079,71 @@ int arc_gen_SWAP(DisasCtxt *ctx, TCGv dest, TCGv src1)return BS_NONE ; } +/* +ABS +*/ +int arc_gen_ABS (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 t0 =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_neg_i32 (t0, src1); +tcg_gen_movcond_tl (TCG_COND_GEU , rslt, src1, ctx->msb32, src1, t0); + +tcg_temp_free_i32 (t0); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Cf, src1,31 ); +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Nf, src1, ctx->msb32); +tcg_gen_mov_tl (cpu_Vf, cpu_Nf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +NEG +*/ +int arc_gen_NEG (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +arc_gen_SUB (ctx, dest, ctx->zero, src1); + +return BS_NONE ; +} + +/* +NOT +*/ +int arc_gen_NOT (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_not_tl (rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +4 -0
@@ -71,3 +71,7 @@ int arc_gen_SEXB(DisasCtxt *c, TCGv dest, TCGv src1);int arc_gen_SEXW (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_SWAP (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_NEG (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_ABS (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_NOT (DisasCtxt *c,TCGv dest,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 09/29] target-arc: NEG, ABS, NOT
Quoted 1 line · Michael Rolnik
+
tcg_gen_movcond_tl(TCG_COND_GEU, rslt, src1, ctx->msb32, src1, t0);
Better as a signed comparison vs zero.
r~
RFC PATCH 10/29 target-arc: POP, PUSH
In reply to Michael Rolnik--- target-arc/translate-inst.c | 22 ++++++++++++++++++++++ target-arc/translate-inst.h | 3 +++ 2 files changed, 25 insertions(+)
target-arc/translate-inst.c +22 -0
@@ -1147,3 +1147,25 @@ int arc_gen_NOT(DisasCtxt *ctx, TCGv dest, TCGv src1)return BS_NONE ; } +/* +POP +*/ +int arc_gen_POP (DisasCtxt *ctx,TCGv src1) +{ +tcg_gen_qemu_ld_tl (src1, cpu_sp, ctx->memidx,MO_UL ); +tcg_gen_addi_tl (cpu_sp, cpu_sp,4 ); + +return BS_NONE ; +} + +/* +PUSH +*/ +int arc_gen_PUSH (DisasCtxt *ctx,TCGv src1) +{ +tcg_gen_subi_tl (cpu_sp, cpu_sp,4 ); +tcg_gen_qemu_st_tl (src1, cpu_sp, ctx->memidx,MO_UL ); + +return BS_NONE ; +} +
target-arc/translate-inst.h +3 -0
@@ -75,3 +75,6 @@ int arc_gen_NEG(DisasCtxt *c, TCGv dest, TCGv src1);int arc_gen_ABS (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_NOT (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_POP (DisasCtxt *c,TCGv src1); +int arc_gen_PUSH (DisasCtxt *c,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 10/29] target-arc: POP, PUSH
target-arc/translate-inst.c int arc_gen_NOT(DisasCtxt *ctx, TCGv dest, TCGv src1) · line 1167
Quoted 2 lines · Michael Rolnik
target-arc/translate-inst.c +2
-0+tcg_gen_subi_tl (cpu_sp, cpu_sp,4 ); +tcg_gen_qemu_st_tl (src1, cpu_sp, ctx->memidx,MO_UL );
You need to delay the write to the stack pointer until after the store, otherwise sp will have the incorrect contents if the page is not writable.
r~
RFC PATCH 11/29 target-arc: BCLR, BMSK, BSET, BTST, BXOR
In reply to Michael Rolnik--- target-arc/translate-inst.c | 139 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 6 ++ 2 files changed, 145 insertions(+)
target-arc/translate-inst.c +139 -0
@@ -1169,3 +1169,142 @@ int arc_gen_PUSH(DisasCtxt *ctx, TCGv src1)return BS_NONE ; } +/* +BCLR +*/ +int arc_gen_BCLR (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_andi_tl (rslt, src2,0x3f ); +tcg_gen_shr_tl (rslt, ctx->one, rslt); +tcg_gen_andc_tl (rslt, src1, rslt);/* rslt = src1 & ~(1 << 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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +BMSK +*/ +int arc_gen_BMSK (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv mask =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (mask, src2,0x3f ); +tcg_gen_add_tl (mask, mask, ctx->one); +tcg_gen_shr_tl (mask, ctx->one, mask); +tcg_gen_sub_tl (mask, mask, ctx->one); + +tcg_gen_and_tl (rslt, src1, mask); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +tcg_temp_free_i32 (mask); + +return BS_NONE ; +} + +/* +BSET +*/ +int arc_gen_BSET (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_andi_tl (rslt, src2,0x3f ); +tcg_gen_shr_tl (rslt, ctx->one, rslt); +tcg_gen_or_tl (rslt, src1, rslt);/* rslt = src1 | (1 << 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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +BTST +*/ +int arc_gen_BTST (DisasCtxt *ctx,TCGv src1,TCGv src2) +{ +TCGv rslt =tcg_temp_new_i32 (); + +tcg_gen_andi_tl (rslt, src2,0x3f ); +tcg_gen_shr_tl (rslt, ctx->one, rslt); +tcg_gen_and_tl (rslt, src1, rslt);/* rslt = src1 & (1 << 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 ); + } + +tcg_temp_free_i32 (rslt); + +return BS_NONE ; +} + +/* +BXOR +*/ +int arc_gen_BXOR (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_andi_tl (rslt, src2,0x3f ); +tcg_gen_shr_tl (rslt, ctx->one, rslt); +tcg_gen_xor_tl (rslt, src1, rslt);/* rslt = src1 ^ (1 << 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 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +6 -0
@@ -78,3 +78,9 @@ int arc_gen_NOT(DisasCtxt *c, TCGv dest, TCGv src1);int arc_gen_POP (DisasCtxt *c,TCGv src1);int arc_gen_PUSH (DisasCtxt *c,TCGv src1); +int arc_gen_BCLR (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_BMSK (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_BSET (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_BTST (DisasCtxt *c,TCGv src1,TCGv src2); +int arc_gen_BXOR (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 11/29] target-arc: BCLR, BMSK, BSET, BTST, BXOR
target-arc/translate-inst.c int arc_gen_PUSH(DisasCtxt *ctx, TCGv src1) · line 1183
Quoted 9 lines · Michael Rolnik
target-arc/translate-inst.c +9
-0+int arc_gen_BCLR (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_andi_tl (rslt, src2,0x3f );
0x1f, in all of the functions.
target-arc/translate-inst.c int arc_gen_PUSH(DisasCtxt *ctx, TCGv src1) · line 1215
Quoted 3 lines
target-arc/translate-inst.c +3
-0+tcg_gen_add_tl (mask, mask, ctx->one); +tcg_gen_shr_tl (mask, ctx->one, mask); +tcg_gen_sub_tl (mask, mask, ctx->one);
I know this is the description in the manual, but this will produce a shift of 32 with an input of 31, which is illegal in tcg.
You need to use
mask = -1u >> (src2 ^ 31)
r~
RFC PATCH 12/29 target-arc: RLC, RRC
In reply to Michael Rolnik--- target-arc/translate-inst.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 2 ++ 2 files changed, 59 insertions(+)
target-arc/translate-inst.c +57 -0
@@ -1308,3 +1308,60 @@ int arc_gen_BXOR(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +RLC +*/ +int arc_gen_RLC (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_shli_tl (rslt, src1,1 ); +tcg_gen_or_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 ); +tcg_gen_shri_tl (cpu_Cf, src1,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +RRC +*/ +int arc_gen_RRC (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (rslt, src1,0xfffffffe ); +tcg_gen_or_tl (rslt, rslt, cpu_Cf); +tcg_gen_rotri_tl (rslt, rslt,1 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_andi_tl (cpu_Cf, src1,1 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +2 -0
@@ -84,3 +84,5 @@ int arc_gen_BSET(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_BTST (DisasCtxt *c,TCGv src1,TCGv src2);int arc_gen_BXOR (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_RRC (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_RLC (DisasCtxt *c,TCGv dest,TCGv src1);
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 13/29 target-arc: NORM, NORMW
In reply to Michael Rolnik--- target-arc/Makefile.objs | 1 + target-arc/helper.h | 3 ++ target-arc/op_helper.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.c | 52 ++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 ++ 5 files changed, 151 insertions(+) create mode 100644 target-arc/op_helper.c
target-arc/Makefile.objs +1 -0
@@ -21,6 +21,7 @@ obj-y += translate.o obj-y += helper.o obj-y += cpu.o +obj-y += op_helper.o obj-y += translate-inst.o obj-y += gdbstub.o obj-y += decode.o
target-arc/helper.h +3 -0
@@ -19,3 +19,6 @@*/ DEF_HELPER_1(debug, void, env) +DEF_HELPER_2(norm, i32, env, i32) +DEF_HELPER_2 (normw, i32, env, i32) +
target-arc/op_helper.c new file +91 -0
91 lines not on this page · raw message
target-arc/translate-inst.c +52 -0
55 lines not on this page · raw message
target-arc/translate-inst.h +4 -0
@@ -86,3 +86,7 @@ int arc_gen_BXOR(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_RRC (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_RLC (DisasCtxt *c,TCGv dest,TCGv src1); + +int arc_gen_NORMW (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_NORM (DisasCtxt *c,TCGv dest,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 13/29] target-arc: NORM, NORMW
target-arc/op_helper.c line 75
Quoted 10 lines · Michael Rolnik
target-arc/op_helper.c new file +10
-0+target_ulong helper_norm (CPUARCState *env,uint32_t src1) +{ +if (src1 ==0x00000000 || src1 ==0xffffffff ) { +return 31 ; + }else { +if ((src1 &0x80000000 ) ==0x80000000 ) { + src1 = ~src1; + } +return clz32 (src1) -1 ; + }
This is clrsb32.
target-arc/op_helper.c line 89
Quoted 12 lines
target-arc/op_helper.c new file +12
-0+target_ulong helper_normw (CPUARCState *env,uint32_t src1) +{ + src1 &=0xffff ; + +if (src1 ==0x0000 || src1 ==0xffff ) { +return 15 ; + }else { +if ((src1 &0x8000 ) ==0x8000 ) { + src1 = ~src1 &0xffff ; + } +return clz32 (src1) -17 ; + }
clrsb32((int16_t)src1) - 16
r~
RFC PATCH 14/29 target-arc: MPY, MPYH, MPYHU, MPYU
In reply to Michael Rolnik--- target-arc/translate-inst.c | 129 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 5 ++ 2 files changed, 134 insertions(+)
target-arc/translate-inst.c +129 -0
@@ -1417,3 +1417,132 @@ int arc_gen_NORM(DisasCtxt *ctx, TCGv dest, TCGv src1)return BS_NONE ; } +/* +MPY +*/ +int arc_gen_MPY (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv_i64 rslt =tcg_temp_new_i64 (); +TCGv_i64 srcA =tcg_temp_new_i64 (); +TCGv_i64 srcB =tcg_temp_new_i64 (); + +tcg_gen_ext_i32_i64 (srcA, src1); +tcg_gen_ext_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_trunc_i64_tl (dest, rslt); + +if (ctx->opt.f) { +TCGv_i64 temp =tcg_temp_new_i64 (); + +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, dest, ctx->zero); + +tcg_gen_trunc_i64_tl (cpu_Nf, rslt); +tcg_gen_shri_tl (cpu_Nf, cpu_Nf,31 ); + +tcg_gen_ext_i32_i64 (temp, dest); +tcg_gen_setcond_i64 (TCG_COND_NE , temp, temp, rslt); +tcg_gen_trunc_i64_tl (cpu_Cf, temp); + +tcg_temp_free_i64 (temp); + } + +tcg_temp_free_i64 (rslt); +tcg_temp_free_i64 (srcA); +tcg_temp_free_i64 (srcB); + +return BS_NONE ; +} + +/* +MPYH +*/ +int arc_gen_MPYH (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv_i64 rslt =tcg_temp_new_i64 (); +TCGv_i64 srcA =tcg_temp_new_i64 (); +TCGv_i64 srcB =tcg_temp_new_i64 (); + +tcg_gen_ext_i32_i64 (srcA, src1); +tcg_gen_ext_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_sari_i64 (rslt, rslt,32 ); +tcg_gen_trunc_i64_tl (dest, rslt); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, dest, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, dest,31 ); +tcg_gen_movi_tl (cpu_Vf,0 ); + } + +tcg_temp_free_i64 (rslt); +tcg_temp_free_i64 (srcA); +tcg_temp_free_i64 (srcB); + +return BS_NONE ; +} + +/* +MPYHU +*/ +int arc_gen_MPYHU (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv_i64 rslt =tcg_temp_new_i64 (); +TCGv_i64 srcA =tcg_temp_new_i64 (); +TCGv_i64 srcB =tcg_temp_new_i64 (); + +tcg_gen_extu_i32_i64 (srcA, src1); +tcg_gen_extu_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_shri_i64 (rslt, rslt,32 ); +tcg_gen_trunc_i64_tl (dest, rslt); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, dest, ctx->zero); +tcg_gen_movi_tl (cpu_Nf,0 ); +tcg_gen_movi_tl (cpu_Vf,0 ); + } + +tcg_temp_free_i64 (rslt); +tcg_temp_free_i64 (srcA); +tcg_temp_free_i64 (srcB); + +return BS_NONE ; +} + +/* +MPYU +*/ +int arc_gen_MPYU (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv_i64 rslt =tcg_temp_new_i64 (); +TCGv_i64 srcA =tcg_temp_new_i64 (); +TCGv_i64 srcB =tcg_temp_new_i64 (); + +tcg_gen_extu_i32_i64 (srcA, src1); +tcg_gen_extu_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_trunc_i64_tl (dest, rslt); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, dest, ctx->zero); +tcg_gen_movi_tl (cpu_Nf,0 ); +tcg_gen_shri_i64 (rslt, rslt,32 ); +tcg_gen_trunc_i64_tl (cpu_Vf, rslt); +tcg_gen_setcondi_tl (TCG_COND_NE , cpu_Vf, cpu_Vf,0 ); + } + +tcg_temp_free_i64 (rslt); +tcg_temp_free_i64 (srcA); +tcg_temp_free_i64 (srcB); + +return BS_NONE ; +} +
target-arc/translate-inst.h +5 -0
@@ -90,3 +90,8 @@ int arc_gen_RLC(DisasCtxt *c, TCGv dest, TCGv src1);int arc_gen_NORMW (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_NORM (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_MPY (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MPYH (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MPYHU (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MPYU (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 14/29] target-arc: MPY, MPYH, MPYHU, MPYU
Quoted 11 lines · Michael Rolnik
target-arc/translate-inst.c +11
-0+tcg_gen_ext_i32_i64 (srcA, src1); +tcg_gen_ext_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_trunc_i64_tl (dest, rslt); + +if (ctx->opt.f) { +TCGv_i64 temp =tcg_temp_new_i64 (); + +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, dest, ctx->zero);
target-arc/translate-inst.c int arc_gen_NORM(DisasCtxt *ctx, TCGv dest, TCGv src1) · line 1449
Quoted 10 lines
target-arc/translate-inst.c +10
-0+ +tcg_gen_trunc_i64_tl (cpu_Nf, rslt); +tcg_gen_shri_tl (cpu_Nf, cpu_Nf,31 ); + +tcg_gen_ext_i32_i64 (temp, dest); +tcg_gen_setcond_i64 (TCG_COND_NE , temp, temp, rslt); +tcg_gen_trunc_i64_tl (cpu_Cf, temp); + +tcg_temp_free_i64 (temp); + }
It's probably easier to do this with tcg_gen_muls2_tl.
r~
RFC PATCH 15/29 target-arc: MUL64, MULU64, DIVAW
In reply to Michael Rolnik--- target-arc/translate-inst.c | 105 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 ++ 2 files changed, 109 insertions(+)
target-arc/translate-inst.c +105 -0
@@ -1546,3 +1546,108 @@ int arc_gen_MPYU(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +DIVAW +*/ +int arc_gen_DIVAW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGLabel *label_else =gen_new_label (); +TCGLabel *label_done =gen_new_label (); +TCGv rslt = dest; +TCGv temp = dest; + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +/* +if (src1 == 0) +dest = 0 +else +{ +src1_temp = src1 << 1 +if (src1_temp >= src2) +dest = ((src1_temp - src2) | 0x0000_0001) +else +dest = src1_temp +} +*/ + +tcg_gen_brcondi_tl (TCG_COND_NE , src1,0 , label_else); + +tcg_gen_xor_tl (rslt, rslt, rslt); +tcg_gen_br (label_done); + +gen_set_label (label_else); +tcg_gen_shli_tl (temp, src1,1 ); +tcg_gen_mov_tl (rslt, temp); +tcg_gen_brcond_tl (TCG_COND_LT , temp, src2, label_done); +tcg_gen_sub_tl (rslt, temp, src2); +tcg_gen_ori_tl (rslt, rslt,1 ); + +gen_set_label (label_done); + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +tcg_temp_free_i32 (temp); + +return BS_NONE ; +} + +/* +MUL64 +*/ +int arc_gen_MUL64 (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv_i64 rslt =tcg_temp_new_i64 (); +TCGv_i64 srcA =tcg_temp_new_i64 (); +TCGv_i64 srcB =tcg_temp_new_i64 (); + +tcg_gen_ext_i32_i64 (srcA, src1); +tcg_gen_ext_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_trunc_i64_tl (cpu_mlo, rslt); +tcg_gen_sari_i64 (rslt, rslt,16 ); +tcg_gen_trunc_i64_tl (cpu_mmi, rslt); +tcg_gen_sari_i64 (rslt, rslt,16 ); +tcg_gen_trunc_i64_tl (cpu_mhi, rslt); + +tcg_temp_free_i64 (rslt); +tcg_temp_free_i64 (srcA); +tcg_temp_free_i64 (srcB); + +return BS_NONE ; +} + +/* +MULU64 +*/ +int arc_gen_MULU64 (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv_i64 rslt =tcg_temp_new_i64 (); +TCGv_i64 srcA =tcg_temp_new_i64 (); +TCGv_i64 srcB =tcg_temp_new_i64 (); + +tcg_gen_extu_i32_i64 (srcA, src1); +tcg_gen_extu_i32_i64 (srcB, src2); + +tcg_gen_mul_i64 (rslt, srcA, srcB); + +tcg_gen_trunc_i64_tl (cpu_mlo, rslt); +tcg_gen_shri_i64 (rslt, rslt,16 ); +tcg_gen_trunc_i64_tl (cpu_mmi, rslt); +tcg_gen_shri_i64 (rslt, rslt,16 ); +tcg_gen_trunc_i64_tl (cpu_mhi, rslt); + +tcg_temp_free_i64 (rslt); +tcg_temp_free_i64 (srcA); +tcg_temp_free_i64 (srcB); + +return BS_NONE ; +} +
target-arc/translate-inst.h +4 -0
@@ -95,3 +95,7 @@ int arc_gen_MPYH(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_MPYHU (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_MPYU (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_DIVAW (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MUL64 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_MULU64 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 15/29] target-arc: MUL64, MULU64, DIVAW
Quoted 30 lines · Michael Rolnik
Signed-off-by Michael Rolnik <[email protected]>--- target-arc/translate-inst.c | 105 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 ++ 2 files changed, 109 insertions(+)target-arc/translate-inst.c +16
-0@@ -1546,3 +1546,108 @@ int arc_gen_MPYU(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +DIVAW +*/ +int arc_gen_DIVAW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGLabel *label_else =gen_new_label (); +TCGLabel *label_done =gen_new_label (); +TCGv rslt = dest; +TCGv temp = dest; + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +/* +if (src1 == 0)
target-arc/translate-inst.c int arc_gen_MPYU(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2) · line 1574
Quoted 10 lines
target-arc/translate-inst.c +10
-0+dest = 0 +else +{ +src1_temp = src1 << 1 +if (src1_temp >= src2) +dest = ((src1_temp - src2) | 0x0000_0001) +else +dest = src1_temp +} +*/
Probably better with two movcond instead of branches.
r~
RFC PATCH 16/29 target-arc: BBIT0, BBIT1, BR
In reply to Michael Rolnik--- target-arc/translate-inst.c | 136 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 35 ++++++++++++ 2 files changed, 171 insertions(+)
target-arc/translate-inst.c +136 -0
@@ -104,6 +104,42 @@ static void gen_sub_Vf(TCGv dest, TCGv src1, TCGv src2)tcg_temp_free_i32 (t1); } +static void arc_gen_exec_delayslot (DisasCtxt *ctx) +{ +if (ctx->opt.limm ==0 ) { +uint32_t cpc = ctx->cpc; +uint32_t npc = ctx->npc; +uint32_t dpc = ctx->dpc; +uint32_t pcl = ctx->pcl; +options_t opt = ctx->opt; +int bstate = ctx->bstate; + + ctx->cpc = ctx->npc; + ctx->pcl = ctx->cpc &0xfffffffc ; + + ++ctx->ds; + +/* TODO: check for illegal instruction sequence */ + +memset (&ctx->opt,0 ,sizeof (ctx->opt)); +arc_decode (ctx); + + --ctx->ds; + + ctx->cpc = cpc; + ctx->npc = npc; + ctx->dpc = dpc; + ctx->pcl = pcl; + ctx->opt = opt; + ctx->bstate = bstate; + } +} + +static void arc_gen_kill_delayslot (DisasCtxt *ctx) +{ +/* nothing to do */ +} +/* ADC */
@@ -1651,3 +1687,103 @@ int arc_gen_MULU64(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +BBIT0 +*/ +int arc_gen_BBIT0 (DisasCtxt *ctx,TCGv src1,TCGv src2,TCGv rd) +{ +TCGv mask =tcg_temp_new_i32 (); +TCGv cond =tcg_temp_new_i32 (); +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_jump =gen_new_label (); + +tcg_gen_andi_tl (mask, src2,0x31 ); +tcg_gen_shr_tl (mask, ctx->one, mask); +tcg_gen_andc_tl (cond, src1, mask);/* cond = src1 & ~(1 << src2) */ + +tcg_gen_brcond_tl (TCG_COND_EQ , cond, ctx->zero, label_jump); + +tcg_gen_movi_tl (cpu_pc, ctx->npc); +arc_gen_exec_delayslot (ctx); +tcg_gen_br (label_done); + +gen_set_label (label_jump); +tcg_gen_shli_tl (cpu_pc, rd,1 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc, ctx->pcl); +if (ctx->opt.d ==0 ) { +arc_gen_kill_delayslot (ctx); + }else { +arc_gen_exec_delayslot (ctx); + } + +gen_set_label (label_done); +tcg_temp_free_i32 (cond); +tcg_temp_free_i32 (mask); + +return BS_BRANCH_DS ; +} + +/* +BBIT1 +*/ +int arc_gen_BBIT1 (DisasCtxt *ctx,TCGv src1,TCGv src2,TCGv rd) +{ +TCGv mask =tcg_temp_new_i32 (); +TCGv cond =tcg_temp_new_i32 (); +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_jump =gen_new_label (); + +tcg_gen_andi_tl (mask, src2,0x31 ); +tcg_gen_shr_tl (mask, ctx->one, mask); +tcg_gen_and_tl (cond, src1, mask);/* cond = src1 & (1 << src2) */ + +tcg_gen_brcond_tl (TCG_COND_EQ , cond, ctx->zero, label_jump); + +tcg_gen_movi_tl (cpu_pc, ctx->dpc); +arc_gen_exec_delayslot (ctx); +tcg_gen_br (label_done); + +gen_set_label (label_jump); +tcg_gen_shli_tl (cpu_pc, rd,1 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc, ctx->pcl); +if (ctx->opt.d ==0 ) { +arc_gen_kill_delayslot (ctx); + }else { +arc_gen_exec_delayslot (ctx); + } + +gen_set_label (label_done); +tcg_temp_free_i32 (cond); +tcg_temp_free_i32 (mask); + +return BS_BRANCH_DS ; +} + +/* +BR +*/ +int arc_gen_BR (DisasCtxt *ctx,TCGv src1,TCGv src2,TCGv Rd,TCGCond cond) +{ +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_jump =gen_new_label (); + +tcg_gen_brcond_tl (cond, src1, src2, label_jump); + +tcg_gen_movi_tl (cpu_pc, ctx->dpc); +arc_gen_exec_delayslot (ctx); +tcg_gen_br (label_done); + +gen_set_label (label_jump); +tcg_gen_shli_tl (cpu_pc, Rd,1 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc, ctx->pcl); +if (ctx->opt.d ==0 ) { +arc_gen_kill_delayslot (ctx); + }else { +arc_gen_exec_delayslot (ctx); + } + +gen_set_label (label_done); + +return BS_BRANCH_DS ; +} +
target-arc/translate-inst.h +35 -0
@@ -22,6 +22,37 @@#include "qemu/bitops.h" #include "tcg/tcg.h" +typedef enum ARC_COND { +ARC_COND_AL =0x00 , +ARC_COND_RA =0x00 , +ARC_COND_EQ =0x01 , +ARC_COND_Z =0x01 , +ARC_COND_NE =0x02 , +ARC_COND_NZ =0x02 , +ARC_COND_PL =0x03 , +ARC_COND_P =0x03 , +ARC_COND_MI =0x04 , +ARC_COND_N =0x04 , +ARC_COND_CS =0x05 , +ARC_COND_C =0x05 , +ARC_COND_LO =0x05 , +ARC_COND_CC =0x06 , +ARC_COND_NC =0x06 , +ARC_COND_HS =0x06 , +ARC_COND_VS =0x07 , +ARC_COND_V =0x07 , +ARC_COND_VC =0x08 , +ARC_COND_NV =0x08 , +ARC_COND_GT =0x09 , +ARC_COND_GE =0x0a , +ARC_COND_LT =0x0b , +ARC_COND_LE =0x0c , +ARC_COND_HI =0x0d , +ARC_COND_LS =0x0e , +ARC_COND_PNZ =0x0f , +}ARC_COND ; + +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);
@@ -99,3 +130,7 @@ int arc_gen_DIVAW(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_MUL64 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_MULU64 (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_BBIT0 (DisasCtxt *c,TCGv src1,TCGv src2,TCGv rd); +int arc_gen_BBIT1 (DisasCtxt *c,TCGv src1,TCGv src2,TCGv rd); +int arc_gen_BR (DisasCtxt *c,TCGv src1,TCGv src2,TCGv Rd,TCGCond cond); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 16/29] target-arc: BBIT0, BBIT1, BR
Quoted 20 lines · Michael Rolnik
target-arc/translate-inst.c +20
-0+static void arc_gen_exec_delayslot (DisasCtxt *ctx) +{ +if (ctx->opt.limm ==0 ) { +uint32_t cpc = ctx->cpc; +uint32_t npc = ctx->npc; +uint32_t dpc = ctx->dpc; +uint32_t pcl = ctx->pcl; +options_t opt = ctx->opt; +int bstate = ctx->bstate; + + ctx->cpc = ctx->npc; + ctx->pcl = ctx->cpc &0xfffffffc ; + + ++ctx->ds; + +/* TODO: check for illegal instruction sequence */ + +memset (&ctx->opt,0 ,sizeof (ctx->opt)); +arc_decode (ctx); +
target-arc/translate-inst.c static void gen_sub_Vf(TCGv dest, TCGv src1, TCGv src2) · line 136
Quoted 10 lines
target-arc/translate-inst.c +10
-0+ --ctx->ds; + + ctx->cpc = cpc; + ctx->npc = npc; + ctx->dpc = dpc; + ctx->pcl = pcl; + ctx->opt = opt; + ctx->bstate = bstate; + } +}
It might be easier to put the delay slot into a TB by itself. That will avoid having to duplicate the decoding here.
r~
RFC PATCH 17/29 target-arc: B, BL
In reply to Michael Rolnik--- target-arc/translate-inst.c | 189 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 + 2 files changed, 193 insertions(+)
target-arc/translate-inst.c +189 -0
@@ -140,6 +140,137 @@ static void arc_gen_kill_delayslot(DisasCtxt *ctx)/* nothing to do */ } +#define ARC_COND_IF_1 (flag, label) \ + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_ ## flag ## f, 0, label) +#define ARC_COND_IF_0 (flag, label) \ + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_ ## flag ## f, 0, label) + +void arc_gen_jump_ifnot (DisasCtxt *ctx,ARC_COND cond,TCGLabel *label_skip) +{ +TCGLabel *label_cont =gen_new_label (); + +switch (cond) { +/* +Always +*/ +case ARC_COND_AL : { + }break ; + +/* +Zero +*/ +case ARC_COND_Z : { +ARC_COND_IF_0 (Z , label_skip); + }break ; + +/* +Non-Zero +*/ +case ARC_COND_NZ : { +ARC_COND_IF_1 (Z , label_skip); + }break ; + +/* +Positive +*/ +case ARC_COND_P : { +tcg_gen_brcondi_tl (TCG_COND_LT , cpu_Nf,0 , label_skip); + }break ; + +/* +Negative +*/ +case ARC_COND_N : { +tcg_gen_brcondi_tl (TCG_COND_GE , cpu_Nf,0 , label_skip); + }break ; + +/* +Carry set, lower than (unsigned) +*/ +case ARC_COND_C : { +tcg_gen_brcondi_tl (TCG_COND_EQ , cpu_Cf,0 , label_skip); + }break ; + +/* +Carry clear, higher or same (unsigned) +*/ +case ARC_COND_CC : { +tcg_gen_brcondi_tl (TCG_COND_NE , cpu_Cf,0 , label_skip); + }break ; + +/* +Over-flow set +*/ +case ARC_COND_VS : { +tcg_gen_brcondi_tl (TCG_COND_EQ , cpu_Cf,0 , label_skip); + }break ; + +/* +Over-flow clear +*/ +case ARC_COND_VC : { +tcg_gen_brcondi_tl (TCG_COND_NE , cpu_Cf,0 , label_skip); + }break ; + +/* +Greater than (signed) +*/ +case ARC_COND_GT : { +tcg_gen_brcondi_tl (TCG_COND_LE , cpu_Nf,0 , label_skip); + }break ; + +/* +Greater than or equal to (signed) +*/ +case ARC_COND_GE : { +tcg_gen_brcondi_tl (TCG_COND_LT , cpu_Nf,0 , label_skip); + }break ; + +/* +Less than (signed) +*/ +case ARC_COND_LT : { +tcg_gen_brcondi_tl (TCG_COND_GE , cpu_Nf,0 , label_skip); + }break ; + +/* +Less than or equal to (signed) +*/ +case ARC_COND_LE : { +tcg_gen_brcondi_tl (TCG_COND_GT , cpu_Nf,0 , label_skip); + }break ; + +/* +Higher than (unsigned) +!C and !Z +*/ +case ARC_COND_HI : { +ARC_COND_IF_1 (C , label_skip); +ARC_COND_IF_1 (Z , label_skip); + }break ; + +/* +Lower than +C or Z +*/ +case ARC_COND_LS : { +ARC_COND_IF_1 (C , label_cont); +ARC_COND_IF_0 (Z , label_skip); + }break ; + +/* +Positive non-zero +!N and !Z +*/ +case ARC_COND_PNZ : { +ARC_COND_IF_1 (N , label_skip); +ARC_COND_IF_1 (Z , label_skip); + }break ; + } + +gen_set_label (label_cont); +} +/* ADC */
@@ -1787,3 +1918,61 @@ gen_set_label(label_done);return BS_BRANCH_DS ; } +/* +B +*/ +int arc_gen_B (DisasCtxt *ctx,TCGv rd,ARC_COND cond) +{ +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_fall =gen_new_label (); + +arc_gen_jump_ifnot (ctx, cond, label_fall); + +tcg_gen_shli_tl (cpu_pc, rd,1 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc, ctx->pcl); +if (ctx->opt.d ==0 ) { +arc_gen_kill_delayslot (ctx); + }else { +arc_gen_exec_delayslot (ctx); + } +tcg_gen_br (label_done); + +gen_set_label (label_fall); +tcg_gen_movi_tl (cpu_pc, ctx->dpc); +arc_gen_exec_delayslot (ctx); + +gen_set_label (label_done); + +return BS_BRANCH_DS ; +} + +/* +BL +*/ +int arc_gen_BL (DisasCtxt *ctx,TCGv Rd,ARC_COND cond) +{ +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_fall =gen_new_label (); + +arc_gen_jump_ifnot (ctx, cond, label_fall); + +tcg_gen_shli_tl (cpu_pc, Rd,2 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc, ctx->pcl); +if (ctx->opt.d ==0 ) { +tcg_gen_movi_tl (cpu_blink, ctx->npc); +arc_gen_kill_delayslot (ctx); + }else { +tcg_gen_movi_tl (cpu_blink, ctx->dpc); +arc_gen_exec_delayslot (ctx); + } +tcg_gen_br (label_done); + +gen_set_label (label_fall); +tcg_gen_movi_tl (cpu_pc, ctx->dpc); +arc_gen_exec_delayslot (ctx); + +gen_set_label (label_done); + +return BS_BRANCH_DS ; +} +
target-arc/translate-inst.h +4 -0
@@ -134,3 +134,7 @@ int arc_gen_BBIT0(DisasCtxt *c, TCGv src1, TCGv src2, TCGv rd);int arc_gen_BBIT1 (DisasCtxt *c,TCGv src1,TCGv src2,TCGv rd);int arc_gen_BR (DisasCtxt *c,TCGv src1,TCGv src2,TCGv Rd,TCGCond cond); +void arc_gen_jump_ifnot (DisasCtxt *ctx,ARC_COND cond,TCGLabel *label_skip); +int arc_gen_B (DisasCtxt *c,TCGv rd,ARC_COND cond); +int arc_gen_BL (DisasCtxt *c,TCGv Rd,ARC_COND cond); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 17/29] target-arc: B, BL
target-arc/translate-inst.c static void arc_gen_kill_delayslot(DisasCtxt *ctx) · line 250
Quoted 4 lines · Michael Rolnik
target-arc/translate-inst.c +4
-0+case ARC_COND_HI : { +ARC_COND_IF_1 (C , label_skip); +ARC_COND_IF_1 (Z , label_skip); + }break ;
Why aren't you using AND / OR to combine these conditions?
r~
RFC PATCH 18/29 target-arc: J, JL
In reply to Michael Rolnik--- target-arc/translate-inst.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 3 ++ 2 files changed, 96 insertions(+)
target-arc/translate-inst.c +93 -0
@@ -1976,3 +1976,96 @@ gen_set_label(label_done);return BS_BRANCH_DS ; } +/* +J +*/ +int arc_gen_J (DisasCtxt *ctx,TCGv src1,ARC_COND cond) +{ +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_fall =gen_new_label (); + +arc_gen_jump_ifnot (ctx, cond, label_fall); + +if (ctx->opt.f) { +if (TCGV_EQUAL (src1, cpu_ilink1)) { +tcg_gen_mov_tl (cpu_Lf, cpu_l1_Lf); +tcg_gen_mov_tl (cpu_Zf, cpu_l1_Zf); +tcg_gen_mov_tl (cpu_Nf, cpu_l1_Nf); +tcg_gen_mov_tl (cpu_Cf, cpu_l1_Cf); +tcg_gen_mov_tl (cpu_Vf, cpu_l1_Vf); +tcg_gen_mov_tl (cpu_Uf, cpu_l1_Uf); + +tcg_gen_mov_tl (cpu_DEf, cpu_l1_DEf); +tcg_gen_mov_tl (cpu_AEf, cpu_l1_AEf); +tcg_gen_mov_tl (cpu_A2f, cpu_l1_A2f); +tcg_gen_mov_tl (cpu_A1f, cpu_l1_A1f); +tcg_gen_mov_tl (cpu_E2f, cpu_l1_E2f); +tcg_gen_mov_tl (cpu_E1f, cpu_l1_E1f); + +tcg_gen_mov_tl (cpu_bta, cpu_bta_l1); + } +if (TCGV_EQUAL (src1, cpu_ilink2)) { +tcg_gen_mov_tl (cpu_Lf, cpu_l2_Lf); +tcg_gen_mov_tl (cpu_Zf, cpu_l2_Zf); +tcg_gen_mov_tl (cpu_Nf, cpu_l2_Nf); +tcg_gen_mov_tl (cpu_Cf, cpu_l2_Cf); +tcg_gen_mov_tl (cpu_Vf, cpu_l2_Vf); +tcg_gen_mov_tl (cpu_Uf, cpu_l2_Uf); + +tcg_gen_mov_tl (cpu_DEf, cpu_l2_DEf); +tcg_gen_mov_tl (cpu_AEf, cpu_l2_AEf); +tcg_gen_mov_tl (cpu_A2f, cpu_l2_A2f); +tcg_gen_mov_tl (cpu_A1f, cpu_l2_A1f); +tcg_gen_mov_tl (cpu_E2f, cpu_l2_E2f); +tcg_gen_mov_tl (cpu_E1f, cpu_l2_E1f); + +tcg_gen_mov_tl (cpu_bta, cpu_bta_l2); + } + } + +tcg_gen_mov_tl (cpu_pc, src1); +if (ctx->opt.d ==0 ) { +arc_gen_kill_delayslot (ctx); + }else { +arc_gen_exec_delayslot (ctx); + } +tcg_gen_br (label_done); + +gen_set_label (label_fall); +tcg_gen_movi_tl (cpu_pc, ctx->dpc); +arc_gen_exec_delayslot (ctx); + +gen_set_label (label_done); + +return BS_BRANCH_DS ; +} + +/* +JL +*/ +int arc_gen_JL (DisasCtxt *ctx,TCGv src1,ARC_COND cond) +{ +TCGLabel *label_done =gen_new_label (); +TCGLabel *label_fall =gen_new_label (); + +arc_gen_jump_ifnot (ctx, cond, label_fall); + +tcg_gen_mov_tl (cpu_pc, src1); +if (ctx->opt.d ==0 ) { +tcg_gen_movi_tl (cpu_blink, ctx->npc); +arc_gen_kill_delayslot (ctx); + }else { +tcg_gen_movi_tl (cpu_blink, ctx->dpc); +arc_gen_exec_delayslot (ctx); + } +tcg_gen_br (label_done); + +gen_set_label (label_fall); +tcg_gen_movi_tl (cpu_pc, ctx->dpc); +arc_gen_exec_delayslot (ctx); + +gen_set_label (label_done); + +return BS_BRANCH_DS ; +} +
target-arc/translate-inst.h +3 -0
@@ -138,3 +138,6 @@ void arc_gen_jump_ifnot(DisasCtxt *ctx, ARC_COND cond, TCGLabel *label_skip);int arc_gen_B (DisasCtxt *c,TCGv rd,ARC_COND cond);int arc_gen_BL (DisasCtxt *c,TCGv Rd,ARC_COND cond); +int arc_gen_J (DisasCtxt *c,TCGv src1,ARC_COND cond); +int arc_gen_JL (DisasCtxt *c,TCGv src1,ARC_COND cond); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 19/29 target-arc: LR, SR
In reply to Michael Rolnik--- target-arc/helper.h | 2 + target-arc/op_helper.c | 322 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.c | 26 ++++ target-arc/translate-inst.h | 3 + 4 files changed, 353 insertions(+)
target-arc/helper.h +2 -0
@@ -21,4 +21,6 @@ DEF_HELPER_1(debug, void, env) DEF_HELPER_2(norm, i32, env, i32) DEF_HELPER_2(normw, i32, env, i32) +DEF_HELPER_2(lr, tl, env, i32) +DEF_HELPER_2 (sr, void, i32, i32)
target-arc/op_helper.c +322 -0
325 lines not on this page · raw message
target-arc/translate-inst.c +26 -0
@@ -2069,3 +2069,29 @@ gen_set_label(label_done);return BS_BRANCH_DS ; } +/* +LR +*/ +int arc_gen_LR (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv cpc =tcg_const_local_i32 ((ctx->cpc +3 ) &0xfffffffc ); +TCGv npc =tcg_const_local_i32 ((ctx->npc +3 ) &0xfffffffc ); + +gen_helper_lr (dest, cpu_env, src1); + +tcg_temp_free_i32 (cpc); +tcg_temp_free_i32 (npc); + +return BS_NONE ; +} + +/* +SR +*/ +int arc_gen_SR (DisasCtxt *ctx,TCGv src1,TCGv src2) +{ +gen_helper_sr (src1, src2); + +return BS_NONE ; +} +
target-arc/translate-inst.h +3 -0
@@ -141,3 +141,6 @@ int arc_gen_BL(DisasCtxt *c, TCGv Rd, ARC_COND cond);int arc_gen_J (DisasCtxt *c,TCGv src1,ARC_COND cond);int arc_gen_JL (DisasCtxt *c,TCGv src1,ARC_COND cond); +int arc_gen_LR (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_SR (DisasCtxt *c,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 19/29] target-arc: LR, SR
target-arc/translate-inst.c gen_set_label(label_done); · line 2078
Quoted 4 lines · Michael Rolnik
target-arc/translate-inst.c +4
-0+int arc_gen_LR (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv cpc =tcg_const_local_i32 ((ctx->cpc +3 ) &0xfffffffc ); +TCGv npc =tcg_const_local_i32 ((ctx->npc +3 ) &0xfffffffc );
No need for _local here.
r~
RFC PATCH 20/29 target-arc: ADDS, ADDSDW, SUBS, SUBSDW
In reply to Michael Rolnik--- target-arc/translate-inst.c | 227 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 + 2 files changed, 231 insertions(+)
target-arc/translate-inst.c +227 -0
@@ -271,6 +271,45 @@ void arc_gen_jump_ifnot(DisasCtxt *ctx, ARC_COND cond, TCGLabel *label_skip)gen_set_label (label_cont); } +static void gen_add16_Vf (TCGv v,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 (v, t1,15 );/* Vf = t1(15) */ + +tcg_temp_free_i32 (t2); +tcg_temp_free_i32 (t1); +} + + +static void gen_sub16_Vf (TCGv v,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv t1 =tcg_temp_new_i32 (); +TCGv t2 =tcg_temp_new_i32 (); + +/* +t1 = src1 & ~src2 & ~dest +| ~src1 & src2 & dest += (src1 ^ dest) & (src1 ^ dest)*/ +tcg_gen_xor_tl (t1, src1, dest); +tcg_gen_xor_tl (t2, src1, src2); +tcg_gen_and_tl (t1, t1, t2); +tcg_gen_shri_tl (v, t1,15 );/* Vf = t1(15) */ + +tcg_temp_free_i32 (t2); +tcg_temp_free_i32 (t1); +} +/* ADC */
@@ -2095,3 +2134,191 @@ int arc_gen_SR(DisasCtxt *ctx, TCGv src1, TCGv src2)return BS_NONE ; } +/* +ADDS +*/ +int arc_gen_ADDS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv t1 =tcg_temp_new_i32 (); +TCGv t2 =tcg_temp_new_i32 (); +TCGv sat =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_add_tl (rslt, src1, src2); + +/* +src1 & src2 & ~dest | ~src1 & ~src2 & dest += (src1 ^ dest) & ~(src1 ^ src2) +*/ +tcg_gen_xor_tl (t1, src1, rslt);/* 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 (sat, t1,31 );/* sat= t1(31) */ + +tcg_temp_free_i32 (t2); +tcg_temp_free_i32 (t1); + +tcg_gen_movcond_tl (TCG_COND_LTU , rslt, dest, ctx->msb32, dest, ctx->smax32); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Cf, ctx->zero); +tcg_gen_mov_tl (cpu_Vf, sat); +tcg_gen_or_tl (cpu_S1f, cpu_S2f, sat); +tcg_gen_or_tl (cpu_S1f, cpu_S2f, sat); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +ADDSDW +*/ +int arc_gen_ADDSDW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv loB =tcg_temp_new_i32 (); +TCGv hiB =tcg_temp_new_i32 (); +TCGv loC =tcg_temp_new_i32 (); +TCGv hiC =tcg_temp_new_i32 (); +TCGv loA =tcg_temp_new_i32 (); +TCGv hiA =tcg_temp_new_i32 (); +TCGv hiS =tcg_temp_new_i32 (); +TCGv loS =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (loB, src1,0xffff ); +tcg_gen_shri_tl (hiB, src1,16 ); + +tcg_gen_andi_tl (loC, src2,0xffff ); +tcg_gen_shri_tl (hiC, src2,16 ); + +tcg_gen_add_tl (loA, loB, loC); +tcg_gen_add_tl (hiA, hiB, hiC); + +tcg_gen_movcond_tl (TCG_COND_LTU , loA, loA, ctx->msb16, loA, ctx->smax16); +tcg_gen_movcond_tl (TCG_COND_LTU , hiA, hiA, ctx->msb16, hiA, ctx->smax16); + +tcg_gen_deposit_tl (rslt, loA, hiA,16 ,16 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_movi_tl (cpu_Cf,0 ); + +gen_add16_Vf (hiS, hiA, hiB, hiC); +gen_add16_Vf (loS, loA, loB, loC); + +tcg_gen_or_tl (cpu_Vf, hiS, loS); +tcg_gen_or_tl (cpu_S1f, cpu_S1f, hiS); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, loS); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (loA); +tcg_temp_free_i32 (hiA); +tcg_temp_free_i32 (loB); +tcg_temp_free_i32 (hiB); +tcg_temp_free_i32 (loC); +tcg_temp_free_i32 (hiC); +tcg_temp_free_i32 (hiS); +tcg_temp_free_i32 (loS); + +return BS_NONE ; +} + +/* +SUBS +*/ +int arc_gen_SUBS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv temp =tcg_temp_new_i32 (); + +tcg_gen_mov_tl (temp, src2); + +arc_gen_ADDS (ctx, dest, src1, temp); + +tcg_temp_free_i32 (temp); + +return BS_NONE ; +} + +/* +SUBSDW +*/ +int arc_gen_SUBSDW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +TCGv rslt = dest; +TCGv loB =tcg_temp_new_i32 (); +TCGv hiB =tcg_temp_new_i32 (); +TCGv loC =tcg_temp_new_i32 (); +TCGv hiC =tcg_temp_new_i32 (); +TCGv loA =tcg_temp_new_i32 (); +TCGv hiA =tcg_temp_new_i32 (); +TCGv hiS =tcg_temp_new_i32 (); +TCGv loS =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (loB, src1,0xffff ); +tcg_gen_shri_tl (hiB, src1,16 ); + +tcg_gen_andi_tl (loC, src2,0xffff ); +tcg_gen_shri_tl (hiC, src2,16 ); + +tcg_gen_sub_tl (loA, loB, loC); +tcg_gen_sub_tl (hiA, hiB, hiC); + +tcg_gen_movcond_tl (TCG_COND_LTU , loA, loA, ctx->msb16, loA, ctx->smax16); +tcg_gen_movcond_tl (TCG_COND_LTU , hiA, hiA, ctx->msb16, hiA, ctx->smax16); + +tcg_gen_deposit_tl (rslt, loA, hiA,16 ,16 ); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_movi_tl (cpu_Cf,0 ); + +gen_sub16_Vf (hiS, hiA, hiB, hiC); +gen_sub16_Vf (loS, loA, loB, loC); + +tcg_gen_or_tl (cpu_Vf, hiS, loS); +tcg_gen_or_tl (cpu_S1f, cpu_S1f, hiS); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, loS); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (loA); +tcg_temp_free_i32 (hiA); +tcg_temp_free_i32 (loB); +tcg_temp_free_i32 (hiB); +tcg_temp_free_i32 (loC); +tcg_temp_free_i32 (hiC); +tcg_temp_free_i32 (hiS); +tcg_temp_free_i32 (loS); + +return BS_NONE ; +} +
target-arc/translate-inst.h +4 -0
@@ -144,3 +144,7 @@ int arc_gen_JL(DisasCtxt *c, TCGv src1, ARC_COND cond);int arc_gen_LR (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_SR (DisasCtxt *c,TCGv src1,TCGv src2); +int arc_gen_ADDS (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_ADDSDW (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SUBS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SUBSDW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2);
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 21/29 target-arc: ABSS, ABSSW, NEGS, NEGSW, RND16, SAT16
In reply to Michael Rolnik--- target-arc/translate-inst.c | 238 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 8 ++ 2 files changed, 246 insertions(+)
target-arc/translate-inst.c +238 -0
@@ -2322,3 +2322,241 @@ int arc_gen_SUBSDW(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)return BS_NONE ; } +/* +ABSS +*/ +int arc_gen_ABSS (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 t0 =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_neg_i32 (t0, src1); +tcg_gen_movcond_tl (TCG_COND_LEU , rslt, src1, ctx->smax16, src1, t0); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, src1, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, src1,31 ); +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Vf, src1, ctx->msb32); +tcg_gen_or_tl (cpu_S1f, cpu_S1f, cpu_Vf); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, cpu_Vf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (t0); + +return BS_NONE ; +} + +/* +ABSSW +*/ +int arc_gen_ABSSW (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 lo =tcg_temp_new_i32 (); +TCGv_i32 neg =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_andi_tl (lo, src1,0x0000ffff ); +tcg_gen_neg_tl (neg, lo); + +tcg_gen_movcond_tl (TCG_COND_LEU , rslt, lo, ctx->smax16, lo, neg); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, src1, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, src1,31 ); +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Vf, lo, ctx->msb16); +tcg_gen_or_tl (cpu_S1f, cpu_S1f, cpu_Vf); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, cpu_Vf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } +tcg_temp_free_i32 (lo); +tcg_temp_free_i32 (neg); + +return BS_NONE ; +} + +/* +NEGS +*/ +int arc_gen_NEGS (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 sat =tcg_temp_new_i32 (); +TCGLabel *label_else =gen_new_label (); +TCGLabel *label_done =gen_new_label (); + +tcg_gen_brcondi_tl (TCG_COND_NE , src1,0x80000000 , label_else); + +tcg_gen_movi_tl (sat,1 ); +tcg_gen_movi_tl (rslt,0x7fffffff ); +tcg_gen_br (label_done); + +gen_set_label (label_else); +tcg_gen_movi_tl (sat,0 ); +tcg_gen_neg_tl (rslt, src1); + +gen_set_label (label_done); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Vf, sat); +tcg_gen_or_tl (cpu_S1f, cpu_S1f, cpu_Vf); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, cpu_Vf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +tcg_temp_free (sat); + +return BS_NONE ; +} + +/* +NEGSW +*/ +int arc_gen_NEGSW (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 src16 =tcg_temp_new_i32 (); +TCGv_i32 sat =tcg_temp_new_i32 (); +TCGLabel *label_else =gen_new_label (); +TCGLabel *label_done =gen_new_label (); + +tcg_gen_andi_tl (src16, src1,0x0000ffff ); + +tcg_gen_brcondi_tl (TCG_COND_NE , src1,0x8000 , label_else); + +tcg_gen_movi_tl (sat,1 ); +tcg_gen_movi_tl (rslt,0x7fff ); +tcg_gen_br (label_done); + +gen_set_label (label_else); +tcg_gen_movi_tl (sat,0 ); +tcg_gen_neg_tl (rslt, src1); + +gen_set_label (label_done); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Vf, sat); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, cpu_Vf); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +tcg_temp_free (src16); +tcg_temp_free (sat); + +return BS_NONE ; +} + +/* +RND16 +*/ +int arc_gen_RND16 (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 hi =tcg_const_local_i32 (0x00007fff );/* max sint16 */ +TCGv_i32 lo =tcg_const_local_i32 (0xffff8000 );/* min sint16 */ +TCGv_i32 sat =tcg_temp_new_i32 (); +TCGv_i32 temp =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_addi_tl (temp, src1,0x00008000 ); +tcg_gen_shri_tl (temp, temp,16 ); + +tcg_gen_movcond_tl (TCG_COND_LT , rslt, src1, lo, hi, temp); +tcg_gen_movcond_tl (TCG_COND_GT , rslt, src1, hi, hi, temp); +tcg_gen_setcond_tl (TCG_COND_NE , sat, rslt, temp); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Vf, sat); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, sat); + } + +tcg_temp_free_i32 (temp); +tcg_temp_free_i32 (sat); +tcg_temp_free_i32 (lo); +tcg_temp_free_i32 (hi); + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} + +/* +SAT16 +*/ +int arc_gen_SAT16 (DisasCtxt *ctx,TCGv dest,TCGv src1) +{ +TCGv rslt = dest; +TCGv_i32 hi =tcg_const_local_i32 (0x00007fff );/* max sint16 */ +TCGv_i32 lo =tcg_const_local_i32 (0xffff8000 );/* min sint16 */ +TCGv_i32 sat =tcg_temp_new_i32 (); + +if (TCGV_EQUAL (dest, src1)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_movcond_tl (TCG_COND_LT , rslt, src1, lo, lo, src1); +tcg_gen_movcond_tl (TCG_COND_GT , rslt, src1, hi, hi, src1); +tcg_gen_setcond_tl (TCG_COND_NE , sat, rslt, src1); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_shri_tl (cpu_Nf, rslt,31 ); +tcg_gen_mov_tl (cpu_Vf, sat); +tcg_gen_or_tl (cpu_S2f, cpu_S2f, sat); + } + +tcg_temp_free_i32 (sat); +tcg_temp_free_i32 (lo); +tcg_temp_free_i32 (hi); + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +return BS_NONE ; +} +
target-arc/translate-inst.h +8 -0
@@ -148,3 +148,11 @@ int arc_gen_ADDS(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);int arc_gen_ADDSDW (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_SUBS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2);int arc_gen_SUBSDW (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); + +int arc_gen_ABSS (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_ABSSW (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_SAT16 (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_RND16 (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_NEGS (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_NEGSW (DisasCtxt *c,TCGv dest,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 22/29 target-arc: ASLS, ASRS
In reply to Michael Rolnik--- target-arc/translate-inst.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 3 +++ 2 files changed, 60 insertions(+)
target-arc/translate-inst.c +57 -0
@@ -2560,3 +2560,60 @@ int arc_gen_SAT16(DisasCtxt *ctx, TCGv dest, TCGv src1)return BS_NONE ; } +/* +ASLS +*/ +int arc_gen_ASLS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +/* TODO */ + +return BS_NONE ; +} + + +/* +ASRS +*/ +int arc_gen_ASRS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2) +{ +/* TODO: check */ +TCGv rslt = dest; +TCGv shft =tcg_temp_new_i32 (); +TCGLabel *label_pos =gen_new_label (); +TCGLabel *label_done =gen_new_label (); + +if (TCGV_EQUAL (dest, src1) ||TCGV_EQUAL (dest, src2)) { + rslt =tcg_temp_new_i32 (); + } + +tcg_gen_brcond_tl (TCG_COND_LEU , src2, ctx->smax32, label_pos); + +/* negative */ +tcg_gen_movcond_tl (TCG_COND_GT , shft, src2, ctx->smin5, src2, ctx->smin5); +tcg_gen_neg_tl (shft, shft); +tcg_gen_shl_tl (rslt, src1, shft); + +tcg_gen_br (label_done); + +gen_set_label (label_pos); +/* positive */ +tcg_gen_movcond_tl (TCG_COND_LT , shft, src2, ctx->smax5, src2, ctx->smax5); +tcg_gen_sar_tl (rslt, src1, shft); + +gen_set_label (label_done); + +if (ctx->opt.f) { +tcg_gen_setcond_tl (TCG_COND_EQ , cpu_Zf, rslt, ctx->zero); +tcg_gen_sari_tl (cpu_Nf, rslt,31 ); + } + +if (!TCGV_EQUAL (dest, rslt)) { +tcg_gen_mov_tl (dest, rslt); +tcg_temp_free_i32 (rslt); + } + +tcg_temp_free_i32 (shft); + +return BS_NONE ; +} +
target-arc/translate-inst.h +3 -0
@@ -156,3 +156,6 @@ int arc_gen_RND16(DisasCtxt *c, TCGv dest, TCGv src1);int arc_gen_NEGS (DisasCtxt *c,TCGv dest,TCGv src1);int arc_gen_NEGSW (DisasCtxt *c,TCGv dest,TCGv src1); +int arc_gen_ASLS (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_ASRS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 22/29] target-arc: ASLS, ASRS
Quoted 1 line · Michael Rolnik
+int
arc_gen_ASLS(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)
Just do these as helpers.
r~
RFC PATCH 23/29 target-arc: FLAG, BRK, SLEEP
In reply to Michael Rolnik--- target-arc/helper.h | 1 + target-arc/op_helper.c | 6 +++++ target-arc/translate-inst.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 +++ 4 files changed, 72 insertions(+)
target-arc/helper.h +1 -0
@@ -23,4 +23,5 @@ DEF_HELPER_2(norm, i32, env, i32) DEF_HELPER_2(normw, i32, env, i32) DEF_HELPER_2(lr, tl, env, i32) DEF_HELPER_2(sr, void, i32, i32) +DEF_HELPER_1 (halt, void, env)
target-arc/op_helper.c +6 -0
@@ -411,3 +411,9 @@ target_ulong helper_lr(CPUARCState *env, uint32_t aux)return result; } +void helper_halt (CPUARCState *env) +{ +/* TODO: implement */ +} + +
target-arc/translate-inst.c +61 -0
64 lines not on this page · raw message
target-arc/translate-inst.h +4 -0
@@ -159,3 +159,7 @@ int arc_gen_NEGSW(DisasCtxt *c, TCGv dest, TCGv src1);int arc_gen_ASLS (DisasCtxt *c,TCGv dest,TCGv src1,TCGv src2);int arc_gen_ASRS (DisasCtxt *ctx,TCGv dest,TCGv src1,TCGv src2); +int arc_gen_SLEEP (DisasCtxt *c,TCGv src1); +int arc_gen_BRK (DisasCtxt *c); +int arc_gen_FLAG (DisasCtxt *c,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 24/29 target-arc: NOP, UNIMP
In reply to Michael Rolnik--- target-arc/translate-inst.c | 20 ++++++++++++++++++++ target-arc/translate-inst.h | 2 ++ 2 files changed, 22 insertions(+)
target-arc/translate-inst.c +20 -0
@@ -2678,3 +2678,23 @@ int arc_gen_SLEEP(DisasCtxt *ctx, TCGv src1)return BS_BREAK ; } +/* +NOP +*/ +int arc_gen_NOP (DisasCtxt *ctx) +{ +/* literally no operation */ +return BS_NONE ; +} + +/* +UNIMP +*/ +int arc_gen_UNIMP (DisasCtxt *ctx) +{ +/* PC = INT_VECTOR_BACE + 0x10 */ +tcg_gen_andi_tl (cpu_pc, cpu_intvec,0xffffffc0 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc,0x10 ); + +return BS_EXCP ; +}
target-arc/translate-inst.h +2 -0
@@ -163,3 +163,5 @@ int arc_gen_SLEEP(DisasCtxt *c, TCGv src1);int arc_gen_BRK (DisasCtxt *c);int arc_gen_FLAG (DisasCtxt *c,TCGv src1); +int arc_gen_NOP (DisasCtxt *c); +int arc_gen_UNIMP (DisasCtxt *c);
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 24/29] target-arc: NOP, UNIMP
target-arc/translate-inst.c int arc_gen_SLEEP(DisasCtxt *ctx, TCGv src1) · line 2700
Quoted 8 lines · Michael Rolnik
target-arc/translate-inst.c +8
-0+int arc_gen_UNIMP (DisasCtxt *ctx) +{ +/* PC = INT_VECTOR_BACE + 0x10 */ +tcg_gen_andi_tl (cpu_pc, cpu_intvec,0xffffffc0 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc,0x10 ); + +return BS_EXCP ; +}
This should be done via an exception, with the pc change done in do_interrupt.
r~
RFC PATCH 25/29 target-arc: TRAP, SWI
In reply to Michael Rolnik--- target-arc/translate-inst.c | 105 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 4 ++ 2 files changed, 109 insertions(+)
target-arc/translate-inst.c +105 -0
@@ -2698,3 +2698,108 @@ int arc_gen_UNIMP(DisasCtxt *ctx)return BS_EXCP ; } + +/* +TRAP +*/ +int arc_gen_TRAP (DisasCtxt *ctx,TCGv src1) +{ +if (arc_feature (ctx->env,ARC_FEATURE_ARC700 )) { +tcg_gen_mov_tl (cpu_er_Lf, cpu_Lf); +tcg_gen_mov_tl (cpu_er_Zf, cpu_Zf); +tcg_gen_mov_tl (cpu_er_Nf, cpu_Nf); +tcg_gen_mov_tl (cpu_er_Cf, cpu_Cf); +tcg_gen_mov_tl (cpu_er_Vf, cpu_Vf); +tcg_gen_mov_tl (cpu_er_Uf, cpu_Uf); + +tcg_gen_mov_tl (cpu_er_DEf, cpu_DEf); +tcg_gen_mov_tl (cpu_er_AEf, cpu_AEf); +tcg_gen_mov_tl (cpu_er_A2f, cpu_A2f); +tcg_gen_mov_tl (cpu_er_A1f, cpu_A1f); +tcg_gen_mov_tl (cpu_er_E2f, cpu_E2f); +tcg_gen_mov_tl (cpu_er_E1f, cpu_E1f); +tcg_gen_mov_tl (cpu_er_Hf, cpu_Hf); + +tcg_gen_movi_tl (cpu_E1f,0 ); +tcg_gen_movi_tl (cpu_E2f,0 ); +tcg_gen_movi_tl (cpu_AEf,1 ); +tcg_gen_movi_tl (cpu_Uf,0 ); + +tcg_gen_movi_tl (cpu_eret, ctx->npc); +tcg_gen_movi_tl (cpu_efa, ctx->cpc); +tcg_gen_andi_tl (cpu_ecr, src1,0x000000ff ); +tcg_gen_ori_tl (cpu_ecr, cpu_ecr,0x00250000 ); +tcg_gen_movcond_tl (TCG_COND_NE , cpu_erbta, cpu_DEf, ctx->zero, + cpu_bta, cpu_erbta); + +tcg_gen_andi_tl (cpu_pc, cpu_intvec,0xffffffc0 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc,0x128 ); + }else { +arc_gen_UNIMP (ctx); + } + +return BS_EXCP ; +} + +/* +SWI +*/ +int arc_gen_SWI (DisasCtxt *ctx) +{ +if (arc_feature (ctx->env,ARC_FEATURE_ARC700 )) { +tcg_gen_mov_tl (cpu_er_Lf, cpu_Lf); +tcg_gen_mov_tl (cpu_er_Zf, cpu_Zf); +tcg_gen_mov_tl (cpu_er_Nf, cpu_Nf); +tcg_gen_mov_tl (cpu_er_Cf, cpu_Cf); +tcg_gen_mov_tl (cpu_er_Vf, cpu_Vf); +tcg_gen_mov_tl (cpu_er_Uf, cpu_Uf); + +tcg_gen_mov_tl (cpu_er_DEf, cpu_DEf); +tcg_gen_mov_tl (cpu_er_AEf, cpu_AEf); +tcg_gen_mov_tl (cpu_er_A2f, cpu_A2f); +tcg_gen_mov_tl (cpu_er_A1f, cpu_A1f); +tcg_gen_mov_tl (cpu_er_E2f, cpu_E2f); +tcg_gen_mov_tl (cpu_er_E1f, cpu_E1f); +tcg_gen_mov_tl (cpu_er_Hf, cpu_Hf); + +tcg_gen_movi_tl (cpu_E1f,0 ); +tcg_gen_movi_tl (cpu_E2f,0 ); +tcg_gen_movi_tl (cpu_AEf,1 ); +tcg_gen_movi_tl (cpu_Uf,0 ); + +tcg_gen_movi_tl (cpu_eret, ctx->npc); +tcg_gen_movi_tl (cpu_efa, ctx->cpc); +tcg_gen_movi_tl (cpu_ecr,0x00250000 ); +tcg_gen_movcond_tl (TCG_COND_NE , cpu_erbta, cpu_DEf, ctx->zero, + cpu_bta, cpu_erbta); + +tcg_gen_andi_tl (cpu_pc, cpu_intvec,0xffffffc0 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc,0x128 ); + }else { +tcg_gen_movi_tl (cpu_ilink2, ctx->npc); + +tcg_gen_mov_tl (cpu_l2_Lf, cpu_Lf); +tcg_gen_mov_tl (cpu_l2_Zf, cpu_Zf); +tcg_gen_mov_tl (cpu_l2_Nf, cpu_Nf); +tcg_gen_mov_tl (cpu_l2_Cf, cpu_Cf); +tcg_gen_mov_tl (cpu_l2_Vf, cpu_Vf); +tcg_gen_mov_tl (cpu_l2_Uf, cpu_Uf); + +tcg_gen_mov_tl (cpu_l2_DEf, cpu_DEf); +tcg_gen_mov_tl (cpu_l2_AEf, cpu_AEf); +tcg_gen_mov_tl (cpu_l2_A2f, cpu_A2f); +tcg_gen_mov_tl (cpu_l2_A1f, cpu_A1f); +tcg_gen_mov_tl (cpu_l2_E2f, cpu_E2f); +tcg_gen_mov_tl (cpu_l2_E1f, cpu_E1f); +tcg_gen_mov_tl (cpu_l2_Hf, cpu_Hf); + +tcg_gen_movi_tl (cpu_E1f,0 ); +tcg_gen_movi_tl (cpu_E2f,0 ); + +tcg_gen_andi_tl (cpu_pc, cpu_intvec,0xffffffc0 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc,0x10 ); + } + +return BS_EXCP ; +} +
target-arc/translate-inst.h +4 -0
@@ -165,3 +165,7 @@ int arc_gen_FLAG(DisasCtxt *c, TCGv src1);int arc_gen_NOP (DisasCtxt *c);int arc_gen_UNIMP (DisasCtxt *c); + +int arc_gen_SWI (DisasCtxt *c); +int arc_gen_TRAP (DisasCtxt *c,TCGv src1); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 26/29 target-arc: RTIE
In reply to Michael Rolnik--- target-arc/helper.h | 1 + target-arc/op_helper.c | 21 +++++++++++++++++++++ target-arc/translate-inst.c | 10 ++++++++++ target-arc/translate-inst.h | 2 ++ 4 files changed, 34 insertions(+)
target-arc/helper.h +1 -0
@@ -24,4 +24,5 @@ DEF_HELPER_2(normw, i32, env, i32) DEF_HELPER_2(lr, tl, env, i32) DEF_HELPER_2(sr, void, i32, i32) DEF_HELPER_1(halt, void, env) +DEF_HELPER_1 (rtie, void, env)
target-arc/op_helper.c +21 -0
@@ -416,4 +416,25 @@ void helper_halt(CPUARCState *env)/* TODO: implement */ } +void helper_rtie (CPUARCState *env) +{ +if (env->stat.AEf) { +CPU_PCL (env) = env->eret; + env->stat = env->stat_er; + env->bta = env->erbta; + }else if (env->stat.A2f) { +CPU_PCL (env) =CPU_ILINK2 (env); + env->stat = env->stat_l2; + env->bta = env->bta_l2; + }else if (env->stat.A1f) { +CPU_PCL (env) =CPU_ILINK1 (env); + env->stat = env->stat_l1; + env->bta = env->bta_l1; + }else { +CPU_PCL (env) = env->eret; + env->stat = env->stat_er; + env->bta = env->stat.AEf; + } +} +
target-arc/translate-inst.c +10 -0
@@ -2803,3 +2803,13 @@ int arc_gen_SWI(DisasCtxt *ctx)return BS_EXCP ; } +/* +RTIE +*/ +int arc_gen_RTIE (DisasCtxt *ctx) +{ +gen_helper_rtie (cpu_env); + +return BS_BRANCH ; +} +
target-arc/translate-inst.h +2 -0
@@ -169,3 +169,5 @@ int arc_gen_UNIMP(DisasCtxt *c);int arc_gen_SWI (DisasCtxt *c);int arc_gen_TRAP (DisasCtxt *c,TCGv src1); +int arc_gen_RTIE (DisasCtxt *c); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 27/29 target-arc: LP
In reply to Michael Rolnik--- target-arc/helper.h | 1 + target-arc/op_helper.c | 5 ++++- target-arc/translate-inst.c | 40 ++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.h | 2 ++ 4 files changed, 47 insertions(+), 1 deletion(-)
target-arc/helper.h +1 -0
@@ -25,4 +25,5 @@ DEF_HELPER_2(lr, tl, env, i32) DEF_HELPER_2(sr, void, i32, i32) DEF_HELPER_1(halt, void, env) DEF_HELPER_1(rtie, void, env) +DEF_HELPER_1 (flush, void, env)
target-arc/op_helper.c +4 -1
@@ -437,4 +437,7 @@ void helper_rtie(CPUARCState *env) } } - +void helper_flush (CPUARCState *env) +{ +tb_flush ((CPUState *)arc_env_get_cpu (env)); +}
target-arc/translate-inst.c +40 -0
@@ -2813,3 +2813,43 @@ int arc_gen_RTIE(DisasCtxt *ctx)return BS_BRANCH ; } +/* +LPcc +*/ +int arc_gen_LPcc (DisasCtxt *ctx,TCGv rd,unsigned Q ) +{ +TCGLabel *label_done =gen_new_label (); +TCGv t0 =tcg_const_local_i32 (ctx->npc); + +/* +if cc is false, pc will be updated here +pc = pcl + rd +*/ +tcg_gen_shli_tl (cpu_pc, rd,1 ); +tcg_gen_addi_tl (cpu_pc, cpu_pc, ctx->pcl); + +/* +if cc is false we will jump to done label +*/ +arc_gen_jump_ifnot (ctx,Q , label_done); + +/* +cc is true +*/ +tcg_gen_movi_tl (t0, ctx->lpe); + +tcg_gen_movi_tl (cpu_lps, ctx->npc); +tcg_gen_mov_tl (cpu_lpe, cpu_pc); +tcg_gen_movi_tl (cpu_pc, ctx->npc); + +tcg_gen_brcond_tl (TCG_COND_EQ , t0, cpu_lpe, label_done); + +gen_helper_flush (cpu_env); + +gen_set_label (label_done); + +tcg_temp_free_i32 (t0); + +return BS_BRANCH ; +} +
target-arc/translate-inst.h +2 -0
@@ -171,3 +171,5 @@ int arc_gen_TRAP(DisasCtxt *c, TCGv src1);int arc_gen_RTIE (DisasCtxt *c); +int arc_gen_LPcc (DisasCtxt *ctx,TCGv Rd,unsigned Q ); +
Signature · 1 line
2.4.9 (Apple Git-60)
RFC PATCH 28/29 target-arc: decode
In reply to Michael Rolnik--- target-arc/decode.c | 2209 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 2207 insertions(+), 2 deletions(-)
target-arc/decode.c +2207 -2
@@ -1,7 +1,2212 @@#include "translate.h" +#include "translate-inst.h" -int arc_decode (DisasCtxt *ctx) +typedef int (*decode_f )(DisasCtxt *ctx,uint32_t opcode); + +static void arc_decode_src (DisasCtxt *ctx,TCGv src) +{ +if (TCGV_EQUAL (src, cpu_limm)/* register refers to limm */ + && ctx->opt.limm ==0 ) {/* limm is not yet decoded */ +uint32_t limm; + + limm =cpu_ldl_code (ctx->env, ctx->npc); + limm = (limm &0xffff0000 ) >>16 + | (limm &0x0000ffff ) <<16 ; + +tcg_gen_movi_tl (cpu_limm, limm); + + ctx->npc +=sizeof (limm); + ctx->opt.limm =1 ; + ctx->opt.d =0 ; + } + +if (TCGV_EQUAL (src, cpu_pcl)) { +tcg_gen_movi_tl (cpu_pcl, ctx->pcl); + } +} + +static int arc_decode_invalid (DisasCtxt *ctx,uint32_t opcode) +{ +return BS_EXCP ; +} + + +/* +Branch Conditionally ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------|-------------------|-|-------------------|-|----------+ +| major |S[10:1] |0|S[20:11] |N|Q[4:0] | ++---------|-------------------|-|-------------------|-|----------+ +|0 0 0 0 0|s s s s s s s s s s|0|S S S S S S S S S S|N|Q Q Q Q Q | ++---------+-------------------+-+-------------------+-+----------+ + +Branch Unconditional Far ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------|-------------------|-|-------------------|-|-|--------+ +| major |S[10:1] |1|S[20:11] |N|R|S[24:21]| ++---------|-------------------|-|-------------------|-|-|--------+ +|0 0 0 0 0|s s s s s s s s s s|1|S S S S S S S S S S|N|0|T T T T | ++---------+-------------------+-+-------------------+-+-+--------+ +*/ +static int arc_decode_major00 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret; +TCGv s; + +if (extract32 (opcode,16 ,1 ) ==0 ) { +unsigned _Q =extract32 (opcode,0 ,5 ); +unsigned _N =extract32 (opcode,5 ,1 ); +unsigned _S =extract32 (opcode,6 ,10 ); +unsigned _s =extract32 (opcode,17 ,10 ); + + s =tcg_const_local_i32 (sextract32 ((_S <<10 ) | _s,0 ,20 )); + ctx->opt.d = _N; + + ret =arc_gen_B (ctx, s, _Q); + + }else { +unsigned _T =extract32 (opcode,0 ,4 ); +unsigned _N =extract32 (opcode,5 ,1 ); +unsigned _S =extract32 (opcode,6 ,10 ); +unsigned _s =extract32 (opcode,17 ,10 ); + + s =tcg_const_local_i32 (sextract32 ((((_T <<10 ) | _S) <<10 ) | _s,0 , +24 )); + ctx->opt.d = _N; + + ret =arc_gen_B (ctx, s,ARC_COND_AL ); + } + +tcg_temp_free_i32 (s); + +return ret; +} + +/* + +Branch and Link Conditionally ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------|-----------------|-|-|-------------------|-|----------+ +| major |S[10:2] |0|0|S[20:11] |N|Q[4:0] | ++---------|-----------------|-|-|-------------------|-|----------+ +|0 0 0 0 1|s s s s s s s s s|0|0|S S S S S S S S S S|N|Q Q Q Q Q | ++---------+-----------------+-+-+-------------------+-+----------+ + +Branch and Link Unconditional Far ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------|-----------------|-|-|-------------------|-|----------+ +| major |S[10:2] |0|0|S[20:11] |N|Q[4:0] | ++---------|-----------------|-|-|-------------------|-|----------+ +|0 0 0 0 1|s s s s s s s s s|0|0|S S S S S S S S S S|N|Q Q Q Q Q | ++---------+-----------------+-+-+-------------------+-+----------+ + +Branch on Compare Register-Register ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------|-----|-------------|-|-|-----|-----------|-|-|--------+ +| major |b |S[7:1] |1|S|B |C[5:0] |N|0| minor | ++---------|-----|-------------|-|-|-----|-----------|-|-|--------+ +|0 0 0 0 1|b b b|s s s s s s s|1|S|B B B|C C C C C C|N|0|i i i i | ++---------+-----+-------------+-+-+-----+-----------+-+-+--------+ + +Branch on Compare/Bit Test Register-Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------|-----|-------------|-|-|-----|-----------|-|-|--------+ +| major |b |S[7:1] |1|S|B |U[5:0] |N|1| minor | ++---------|-----|-------------|-|-|-----|-----------|-|-|--------+ +|0 0 0 0 1|b b b|s s s s s s s|1|S|B B B|U U U U U U|N|1|i i i i | ++---------+-----+-------------+-+-+-----+-----------+-+-+--------+ +*/ +static int arc_decode_major01_body (DisasCtxt *ctx, +unsigned minor,TCGv a,TCGv b,TCGv c) +{ +int ret; + +switch (minor) { +case 0x00 : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BR (ctx, a, b, c,TCG_COND_EQ ); +break ; + } +case 0x01 : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BR (ctx, a, b, c,TCG_COND_NE ); +break ; + } +case 0x02 : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BR (ctx, a, b, c,TCG_COND_LT ); +break ; + } +case 0x03 : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BR (ctx, a, b, c,TCG_COND_GE ); +break ; + } +case 0x04 : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BR (ctx, a, b, c,TCG_COND_LTU ); +break ; + } +case 0x05 : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BR (ctx, a, b, c,TCG_COND_GEU ); +break ; + } + + case 0x06 ... 0x0d: { + ret =arc_gen_INVALID (ctx); +break ; + } + +case 0x0E : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BBIT0 (ctx, a, b, c); +break ; + } +case 0x0F : { +arc_decode_src (ctx, a); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BBIT1 (ctx, a, b, c); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} + +static int arc_decode_major01 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret; + +if (extract32 (opcode,16 ,1 ) ==0 ) { + +if (extract32 (opcode,17 ,1 ) ==0 ) { +/* Branch and Link Conditionally */ +unsigned _Q =extract32 (opcode,0 ,5 ); +unsigned _N =extract32 (opcode,5 ,1 ); +unsigned _S =extract32 (opcode,6 ,10 ); +unsigned _s =extract32 (opcode,18 ,9 ); +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<9 ) | _s,0 ,19 )); + + ctx->opt.d = _N; + + ret =arc_gen_BL (ctx, s, _Q); + +tcg_temp_free_i32 (s); + }else { +/* Branch and Link Unconditional Far */ +unsigned _T =extract32 (opcode,0 ,4 ); +unsigned _N =extract32 (opcode,5 ,1 ); +unsigned _S =extract32 (opcode,6 ,10 ); +unsigned _s =extract32 (opcode,18 ,9 ); +TCGv s =tcg_const_local_i32 (sextract32 ((((_T <<10 ) | _S) <<9 ) | + _s,0 ,23 )); + + ctx->opt.d = _N; + + ret =arc_gen_BL (ctx, s,ARC_COND_AL ); + +tcg_temp_free_i32 (s); + } + }else { +unsigned minor; + + minor =extract32 (opcode,0 ,4 ); + +if (extract32 (opcode,4 ,1 ) ==0 ) { +/* Branch on Compare Register-Register */ +unsigned _N =extract32 (opcode,5 ,1 ); +unsigned _C =extract32 (opcode,6 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _S =extract32 (opcode,15 ,1 ); +unsigned _s =extract32 (opcode,17 ,7 ); +unsigned _b =extract32 (opcode,24 ,3 ); + +TCGv b = cpu_r[(_B <<3 ) | _b]; +TCGv c = cpu_r[_C]; +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<7 ) | _s,0 ,8 )); + + ctx->opt.d = _N; + + ret =arc_decode_major01_body (ctx, minor, b, c, s); + +tcg_temp_free_i32 (s); + }else { +/* Branch on Compare/Bit Test Register-Immediate */ +unsigned _N =extract32 (opcode,5 ,1 ); +unsigned _u =extract32 (opcode,6 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _S =extract32 (opcode,15 ,1 ); +unsigned _s =extract32 (opcode,17 ,7 ); +unsigned _b =extract32 (opcode,24 ,3 ); + +TCGv b = cpu_r[(_B <<3 ) | _b]; +TCGv u =tcg_const_local_i32 (_u); +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<7 ) | _s,0 ,8 )); + ctx->opt.d = _N; + + ret =arc_decode_major01_body (ctx, minor, b, u, s); + +tcg_temp_free_i32 (s); +tcg_temp_free_i32 (u); + } + } + +return ret; +} + + +/* +Load Register with Offset ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---------------+-+-----+-+---+---+-+------------+ +| major | b |S[7:0] |S|B |D|aa |zz |x| A[5:0] | ++---------+-----+---------------+-+-----+-+---+---+-+------------+ +|0 0 0 1 0|b b b|s s s s s s s s|S|B B B|D|a a|Z Z|X|A A A A A A | ++---------+-----+---------------+-+-----+-+---+---+-+------------+ +*/ +static int arc_decode_major02 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; + +unsigned _A =extract32 (opcode,0 ,6 ); +unsigned _X =extract32 (opcode,6 ,1 ); +unsigned _ZZ =extract32 (opcode,7 ,2 ); +unsigned _AA =extract32 (opcode,9 ,2 ); +unsigned _DI =extract32 (opcode,11 ,1 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _S =extract32 (opcode,15 ,1 ); +unsigned _s =extract32 (opcode,16 ,8 ); +unsigned _b =extract32 (opcode,24 ,3 ); + +TCGv a = cpu_r[_A]; +TCGv b = cpu_r[(_B <<3 ) | _b]; +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<8 ) | _s,0 ,9 )); + ctx->opt.zz = _ZZ; + ctx->opt.x = _X; + ctx->opt.aa = _AA; + ctx->opt.di = _DI; + +arc_decode_src (ctx, b); + ret =arc_gen_LD (ctx, a, b, s); + +tcg_temp_free_i32 (s); + +return ret; +} + +/* +Store Register with Offset ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---------------+-+-----+-----------+-+---+---+--+ +| major | b | S[7:0] |S| B | C[5:0] |D|aa |zz |R | ++---------+-----+---------------+-+-----+-----------+-+---+---+--+ +|0 0 0 1 1|b b b|s s s s s s s s|S|B B B|C C C C C C|D|a a|Z Z|0 | ++---------+-----+---------------+-+-----+-----------+-+---+---+--+ +*/ +static int arc_decode_major03 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _ZZ =extract32 (opcode,1 ,2 ); +unsigned _AA =extract32 (opcode,3 ,2 ); +unsigned _DI =extract32 (opcode,5 ,1 ); +unsigned _C =extract32 (opcode,6 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _S =extract32 (opcode,15 ,1 ); +unsigned _s =extract32 (opcode,16 ,8 ); +unsigned _b =extract32 (opcode,24 ,3 ); + +TCGv b = cpu_r[(_B <<3 ) | _b]; +TCGv c = cpu_r[_C]; +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<8 ) | _s,0 ,9 )); + ctx->opt.zz = _ZZ; + ctx->opt.aa = _AA; + ctx->opt.di = _DI; + +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ST (ctx, c, b, s); + +tcg_temp_free_i32 (s); +return ret; +} + +/* +General Operations Register-Register ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major | b |P | minor |F| B | C[5:0] | A[5:0] | ++---------+-----+---+-----------+-+-----+-----------+------------+ +|0 0 1 0 0|b b b|0 0|i i i i i i|F|B B B|C C C C C C|A A A A A A | ++---------+-----+---+-----------+-+-----+-----------+------------+ + +General Operations Register with Unsigned 6-bit Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major | b |P | minor |F| B | U[5:0] | A[5:0] | ++---------+-----+---+-----------+-+-----+-----------+------------+ +|0 0 1 0 0|b b b|0 1|i i i i i i|F|B B B|U U U U U U|A A A A A A | ++---------+-----+---+-----------+-+-----+-----------+------------+ + +General Operations Register with Signed 12-bit Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major | b |P | minor |F| B | S[5:0] | S[11:6] | ++---------+-----+---+-----------+-+-----+-----------+------------+ +|0 0 1 0 0|b b b|0 1|i i i i i i|F|B B B|s s s s s s|S S S S S S | ++---------+-----+---+-----------+-+-----+-----------+------------+ + +General Operations Conditional Register ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ +| major | b |P | minor |F| B | C[5:0] |M|Q[4:0] | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ +|0 0 1 0 0|b b b|1 1|i i i i i i|F|B B B|C C C C C C|0|Q Q Q Q Q | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ + +General Operations Conditional Register with Unsigned 6-bit Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ +| major | b |P | minor |F| B | U[5:0] |M|Q[4:0] | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ +|0 0 1 0 0|b b b|1 1|i i i i i i|F|B B B|U U U U U U|1|Q Q Q Q Q | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ + +Load Register-Register ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+---+-+---+-+-+-----+-----------+------------+ +| major | b |aa |1 1 0|zz |x|d|B | C[5:0] | A[5:0] | ++---------+-----+---+-----+---+-+-+-----+-----------+------------+ +|0 0 1 0 0|b b b|a a|1 1 0|Z Z|X|D|B B B|C C C C C C|A A A A A A | ++---------+-----+---+---+-+---+-+-+-----+-----------+------------+ + +*/ +static int arc_decode_major04_zop (DisasCtxt *ctx, +unsigned _B,TCGv c) +{ +int ret =BS_NONE ; + +switch (_B) { +case 0x01 : { + ret =arc_gen_SLEEP (ctx, c); +break ; + } +case 0x02 : { + ret =arc_gen_SWI (ctx); +break ; + } +case 0x03 : { + ret =arc_gen_SYNC (ctx); +break ; + } +case 0x04 : { + ret =arc_gen_RTIE (ctx); +break ; + } +case 0x05 : { + ret =arc_gen_BRK (ctx); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} + +static int arc_decode_major04_sop (DisasCtxt *ctx, +unsigned _A,unsigned _B,TCGv b,TCGv c) +{ +int ret =BS_NONE ; + +switch (_A) { +case 0x00 : { +arc_decode_src (ctx, c); + ret =arc_gen_ASL (ctx, b, c); +break ; + } +case 0x01 : { +arc_decode_src (ctx, c); + ret =arc_gen_ASR (ctx, b, c); +break ; + } +case 0x02 : { +arc_decode_src (ctx, c); + ret =arc_gen_LSR (ctx, b, c); +break ; + } +case 0x03 : { +arc_decode_src (ctx, c); + ret =arc_gen_ROR (ctx, b, c); +break ; + } +case 0x04 : { +arc_decode_src (ctx, c); + ret =arc_gen_RRC (ctx, b, c); +break ; + } +case 0x05 : { +arc_decode_src (ctx, c); + ret =arc_gen_SEXB (ctx, b, c); +break ; + } +case 0x06 : { +arc_decode_src (ctx, c); + ret =arc_gen_SEXW (ctx, b, c); +break ; + } +case 0x07 : { +arc_decode_src (ctx, c); + ret =arc_gen_EXTB (ctx, b, c); +break ; + } +case 0x08 : { +arc_decode_src (ctx, c); + ret =arc_gen_EXTW (ctx, b, c); +break ; + } +case 0x09 : { +arc_decode_src (ctx, c); + ret =arc_gen_ABS (ctx, b, c); +break ; + } +case 0x0A : { +arc_decode_src (ctx, c); + ret =arc_gen_NOT (ctx, b, c); +break ; + } +case 0x0B : { +arc_decode_src (ctx, c); + ret =arc_gen_RLC (ctx, b, c); +break ; + } +case 0x0C : { +arc_decode_src (ctx, c); + ret =arc_gen_EX (ctx, b, c); +break ; + } +case 0x3F : { + ret =arc_decode_major04_zop (ctx, _B, c); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} +static int arc_decode_major04_op (DisasCtxt *ctx, +uint32_t opcode,TCGv a,TCGv b,TCGv c,unsigned _Q) +{ +int ret =BS_NONE ; +unsigned _A =extract32 (opcode,0 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _b =extract32 (opcode,24 ,3 ); +unsigned minor =extract32 (opcode,16 ,6 ); +TCGLabel *skip =gen_new_label (); + + _B = (_B <<3 ) | _b; + +switch (minor) { +case 0x00 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADD (ctx, a, b, c); +break ; + } +case 0x01 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADC (ctx, a, b, c); +break ; + } +case 0x02 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SUB (ctx, a, b, c); +break ; + } +case 0x03 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SBC (ctx, a, b, c); +break ; + } +case 0x04 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_AND (ctx, a, b, c); +break ; + } +case 0x05 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_OR (ctx, a, b, c); +break ; + } +case 0x06 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BIC (ctx, a, b, c); +break ; + } +case 0x07 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_XOR (ctx, a, b, c); +break ; + } +case 0x08 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MAX (ctx, a, b, c); +break ; + } +case 0x09 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MIN (ctx, a, b, c); +break ; + } +case 0x0A : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, c); + ret =arc_gen_MOV (ctx, b, c); +break ; + } +case 0x0B : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_TST (ctx, b, c); +break ; + } +case 0x0C : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_CMP (ctx, b, c); +break ; + } +case 0x0D : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_CMP (ctx, c, b); +break ; + } +case 0x0E : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_RSUB (ctx, a, b, c); +break ; + } +case 0x0F : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BSET (ctx, a, b, c); +break ; + } +case 0x10 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BCLR (ctx, a, b, c); +break ; + } +case 0x11 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BTST (ctx, b, c); +break ; + } +case 0x12 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BXOR (ctx, a, b, c); +break ; + } +case 0x13 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_BMSK (ctx, a, b, c); +break ; + } +case 0x14 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADD1 (ctx, a, b, c); +break ; + } +case 0x15 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADD2 (ctx, a, b, c); +break ; + } +case 0x16 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADD3 (ctx, a, b, c); +break ; + } +case 0x17 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SUB1 (ctx, a, b, c); +break ; + } +case 0x18 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SUB2 (ctx, a, b, c); +break ; + } +case 0x19 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SUB3 (ctx, a, b, c); +break ; + } +case 0x1A : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MPY (ctx, a, b, c); +break ; + } +case 0x1B : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MPYH (ctx, a, b, c); +break ; + } +case 0x1C : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MPYHU (ctx, a, b, c); +break ; + } +case 0x1D : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MPYU (ctx, a, b, c); +break ; + } +case 0x20 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, c); + ret =arc_gen_J (ctx, c,ARC_COND_AL ); +break ; + } +case 0x21 : { + ctx->opt.d =1 ; +arc_decode_src (ctx, c); + ret =arc_gen_J (ctx, c,ARC_COND_AL ); +break ; + } +case 0x22 : { +arc_decode_src (ctx, c); + ret =arc_gen_JL (ctx, c, _Q); +break ; + } +case 0x23 : { + ctx->opt.d =1 ; +arc_decode_src (ctx, c); + ret =arc_gen_JL (ctx, c, _Q); +break ; + } +case 0x28 : { + ret =arc_gen_LPcc (ctx, c, _Q); +break ; + } +case 0x29 : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, c); + ret =arc_gen_FLAG (ctx, c); +break ; + } +case 0x2A : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, c); + ret =arc_gen_LR (ctx, b, c); +break ; + } +case 0x2B : { +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SR (ctx, b, c); +break ; + } +case 0x2F : { +arc_gen_jump_ifnot (ctx, _Q, skip); + ret =arc_decode_major04_sop (ctx, _A, _B, b, c); +break ; + } + case 0x30 ... 0x37: { +unsigned _DI =extract32 (opcode,15 ,1 ); +unsigned _X =extract32 (opcode,16 ,1 ); +unsigned _ZZ =extract32 (opcode,17 ,2 ); +unsigned _AA =extract32 (opcode,22 ,2 ); + + ctx->opt.zz = _ZZ; + ctx->opt.x = _X; + ctx->opt.aa = _AA; + ctx->opt.di = _DI; + +arc_gen_jump_ifnot (ctx, _Q, skip); +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_LD (ctx, a, b, c); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +gen_set_label (skip); + +return ret; +} + +static int arc_decode_major04 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _A =extract32 (opcode,0 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _C =extract32 (opcode,6 ,6 ); +unsigned _F =extract32 (opcode,15 ,1 ); +unsigned _Q =extract32 (opcode,0 ,5 ); +unsigned _S =extract32 (opcode,0 ,6 ); +unsigned _b =extract32 (opcode,24 ,3 ); +unsigned _s =extract32 (opcode,6 ,6 ); +unsigned _u =extract32 (opcode,6 ,6 ); + + _B = (_B <<3 ) | _b; + +switch (extract32 (opcode,22 ,2 )) { +case 0x00 : { +/* General Operations Register-Register */ + +TCGv a = cpu_r[_A]; +TCGv b = cpu_r[_B]; +TCGv c = cpu_r[_C]; + ctx->opt.f = _F; + + ret =arc_decode_major04_op (ctx, opcode, a, b, c,ARC_COND_AL ); + +break ; + } +case 0x01 : { +/* General Operations Register with Unsigned 6-bit Immediate */ + +TCGv a = cpu_r[_A]; +TCGv b = cpu_r[_B]; +TCGv u =tcg_const_local_i32 (_u); + ctx->opt.f = _F; + + ret =arc_decode_major04_op (ctx, opcode, a, b, u,ARC_COND_AL ); + +tcg_temp_free_i32 (u); +break ; + } +case 0x02 : { +/* General Operations Register with Signed 12-bit Immediate */ + +TCGv b = cpu_r[_B]; +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<6 ) | _s,0 ,12 )); + ctx->opt.f = _F; + + ret =arc_decode_major04_op (ctx, opcode, b, b, s,ARC_COND_AL ); + +tcg_temp_free_i32 (s); +break ; + } +case 0x03 : { +if (extract32 (opcode,5 ,1 ) ==0 ) { +/* General Operations Conditional Register */ + +TCGv b = cpu_r[_B]; +TCGv c = cpu_r[_C]; + ctx->opt.f = _F; + + ret =arc_decode_major04_op (ctx, opcode, b, b, c, _Q); + }else { +TCGv b = cpu_r[_B]; +TCGv u =tcg_const_local_i32 (_u); + + ctx->opt.f = _F; + + ret =arc_decode_major04_op (ctx, opcode, b, b, u, _Q); + } + +break ; + } + } +return ret; +} + +/* +Extension ALU Operation, Register-Register ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major |b |P | minor |F|B | C[5:0] | A[5:0] | ++---------+-----+---+-----------+-+-----+-----------+------------+ +|0 0 1 0 1|b b b|0 0|i i i i i i|F|B B B|C C C C C C|A A A A A A | ++---------+-----+---+-----------+-+-----+-----------+------------+ + +Extension ALU Operation, Register with Unsigned 6-bit Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major |b |P | minor |F|B | U[5:0] | A[5:0] | ++---------+-----+---+-----------+-+-----+-----------+------------+ +|0 0 1 0 1|b b b|0 1|i i i i i i|F|B B B|U U U U U U|A A A A A A | ++---------+-----+---+-----------+-+-----+-----------+------------+ + +Extension ALU Operation, Register with Signed 12-bit Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major |b |P | minor |F|B | S[5:0] | S[11:6] | ++---------+-----+---+-----------+-+-----+-----------+------------+ +|0 0 1 0 1|b b b|1 0|i i i i i i|F|B B B|s s s s s s|S S S S S S | ++---------+-----+---+-----------+-+-----+-----------+------------+ + +Extension ALU Operation, Conditional Register ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major |b |P | minor |F|B | C[5:0] |M| Q[5:0] | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ +|0 0 1 0 1|b b b|1 1|i i i i i i|F|B B B|C C C C C C|0|Q Q Q Q Q | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ + +Extension ALU Operation, Conditional Register with Unsigned 6-bit Immediate ++----------------------------------------------------------------+ +|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+---+-----------+-+-----+-----------+------------+ +| major |b |P | minor |F|B | U[5:0] |M| Q[5:0] | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ +|0 0 1 0 1|b b b|1 1|i i i i i i|F|B B B|U U U U U U|1|Q Q Q Q Q | ++---------+-----+---+-----------+-+-----+-----------+-+----------+ + +*/ +static int arc_decode_major05_zop (DisasCtxt *ctx, +unsigned _B,TCGv c) { -return BS_STOP ; +int ret =BS_NONE ; + + ret =arc_gen_INVALID (ctx); + +return ret; } +static int arc_decode_major05_sop (DisasCtxt *ctx, +unsigned _A,unsigned _B,TCGv b,TCGv c) +{ +int ret =BS_NONE ; +switch (_A) { +case 0x00 : { +arc_decode_src (ctx, c); + ret =arc_gen_SWAP (ctx, b, c); +break ; + } +case 0x01 : { +arc_decode_src (ctx, c); + ret =arc_gen_NORM (ctx, b, c); +break ; + } +case 0x02 : { +arc_decode_src (ctx, c); + ret =arc_gen_SAT16 (ctx, b, c); +break ; + } +case 0x03 : { +arc_decode_src (ctx, c); + ret =arc_gen_RND16 (ctx, b, c); +break ; + } +case 0x04 : { +arc_decode_src (ctx, c); + ret =arc_gen_ABSSW (ctx, b, c); +break ; + } +case 0x05 : { +arc_decode_src (ctx, c); + ret =arc_gen_ABSS (ctx, b, c); +break ; + } +case 0x06 : { +arc_decode_src (ctx, c); + ret =arc_gen_NEGSW (ctx, b, c); +break ; + } +case 0x07 : { +arc_decode_src (ctx, c); + ret =arc_gen_NEGS (ctx, b, c); +break ; + } +case 0x08 : { +arc_decode_src (ctx, c); + ret =arc_gen_NORMW (ctx, b, c); +break ; + } +case 0x3F : { + ret =arc_decode_major05_zop (ctx, _B, c); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } +return ret; +} +static int arc_decode_major05_op (DisasCtxt *ctx, +uint32_t opcode,TCGv a,TCGv b,TCGv c) +{ +int ret =BS_NONE ; +unsigned _i =extract32 (opcode,16 ,6 ); +unsigned _A =extract32 (opcode,0 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _b =extract32 (opcode,24 ,3 ); + + _B = (_B <<3 ) | _b; + +switch (_i) { +case 0x00 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ASLm (ctx, a, b, c); +break ; + } +case 0x01 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_LSRm (ctx, a, b, c); +break ; + } +case 0x02 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ASRm (ctx, a, b, c); +break ; + } +case 0x03 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_RORm (ctx, a, b, c); +break ; + } +case 0x04 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MUL64 (ctx, a, b, c); +break ; + } +case 0x05 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_MULU64 (ctx, a, b, c); +break ; + } +case 0x06 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADDS (ctx, a, b, c); +break ; + } +case 0x07 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SUBS (ctx, a, b, c); +break ; + } +case 0x08 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_DIVAW (ctx, a, b, c); +break ; + } +case 0x0A : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ASLS (ctx, a, b, c); +break ; + } +case 0x0B : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ASRS (ctx, a, b, c); +break ; + } +case 0x28 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_ADDSDW (ctx, a, b, c); +break ; + } +case 0x29 : { +arc_decode_src (ctx, b); +arc_decode_src (ctx, c); + ret =arc_gen_SUBSDW (ctx, a, b, c); +break ; + } +case 0x2F : { + ret =arc_decode_major05_sop (ctx, _A, _B, b, c); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} + +static int arc_decode_major05 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _A =extract32 (opcode,0 ,6 ); +unsigned _B =extract32 (opcode,12 ,3 ); +unsigned _C =extract32 (opcode,6 ,6 ); +unsigned _F =extract32 (opcode,15 ,1 ); +unsigned _Q =extract32 (opcode,0 ,5 ); +unsigned _S =extract32 (opcode,0 ,6 ); +unsigned _b =extract32 (opcode,24 ,3 ); +unsigned _s =extract32 (opcode,6 ,6 ); +unsigned _u =extract32 (opcode,6 ,6 ); + + _B = (_B <<3 ) | _b; + +switch (extract32 (opcode,22 ,2 )) { +case 0x00 : { +/* +Extension ALU Operation, Register-Register +*/ +TCGv a = cpu_r[_A]; +TCGv b = cpu_r[_B]; +TCGv c = cpu_r[_C]; + ctx->opt.f = _F; + + ret =arc_decode_major05_op (ctx, opcode, a, b, c); +break ; + } +case 0x01 : { +/* +Extension ALU Operation, Register with Unsigned 6-bit Immediate +*/ +TCGv a = cpu_r[_A]; +TCGv b = cpu_r[_B]; +TCGv u =tcg_const_local_i32 (_u); + ctx->opt.f = _F; + + ret =arc_decode_major05_op (ctx, opcode, a, b, u); + +tcg_temp_free_i32 (u); +break ; + } +case 0x02 : { +/* +Extension ALU Operation, Register with Signed 12-bit Immediate +*/ +TCGv b = cpu_r[_B]; +TCGv s =tcg_const_local_i32 (sextract32 ((_S <<6 ) | _s,0 ,12 )); + ctx->opt.f = _F; + + ret =arc_decode_major05_op (ctx, opcode, b, b, s); + +tcg_temp_free_i32 (s); +break ; + } +case 0x03 : { + ctx->opt.f = _F; +TCGLabel *skip =gen_new_label (); + +arc_gen_jump_ifnot (ctx, _Q, skip); + +if (extract32 (opcode,5 ,1 ) ==0 ) { +/* +Extension ALU Operation, Conditional Register +*/ +TCGv b = cpu_r[_B]; +TCGv c = cpu_r[_C]; + + ret =arc_decode_major05_op (ctx, opcode, b, b, c); + + }else { +/* +Extension ALU Operation, Conditional Register with +Unsigned 6-bit Immediate +*/ +TCGv b = cpu_r[_B]; +TCGv u =tcg_const_local_i32 (_u); + + ret =arc_decode_major05_op (ctx, opcode, b, b, u); + +tcg_temp_free_i32 (u); + } + +gen_set_label (skip); +break ; + } + } +return ret; +} + +/* + +Load /Add Register-Register ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+---+------+ +| major | b | c | i | a | ++---------+-----+-----+---+------+ +|0 1 1 0 0|b b b|c c c|i i|a a a | ++---------+-----+-----+---+------+ +*/ +static int arc_decode_major0C (DisasCtxt *ctx,uint32_t opcode) +{ +unsigned _a =extract32 (opcode,0 ,3 ); +unsigned _c =extract32 (opcode,5 ,3 ); +unsigned _b =extract32 (opcode,8 ,3 ); +unsigned _i =extract32 (opcode,3 ,2 ); +int ret =BS_NONE ; + +TCGv a = cpu_r[(_a /4 ) *12 + _a %4 ]; +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv c = cpu_r[(_c /4 ) *12 + _c %4 ]; + +switch (_i) { +case 0x00 : { + ctx->opt.zz =0 ; + ret =arc_gen_LD (ctx, a, b, c); +break ; + } +case 0x01 : { + ctx->opt.zz =1 ; + ret =arc_gen_LD (ctx, a, b, c); +break ; + } +case 0x02 : { + ctx->opt.zz =2 ; + ret =arc_gen_LD (ctx, a, b, c); +break ; + } +case 0x03 : { + ret =arc_gen_ADD (ctx, a, b, c); +break ; + } + } +return ret; +} + +/* + +Load /Add Register-Register ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+---+------+ +| major | b | c | i | u | ++---------+-----+-----+---+------+ +|0 1 1 0 1|b b b|c c c|i i|u u u | ++---------+-----+-----+---+------+ +*/ +static int arc_decode_major0D (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _u =extract32 (opcode,0 ,3 ); +unsigned _c =extract32 (opcode,5 ,3 ); +unsigned _b =extract32 (opcode,8 ,3 ); +unsigned _i =extract32 (opcode,3 ,2 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv c = cpu_r[(_c /4 ) *12 + _c %4 ]; +TCGv u =tcg_const_local_i32 (_u); + +switch (_i) { +case 0x00 : { + ret =arc_gen_ADD (ctx, c, b, u); +break ; + } +case 0x01 : { + ret =arc_gen_SUB (ctx, c, b, u); +break ; + } +case 0x02 : { + ret =arc_gen_ASLm (ctx, c, b, u); +break ; + } +case 0x03 : { + ret =arc_gen_ASRm (ctx, c, b, u); +break ; + } + } + +tcg_temp_free_i32 (u); +return ret; +} + +/* + +Mov/Cmp/Add with High Register ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+---+------+ +| major | b | h | i | H | ++---------+-----+-----+---+------+ +|0 1 1 1 0|b b b|h h h|i i|H H H | ++---------+-----+-----+---+------+ +*/ +static int arc_decode_major0E (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _H =extract32 (opcode,0 ,3 ); +unsigned _h =extract32 (opcode,5 ,3 ); +unsigned _b =extract32 (opcode,8 ,3 ); +unsigned _i =extract32 (opcode,3 ,2 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv h = cpu_r[(_H <<3 ) | _h]; + +switch (_i) { +case 0x00 : { +arc_decode_src (ctx, h); + ret =arc_gen_ADD (ctx, b, b, h); +break ; + } +case 0x01 : { +arc_decode_src (ctx, h); + ret =arc_gen_MOV (ctx, b, h); +break ; + } +case 0x02 : { +arc_decode_src (ctx, h); + ret =arc_gen_CMP (ctx, b, h); +break ; + } +case 0x03 : { + ret =arc_gen_MOV (ctx, h, b); +break ; + } + } + +return ret; +} + +/* + +General Operations, register-register ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+----------+ +| major | b | c | i | ++---------+-----+-----+----------+ +|0 1 1 1 1|b b b|c c c|i i i i i | ++---------+-----+-----+----------+ + +General Operations, register ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+----------+ +| major | b | i | 0 | ++---------+-----+-----+----------+ +|0 1 1 1 1|b b b|i i i|0 0 0 0 0 | ++---------+-----+-----+----------+ + +General Operations, no register ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+----------+ +| major | i | 7 | 0 | ++---------+-----+-----+----------+ +|0 1 1 1 1|i i i|1 1 1|0 0 0 0 0 | ++---------+-----+-----+----------+ +*/ +static int arc_decode_major0F_zop (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _i =extract32 (opcode,8 ,3 ); + +switch (_i) { +case 0x00 : { + ret =arc_gen_NOP (ctx); +break ; + } +case 0x01 : { + ret =arc_gen_UNIMP (ctx); +break ; + } +case 0x04 : { + ret =arc_gen_J (ctx, cpu_blink,ARC_COND_EQ ); +break ; + } +case 0x05 : { + ret =arc_gen_J (ctx, cpu_blink,ARC_COND_NE ); +break ; + } +case 0x06 : { + ret =arc_gen_J (ctx, cpu_blink,ARC_COND_AL ); +break ; + } +case 0x07 : { + ctx->opt.d =1 ; + ret =arc_gen_J (ctx, cpu_blink,ARC_COND_AL ); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} + +static int arc_decode_major0F_sop (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _i =extract32 (opcode,5 ,3 ); +unsigned _b =extract32 (opcode,8 ,3 ); +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +switch (_i) { +case 0x00 : { + ret =arc_gen_J (ctx, b,ARC_COND_AL ); +break ; + } +case 0x01 : { + ctx->opt.d =1 ; + ret =arc_gen_J (ctx, b,ARC_COND_AL ); +break ; + } +case 0x02 : { + ret =arc_gen_JL (ctx, b,ARC_COND_AL ); +break ; + } +case 0x03 : { + ctx->opt.d =1 ; + ret =arc_gen_JL (ctx, b,ARC_COND_AL ); +break ; + } +case 0x06 : { +TCGLabel *skip =gen_new_label (); + +arc_gen_jump_ifnot (ctx,ARC_COND_NE , skip); + + ret =arc_gen_SUB (ctx, b, b, b); + +gen_set_label (skip); + +break ; + } +case 0x07 : { + ret =arc_decode_major0F_zop (ctx, opcode); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} + +static int arc_decode_major0F (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _c =extract32 (opcode,5 ,3 ); +unsigned _b =extract32 (opcode,8 ,3 ); +unsigned _i =extract32 (opcode,0 ,5 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv c = cpu_r[(_c /4 ) *12 + _c %4 ]; + +switch (_i) { +case 0x00 : { + ret =arc_decode_major0F_sop (ctx, opcode); +break ; + } +case 0x02 : { + ret =arc_gen_SUB (ctx, b, b, c); +break ; + } +case 0x04 : { + ret =arc_gen_AND (ctx, b, b, c); +break ; + } +case 0x05 : { + ret =arc_gen_OR (ctx, b, b, c); +break ; + } +case 0x06 : { + ret =arc_gen_BIC (ctx, b, b, c); +break ; + } +case 0x07 : { + ret =arc_gen_XOR (ctx, b, b, c); +break ; + } +case 0x0B : { + ret =arc_gen_TST (ctx, b, c); +break ; + } +case 0x0C : { + ret =arc_gen_MUL64 (ctx, b, b, c); +break ; + } +case 0x0D : { + ret =arc_gen_SEXB (ctx, b, c); +break ; + } +case 0x0E : { + ret =arc_gen_SEXW (ctx, b, c); +break ; + } +case 0x0F : { + ret =arc_gen_EXTB (ctx, b, c); +break ; + } +case 0x10 : { + ret =arc_gen_EXTW (ctx, b, c); +break ; + } +case 0x11 : { + ret =arc_gen_ABS (ctx, b, c); +break ; + } +case 0x12 : { + ret =arc_gen_NOT (ctx, b, c); +break ; + } +case 0x13 : { + ret =arc_gen_NEG (ctx, b, c); +break ; + } +case 0x14 : { + ret =arc_gen_ADD1 (ctx, b, b, c); +break ; + } +case 0x15 : { + ret =arc_gen_ADD2 (ctx, b, b, c); +break ; + } +case 0x16 : { + ret =arc_gen_ADD3 (ctx, b, b, c); +break ; + } +case 0x18 : { + ret =arc_gen_ASLm (ctx, b, b, c); +break ; + } +case 0x19 : { + ret =arc_gen_LSRm (ctx, b, b, c); +break ; + } +case 0x1A : { + ret =arc_gen_ASRm (ctx, b, b, c); +break ; + } +case 0x1B : { + ret =arc_gen_ASL (ctx, b, c); +break ; + } +case 0x1C : { + ret =arc_gen_ASR (ctx, b, c); +break ; + } +case 0x1D : { + ret =arc_gen_LSR (ctx, b, c); +break ; + } +case 0x1E : { +unsigned _u =extract32 (opcode,5 ,6 ); +TCGv u =tcg_const_local_i32 (_u); + ret =arc_gen_TRAP (ctx, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x1F : { + ret =arc_gen_BRK (ctx); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } + +return ret; +} + +/* +Load/Store with Offset ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+----------+ +| major | b | c | u | ++---------+-----+-----+----------+ +|I I I I I|b b b|c c c|u u u u u | ++---------+-----+-----+----------+ + +*/ +static int arc_decode_major10_16 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _i =extract32 (opcode,11 ,5 ); +unsigned _u =extract32 (opcode,0 ,5 ); +unsigned _c =extract32 (opcode,5 ,3 ); +unsigned _b =extract32 (opcode,8 ,3 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv c = cpu_r[(_c /4 ) *12 + _c %4 ]; +TCGv u; + +switch (_i) { +case 0x10 : { + ctx->opt.zz =0 ; + u =tcg_const_local_i32 (_u <<2 ); + ret =arc_gen_LD (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x11 : { + ctx->opt.zz =1 ; + u =tcg_const_local_i32 (_u); + ret =arc_gen_LD (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x12 : { + ctx->opt.zz =2 ; + u =tcg_const_local_i32 (_u <<1 ); + ret =arc_gen_LD (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x13 : { + ctx->opt.zz =2 ; + ctx->opt.x =1 ; + u =tcg_const_local_i32 (_u <<1 ); + ret =arc_gen_LD (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x14 : { + ctx->opt.zz =0 ; + u =tcg_const_local_i32 (_u <<2 ); + ret =arc_gen_ST (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x15 : { + ctx->opt.zz =1 ; + u =tcg_const_local_i32 (_u); + ret =arc_gen_ST (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } +case 0x16 : { + ctx->opt.zz =2 ; + u =tcg_const_local_i32 (_u <<1 ); + ret =arc_gen_ST (ctx, c, b, u); +tcg_temp_free_i32 (u); +break ; + } + } + + +return ret; +} + +/* +Shift/Subtract/Bit Immediate ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+----------+ +| major | b | i | u | ++---------+-----+-----+----------+ +|1 0 1 1 1|b b b|i i i|u u u u u | ++---------+-----+-----+----------+ + +*/ +static int arc_decode_major17 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _i =extract32 (opcode,5 ,3 ); +unsigned _u =extract32 (opcode,0 ,5 ); +unsigned _b =extract32 (opcode,8 ,3 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv u =tcg_const_local_i32 (_u); + +switch (_i) { +case 0x00 : { + ret =arc_gen_ASLm (ctx, b, b, u); +break ; + } +case 0x01 : { + ret =arc_gen_LSRm (ctx, b, b, u); +break ; + } +case 0x02 : { + ret =arc_gen_ASRm (ctx, b, b, u); +break ; + } +case 0x03 : { + ret =arc_gen_SUB (ctx, b, b, u); +break ; + } +case 0x04 : { + ret =arc_gen_BSET (ctx, b, b, u); +break ; + } +case 0x05 : { + ret =arc_gen_BCLR (ctx, b, b, u); +break ; + } +case 0x06 : { + ret =arc_gen_BMSK (ctx, b, b, u); +break ; + } +case 0x07 : { + ret =arc_gen_BTST (ctx, b, u); +break ; + } + } + +tcg_temp_free_i32 (u); + +return ret; +} + +/* +Stack Pointer Based Instructions ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-----+----------+ +| major | b | i | u | ++---------+-----+-----+----------+ +|1 1 0 0 0|b b b|i i i|u u u u u | ++---------+-----+-----+----------+ + +*/ +static int arc_decode_major18 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _i =extract32 (opcode,5 ,3 ); +unsigned _u =extract32 (opcode,0 ,5 ); +unsigned _b =extract32 (opcode,8 ,3 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv u =tcg_const_local_i32 (_u <<2 ); + +switch (_i) { +case 0x00 : { + ret =arc_gen_LD (ctx, b, cpu_sp, u); +break ; + } +case 0x01 : { + ctx->opt.zz =1 ; + ret =arc_gen_LD (ctx, b, cpu_sp, u); +break ; + } +case 0x02 : { + ret =arc_gen_ST (ctx, b, cpu_sp, u); +break ; + } +case 0x03 : { + ctx->opt.zz =1 ; + ret =arc_gen_ST (ctx, b, cpu_sp, u); +break ; + } +case 0x04 : { + ret =arc_gen_ADD (ctx, b, cpu_sp, u); +break ; + } +case 0x05 : { +switch (_b) { +case 0x00 : { + ret =arc_gen_ADD (ctx, cpu_sp, cpu_sp, u); +break ; + } +case 0x01 : { + ret =arc_gen_SUB (ctx, cpu_sp, cpu_sp, u); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } +break ; + } +case 0x06 : { +switch (_u) { +case 0x01 : { + ret =arc_gen_POP (ctx, b); +break ; + } +case 0x11 : { + ret =arc_gen_POP (ctx, cpu_blink); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } +break ; + } +case 0x07 : { +switch (_u) { +case 0x01 : { + ret =arc_gen_PUSH (ctx, b); +break ; + } +case 0x11 : { + ret =arc_gen_PUSH (ctx, cpu_blink); +break ; + } +default : { + ret =arc_gen_INVALID (ctx); + } + } +break ; + } + } + +tcg_temp_free_i32 (u); + +return ret; +} + +/* +Stack Pointer Based Instructions ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+---+------------------+ +| major | i | s | ++---------+---+------------------+ +|1 1 0 0 1|i i|s s s s s s s s s | ++---------+---+------------------+ +*/ +static int arc_decode_major19 (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +signed _s =sextract32 (opcode,0 ,9 ); +unsigned _i =extract32 (opcode,9 ,2 ); +TCGv s; + +switch (_i) { +case 0x00 : { + ctx->opt.zz =0 ; + s =tcg_const_local_i32 (_s <<2 ); + ret =arc_gen_LD (ctx, cpu_r[0 ], cpu_gp, s); +break ; + } +case 0x01 : { + ctx->opt.zz =1 ; + s =tcg_const_local_i32 (_s); + ret =arc_gen_LD (ctx, cpu_r[0 ], cpu_gp, s); +break ; + } +case 0x02 : { + ctx->opt.zz =2 ; + s =tcg_const_local_i32 (_s <<1 ); + ret =arc_gen_LD (ctx, cpu_r[0 ], cpu_gp, s); +break ; + } +case 0x03 : { + s =tcg_const_local_i32 (_s <<2 ); + ret =arc_gen_ADD (ctx, cpu_r[0 ], cpu_gp, s); +break ; + } + } + +tcg_temp_free_i32 (s); +return ret; +} + +/* +Load PCL-Relative ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+----------------+ +| major | b | s | ++---------+-----+----------------+ +|1 1 0 1 0|b b b|s s s s s s s s | ++---------+-----+----------------+ + +*/ +static int arc_decode_major1A (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _u =extract32 (opcode,0 ,8 ); +unsigned _b =extract32 (opcode,8 ,3 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv u =tcg_const_local_i32 (_u <<2 ); + + ret =arc_gen_LD (ctx, b, cpu_pcl, u); + +tcg_temp_free_i32 (u); +return ret; +} + +/* +Move Immediate ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+----------------+ +| major | b | u | ++---------+-----+----------------+ +|1 1 0 1 1|b b b|u u u u u u u u | ++---------+-----+----------------+ +*/ +static int arc_decode_major1B (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _u =extract32 (opcode,0 ,8 ); +unsigned _b =extract32 (opcode,8 ,3 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv u =tcg_const_local_i32 (_u); + + ret =arc_gen_MOV (ctx, b, u); + +tcg_temp_free_i32 (u); +return ret; +} + +/* +ADD/CMP Immediate ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-+--------------+ +| major | b |i| u | ++---------+-----+-+--------------+ +|1 1 1 0 0|b b b|i|u u u u u u u | ++---------+-----+-+--------------+ +*/ +static int arc_decode_major1C (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +unsigned _u =extract32 (opcode,0 ,7 ); +unsigned _b =extract32 (opcode,8 ,3 ); +unsigned _i =extract32 (opcode,7 ,1 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv u =tcg_const_local_i32 (_u); + +if (_i ==0 ) { + ret =arc_gen_ADD (ctx, b, b, u); + }else { + ret =arc_gen_CMP (ctx, b, u); + } + +tcg_temp_free_i32 (u); +return ret; +} + +/* +Branch on Compare Register with Zero ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+-----+-+--------------+ +| major | b |i| s | ++---------+-----+-+--------------+ +|1 1 1 0 1|b b b|i|s s s s s s s | ++---------+-----+-+--------------+ +*/ +static int arc_decode_major1D (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +signed _s =sextract32 (opcode,0 ,7 ); +unsigned _b =extract32 (opcode,8 ,3 ); +unsigned _i =extract32 (opcode,7 ,1 ); + +TCGv b = cpu_r[(_b /4 ) *12 + _b %4 ]; +TCGv s =tcg_const_local_i32 (_s); + +if (_i ==0 ) { + ret =arc_gen_BR (ctx, b, ctx->zero, s,TCG_COND_EQ ); + }else { + ret =arc_gen_BR (ctx, b, ctx->zero, s,TCG_COND_NE ); + } + +tcg_temp_free_i32 (s); +return ret; +} + +/* +Branch on Compare Register with Zero ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+---+------------------+ +| major | b | s | ++---------+---+------------------+ +|1 1 1 1 0|i i|s s s s s s s s s | ++---------+---+------------------+ +*/ +static int arc_decode_major1E (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +signed _s =sextract32 (opcode,0 ,9 ); +unsigned _i =extract32 (opcode,9 ,2 ); +TCGv s =tcg_const_local_i32 (_s); + +switch (_i) { +case 0x00 : { + ret =arc_gen_B (ctx, s,ARC_COND_AL ); +break ; + } +case 0x01 : { + ret =arc_gen_B (ctx, s,ARC_COND_EQ ); +break ; + } +case 0x02 : { + ret =arc_gen_B (ctx, s,ARC_COND_NE ); +break ; + } +case 0x03 : { +signed _s =sextract32 (opcode,0 ,6 ); +unsigned _i =extract32 (opcode,5 ,3 ); +TCGv s =tcg_const_local_i32 (_s); + +switch (_i) { +case 0x00 : { + ret =arc_gen_B (ctx, s,ARC_COND_GT ); +break ; + } +case 0x01 : { + ret =arc_gen_B (ctx, s,ARC_COND_GE ); +break ; + } +case 0x02 : { + ret =arc_gen_B (ctx, s,ARC_COND_LT ); +break ; + } +case 0x03 : { + ret =arc_gen_B (ctx, s,ARC_COND_LE ); +break ; + } +case 0x04 : { + ret =arc_gen_B (ctx, s,ARC_COND_HI ); +break ; + } +case 0x05 : { + ret =arc_gen_B (ctx, s,ARC_COND_HS ); +break ; + } +case 0x06 : { + ret =arc_gen_B (ctx, s,ARC_COND_LO ); +break ; + } +case 0x07 : { + ret =arc_gen_B (ctx, s,ARC_COND_LS ); +break ; + } + } + +tcg_temp_free_i32 (s); +break ; + } + } + +tcg_temp_free_i32 (s); +return ret; +} + +/* +Branch on Compare Register with Zero ++--------------------------------+ +|1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | +|5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | ++---------+----------------------+ +| major | s | ++---------+----------------------+ +|1 1 1 1 1|s s s s s s s s s s s | ++---------+----------------------+ +*/ +static int arc_decode_major1F (DisasCtxt *ctx,uint32_t opcode) +{ +int ret =BS_NONE ; +signed _s =sextract32 (opcode,0 ,11 ); + +TCGv s =tcg_const_local_i32 (_s); + + ret =arc_gen_BL (ctx, s,ARC_COND_AL ); + +tcg_temp_free_i32 (s); +return ret; +} + +int arc_decode (DisasCtxt *ctx) +{ +unsigned curr_major; +uint32_t curr_opcode; + +unsigned next_major; +uint32_t next_opcode; + +decode_f decode[32 ] = { + [0x00 ] = arc_decode_major00, + [0x01 ] = arc_decode_major01, + [0x02 ] = arc_decode_major02, + [0x03 ] = arc_decode_major03, + [0x04 ] = arc_decode_major04, + [0x05 ] = arc_decode_major05, + + [0x06 ] = arc_decode_invalid, + [0x07 ] = arc_decode_invalid, + [0x08 ] = arc_decode_invalid, + [0x09 ] = arc_decode_invalid, + [0x0a ] = arc_decode_invalid, + [0x0b ] = arc_decode_invalid, + + [0x0c ] = arc_decode_major0C, + [0x0d ] = arc_decode_major0D, + [0x0e ] = arc_decode_major0E, + [0x0f ] = arc_decode_major0F, + + [0x10 ] = arc_decode_major10_16, + [0x11 ] = arc_decode_major10_16, + [0x12 ] = arc_decode_major10_16, + [0x13 ] = arc_decode_major10_16, + [0x14 ] = arc_decode_major10_16, + [0x15 ] = arc_decode_major10_16, + [0x16 ] = arc_decode_major10_16, + + [0x17 ] = arc_decode_major17, + [0x18 ] = arc_decode_major18, + [0x19 ] = arc_decode_major19, + [0x1a ] = arc_decode_major1A, + [0x1b ] = arc_decode_major1B, + [0x1c ] = arc_decode_major1C, + [0x1d ] = arc_decode_major1D, + [0x1e ] = arc_decode_major1E, + [0x1f ] = arc_decode_major1F, + + }; +memset (&ctx->opt,0 ,sizeof (ctx->opt)); + +/* +1. get current opcode +2. set npc +*/ + curr_opcode =cpu_ldl_code (ctx->env, ctx->cpc); + curr_major =extract32 (curr_opcode,11 ,5 ); + +if (curr_major <=5 ) { + curr_opcode = (curr_opcode <<16 ) | (curr_opcode >>16 ); + ctx->npc = ctx->cpc +4 ; + }else { + ctx->npc = ctx->cpc +2 ; + } + +/* +3. set dpc (used by BL) +*/ + next_opcode =cpu_ldl_code (ctx->env, ctx->npc); + next_major =extract32 (next_opcode,11 ,5 ); +if (next_major <=5 ) { + ctx->dpc = ctx->npc +4 ; + }else { + ctx->dpc = ctx->npc +2 ; + } + + ctx->pcl = ctx->cpc &0xfffffffc ; + +return decode[curr_major](ctx, curr_opcode); +}
Signature · 1 line
2.4.9 (Apple Git-60)
Re: [Qemu-devel] [PATCH RFC v1 28/29] target-arc: decode
Quoted 1 line · Michael Rolnik
+
decode_fdecode[32] = {
There's no reason to use an array here, and worse, a non-static non-const array. Just use a switch here
Quoted 1 line
+ return decode[curr_major](ctx,
curr_opcode);
r~
RFC PATCH 29/29 target-arc: sample board
In reply to Michael Rolnik--- MAINTAINERS | 1 + hw/arc/Makefile.objs | 21 ++++++++++++++ hw/arc/sample.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 hw/arc/Makefile.objs create mode 100644 hw/arc/sample.c
MAINTAINERS +1 -0
@@ -103,6 +103,7 @@ ARC M: Michael Rolnik <[email protected]> S: Maintained F: target-arc/ +F: hw/arc ARM M: Peter Maydell <[email protected]>
hw/arc/Makefile.objs new file +21 -0
@@ -0,0 +1,21 @@ +# +# 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 A 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> +# + +obj-y += sample.o
hw/arc/sample.c new file +80 -0
80 lines not on this page · raw message
Signature · 1 line
2.4.9 (Apple Git-60)
cover ARC cores
In reply to Michael RolnikHi Michael,
Quoted 10 lines · Michael Rolnik
This series of patches adds ARC target to QEMU. It indends to support ????- ARCtangent-A5 processor
????- ARC 600 processor
????- ARC 700 processorAll instructions except ASLS are implemented. Not fully tested yet. However I was able to execute correctly recursive fibonacci calculation. Reset vector is assumed to be some hardcoded value which worked for my test. I am planning to get FreeRTOS for ARC, once I get it, I will able to verify and complete interrupt support.
That's both very unexpected and cool!
I tried your patches on top of current QEMU git master and it:
?a) Builds for ARC
?b) Very simple code really works!
I was able to single-step with GDB through program as simple as:
--------------------->8---------------------
.global _start_start:
mov r0, 1 mov r1, 2 mov r1, r0
--------------------->8---------------------
That's what I saw in GDB:
--------------------->8---------------------
(gdb) disassemble?
Dump of assembler code for function _start:
=> 0x00000100 <+0>: mov r0,0x1
???0x00000104 <+4>: mov r1,0x2
???0x00000108 <+8>: mov r1,r0
End of assembler dump.
(gdb) p $r0
$1 = 0
(gdb) stepi0x00000104 in _start ()
(gdb) p $r0
$2 = 1
(gdb) stepi0x00000108 in _start ()
(gdb) p $r1
$3 = 2
(gdb) stepi0x0000010c in ?? ()
(gdb) p $r1
$4 = 1
--------------------->8---------------------
So again this is very promising even though a lot is essentially missing from this very first implementation.
Anyways IMHO it would be good to have these patches accepted so people may start playing with that stuff adding missing things one by one.
Let me know if you need any help from my side.
Regards,
Alexey
H Alexey.
Thanks.
I need some help in getting a small code that exercises interrupts. For several years I wrote FW for ARC based platforms (ARC4 & ARC6), but it seems I forgot some of the things related to interrupts. I compiled FreeRTOS demo from embARC, however I could not find interrupt vectors there, I assume their board has ROM.
So, if you can help me with such a code, it would be great.
thanks,
Michael
On Fri, Sep 16, 2016 at 6:01 PM, Alexey Brodkin <[email protected]
Quoted 69 lines
wrote:
Hi Michael,
Quoted 8 lines · Michael Rolnik
This series of patches adds ARC target to QEMU. It indends to support
- ARCtangent-A5 processor
- ARC 600 processor
- ARC 700 processorAll instructions except ASLS are implemented. Not fully tested yet. However I was able to execute correctly recursive fibonacci calculation. Reset vector is assumed to be some hardcoded value which worked for my
test.
Quoted 1 line
I am planning to get FreeRTOS for ARC, once I get it, I will able to
verify
Quoted 1 line
and complete interrupt support.
That's both very unexpected and cool!
I tried your patches on top of current QEMU git master and it:
a) Builds for ARC
b) Very simple code really works!I was able to single-step with GDB through program as simple as:
--------------------->8---------------------
.global_start_start:mov r0, 1 mov r1, 2 mov r1, r0--------------------->8---------------------
That's what I saw in GDB:
--------------------->8---------------------
(gdb) disassemble
Dump of assembler code for function_start:=> 0x00000100 <+0>: mov r0,0x1 0x00000104 <+4>: mov r1,0x2 0x00000108 <+8>: mov r1,r0End of assembler dump.
(gdb) p $r0
$1 = 0
(gdb) stepi0x00000104in_start()
(gdb) p $r0
$2 = 1
(gdb) stepi0x00000108in_start()
(gdb) p $r1
$3 = 2
(gdb) stepi0x0000010cin ?? ()
(gdb) p $r1
$4 = 1
--------------------->8---------------------So again this is very promising even though a lot is essentially missing from
this very first implementation.Anyways IMHO it would be good to have these patches accepted so people may start
playing with that stuff adding missing things one by one.Let me know if you need any help from my side.
Regards,
Alexey
Signature · 2 lines
Best Regards, Michael Rolnik
Hi Michael,
I'm pretty sure embARC was not meant to be run on ARCompact (AKA ISAv1 cores like ARC600 & ARC700) instead targets were ARCv2 cores like ARC EM and ARC HS. Unfortunately I have no experience with embARC so adding more experienced person in the thread (Igor Guryanov) who may shed some light on interrupts in embARC.
-Alexey
On Sat, 2016-09-17 at 21:26 +0300, Michael Rolnik wrote:
H Alexey.
Thanks.
I need some help in getting a small code that exercises interrupts. For several years I wrote FW for ARC based platforms (ARC4 & ARC6), but it seems I forgot some of the things related to interrupts. I compiled FreeRTOS demo from embARC, however I could not find interrupt vectors there, I assume their board has ROM. So, if you can help me with such a code, it would be great.
thanks,
Michael
On Fri, Sep 16, 2016 at 6:01 PM, Alexey Brodkin <[email protected]<mailto:[email protected]>> wrote:
Hi Michael,
Quoted 10 lines · Michael Rolnik
This series of patches adds ARC target to QEMU. It indends to support
- ARCtangent-A5 processor
- ARC 600 processor
- ARC 700 processorAll instructions except ASLS are implemented. Not fully tested yet. However I was able to execute correctly recursive fibonacci calculation. Reset vector is assumed to be some hardcoded value which worked for my test. I am planning to get FreeRTOS for ARC, once I get it, I will able to verify and complete interrupt support.
That's both very unexpected and cool!
I tried your patches on top of current QEMU git master and it:
a) Builds for ARC
b) Very simple code really works!
I was able to single-step with GDB through program as simple as:
--------------------->8---------------------
.global _start_start:
mov r0, 1
mov r1, 2
mov r1, r0--------------------->8---------------------
That's what I saw in GDB:
--------------------->8---------------------
(gdb) disassemble
Dump of assembler code for function _start:
=> 0x00000100 <+0>: mov r0,0x1 0x00000104 <+4>: mov r1,0x2 0x00000108 <+8>: mov r1,r0
End of assembler dump.
(gdb) p $r0
$1 = 0
(gdb) stepi0x00000104 in _start ()
(gdb) p $r0
$2 = 1
(gdb) stepi0x00000108 in _start ()
(gdb) p $r1
$3 = 2
(gdb) stepi0x0000010c in ?? ()
(gdb) p $r1
$4 = 1
--------------------->8---------------------
So again this is very promising even though a lot is essentially missing from this very first implementation.
Anyways IMHO it would be good to have these patches accepted so people may start playing with that stuff adding missing things one by one.
Let me know if you need any help from my side.
Regards,
Alexey
--
Best Regards,
Michael Rolnik
Hi Michael,
Long time ago debugged one problem with embARC and I remember I was also puzzled with itss interrupt handling approach. The board itself can fit only prebootloader in the ROM, and interrupt handling is kept in embARC itself.
But, the projects is aimed to support several different RTOS. As I remember, BSP was separated and made ‘universal’.
In other words, not very transparent and obvious ☺. If I recall it there were a single entry for interrupt/exceptions which scanned OS defined data structure in a search for pointers for actual handlers. i.e. it was very different from what you can find in simple baremetal example (like this one - https://github.com/foss-for-synopsys-dwc-arc-processors/ARC-Development-Systems-Forum/tree/master/examples/EMSK/timer_IRQ )
Let me refresh my memory on embARC internals which might have already evolved and I give you overview in a day or two.
Regards,
Igor.
From: Alexey Brodkin
Sent: Monday, September 19, 2016 3:41 PM
To: [email protected]
Cc: [email protected]; Igor Guryanov <[email protected]>; [email protected]
Subject: Re: [PATCH RFC v1 00/29] ARC cores
Hi Michael,
I'm pretty sure embARC was not meant to be run on ARCompact (AKA ISAv1 cores like ARC600 & ARC700) instead targets were ARCv2 cores like ARC EM and ARC HS. Unfortunately I have no experience with embARC so adding more experienced person in the thread (Igor Guryanov) who may shed some light on interrupts in embARC.
-Alexey
On Sat, 2016-09-17 at 21:26 +0300, Michael Rolnik wrote:
H Alexey.
Thanks.
I need some help in getting a small code that exercises interrupts. For several years I wrote FW for ARC based platforms (ARC4 & ARC6), but it seems I forgot some of the things related to interrupts. I compiled FreeRTOS demo from embARC, however I could not find interrupt vectors there, I assume their board has ROM. So, if you can help me with such a code, it would be great.
thanks,
Michael
On Fri, Sep 16, 2016 at 6:01 PM, Alexey Brodkin <[email protected]<mailto:[email protected]>> wrote:
Hi Michael,
Quoted 10 lines · Michael Rolnik
This series of patches adds ARC target to QEMU. It indends to support
- ARCtangent-A5 processor
- ARC 600 processor
- ARC 700 processorAll instructions except ASLS are implemented. Not fully tested yet. However I was able to execute correctly recursive fibonacci calculation. Reset vector is assumed to be some hardcoded value which worked for my test. I am planning to get FreeRTOS for ARC, once I get it, I will able to verify and complete interrupt support.
That's both very unexpected and cool!
I tried your patches on top of current QEMU git master and it:
a) Builds for ARC
b) Very simple code really works!
I was able to single-step with GDB through program as simple as:
--------------------->8---------------------
.global _start_start:
mov r0, 1
mov r1, 2
mov r1, r0--------------------->8---------------------
That's what I saw in GDB:
--------------------->8---------------------
(gdb) disassemble
Dump of assembler code for function _start:
=> 0x00000100 <+0>: mov r0,0x1 0x00000104 <+4>: mov r1,0x2 0x00000108 <+8>: mov r1,r0
End of assembler dump.
(gdb) p $r0
$1 = 0
(gdb) stepi0x00000104 in _start ()
(gdb) p $r0
$2 = 1
(gdb) stepi0x00000108 in _start ()
(gdb) p $r1
$3 = 2
(gdb) stepi0x0000010c in ?? ()
(gdb) p $r1
$4 = 1
--------------------->8---------------------
So again this is very promising even though a lot is essentially missing from this very first implementation.
Anyways IMHO it would be good to have these patches accepted so people may start playing with that stuff adding missing things one by one.
Let me know if you need any help from my side.
Regards,
Alexey
--
Best Regards,
Michael Rolnik
Hi Igor,
I will try to compile this example and test my implementations.
Thank you,
Michael
Quoted 170 lines · Igor Guryanov
Hi Michael,
Long time ago debugged one problem with embARC and I remember I was also puzzled with itss interrupt handling approach.
The board itself can fit only prebootloader in the ROM, and interrupt handling is kept in embARC itself.
But, the projects is aimed to support several different RTOS. As I remember, BSP was separated and made ‘universal’.
In other words, not very transparent and obvious J. If I recall it there were a single entry for interrupt/exceptions which scanned OS defined data structure in a search for pointers for actual handlers. i.e. it was very different from what you can find in simple baremetal example (like this one
- https://github.com/foss-for-synopsys-dwc-arc-processors/
ARC-Development-Systems-Forum/tree/master/examples/EMSK/timer_IRQ )Let me refresh my memory on embARC internals which might have already evolved and I give you overview in a day or two.
Regards,
Igor.
*From:* Alexey Brodkin
*Sent:* Monday, September 19, 2016 3:41 PM
*To:* [email protected]
*Cc:* [email protected]; Igor Guryanov <[email protected]>; [email protected]
*Subject:* Re: [PATCH RFC v1 00/29] ARC coresHi Michael,
I'm pretty sure embARC was not meant to be run on ARCompact (AKA ISAv1 cores like ARC600 & ARC700) instead targets were ARCv2 cores like ARC EM and ARC HS. Unfortunately I have no experience with embARC so adding more experienced person in the thread (Igor Guryanov) who may shed some light on interrupts in embARC.
-Alexey
On Sat, 2016-09-17 at 21:26 +0300, Michael Rolnik wrote:
H Alexey.
Thanks.
I need some help in getting a small code that exercises interrupts. For several years I wrote FW for ARC based platforms (ARC4 & ARC6), but it seems I forgot some of the things related to interrupts. I compiled FreeRTOS demo from embARC, however I could not find interrupt vectors there, I assume their board has ROM.
So, if you can help me with such a code, it would be great.
thanks,
Michael
On Fri, Sep 16, 2016 at 6:01 PM, Alexey Brodkin <
[email protected]> wrote:Hi Michael,
Quoted 8 lines · Michael Rolnik
This series of patches adds ARC target to QEMU. It indends to support
- ARCtangent-A5 processor
- ARC 600 processor
- ARC 700 processorAll instructions except ASLS are implemented. Not fully tested yet. However I was able to execute correctly recursive fibonacci calculation. Reset vector is assumed to be some hardcoded value which worked for my
test.
Quoted 1 line
I am planning to get FreeRTOS for ARC, once I get it, I will able to
verify
Quoted 1 line
and complete interrupt support.
That's both very unexpected and cool!
I tried your patches on top of current QEMU git master and it:
a) Builds for ARC
b) Very simple code really works!I was able to single-step with GDB through program as simple as:
--------------------->8---------------------
.global_start_start:mov r0, 1 mov r1, 2 mov r1, r0--------------------->8---------------------
That's what I saw in GDB:
--------------------->8---------------------
(gdb) disassemble
Dump of assembler code for function_start:=> 0x00000100 <+0>: mov r0,0x1 0x00000104 <+4>: mov r1,0x2 0x00000108 <+8>: mov r1,r0End of assembler dump.
(gdb) p $r0
$1 = 0
(gdb) stepi0x00000104in_start()
(gdb) p $r0
$2 = 1
(gdb) stepi0x00000108in_start()
(gdb) p $r1
$3 = 2
(gdb) stepi0x0000010cin ?? ()
(gdb) p $r1
$4 = 1
--------------------->8---------------------So again this is very promising even though a lot is essentially missing from
this very first implementation.Anyways IMHO it would be good to have these patches accepted so people may start
playing with that stuff adding missing things one by one.Let me know if you need any help from my side.
Regards,
Alexey--
Best Regards,
Michael Rolnik
Signature · 2 lines
Best Regards, Michael Rolnik