Re: [Qemu-devel] [PATCH] target/i386: Fix BLSR and BLSI
Hi Richard, I cannot find this patch on qemu master branch. Do you need any help to get this done? Thanks! On Wed, Jul 12, 2017 at 8:45 PM Richard Henderson wrote: > > The implementation of these two instructions was swapped. > At the same time, unify the setup of eflags for the insn group. > > Reported-by: Ricardo Ribalda Delgado > Signed-off-by: Richard Henderson > --- > target/i386/translate.c | 25 - > 1 file changed, 8 insertions(+), 17 deletions(-) > > diff --git a/target/i386/translate.c b/target/i386/translate.c > index 8365a6d..087a2e6 100644 > --- a/target/i386/translate.c > +++ b/target/i386/translate.c > @@ -4029,36 +4029,27 @@ static void gen_sse(CPUX86State *env, DisasContext > *s, int b, > goto illegal_op; > } > ot = mo_64_32(s->dflag); > -gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); > +gen_ldst_modrm(env, s, modrm, ot, OR_TMP1, 0); > > switch (reg & 7) { > case 1: /* blsr By,Ey */ > -tcg_gen_neg_tl(cpu_T1, cpu_T0); > +tcg_gen_subi_tl(cpu_T0, cpu_T1, 1); > tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); > gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); > -gen_op_update2_cc(); > -set_cc_op(s, CC_OP_BMILGB + ot); > break; > - > case 2: /* blsmsk By,Ey */ > -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); > -tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src); > -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > -set_cc_op(s, CC_OP_BMILGB + ot); > +tcg_gen_subi_tl(cpu_T0, cpu_T1, 1); > +tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1); > break; > - > case 3: /* blsi By, Ey */ > -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); > -tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src); > -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > -set_cc_op(s, CC_OP_BMILGB + ot); > +tcg_gen_neg_tl(cpu_T0, cpu_T1); > +tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); > break; > - > default: > goto unknown_op; > } > +gen_op_update2_cc(); > +set_cc_op(s, CC_OP_BMILGB + ot); > break; > > default: > -- > 2.9.4 > -- Ricardo Ribalda
[Qemu-devel] Different feature status
Hi I am missing the following functionality to fully emulate an AMD bulldozer v4: -mno-avx -mno-avx2 -mno-f16c -mno-fma -mno-fma4 -mno-prfchw -mno-rdrnd -mno-xop I was wondering if there is any documentation with the features that are planned to be implemented, and who is implementing them. (Google is not my friend today) I might work on implementing some of those and I do not want to step into anyones foot, or redo work. Thanks! -- Ricardo Ribalda
Re: [Qemu-devel] [PATCH v2] target/i386: Fix BLSR and BLSI
Hi For completion. This is my poor man tbm test. It has run for 5 minutes with no errors gcc tbm.c -O3 -march=native -o pc gcc tbm.c -mtbm -O3 for a in $(seq 0 65535); do /tmp/qemu/x86_64-linux-user/qemu-x86_64 -cpu qemu64,+tbm ./a.out $a >/tmp/res.qemu ; ./pc $a > /tmp/res.pc ; if ! diff /tmp/res.pc /tmp/res.qemu; then echo $a ; fi ; done #include #include #include long test_bextr(long src) { unsigned char start =1, len=3; return (src >> start) & ((1 << len)-1); } long test_blcfill(long val){ return val & (val + 1); } long test_blci(long val){ return val | ~(val + 1); } long test_blcic(long val){ return ~val & (val + 1); } long test_blcmsk(long val){ return val ^ (val + 1); } long test_blcs(long val){ return val | (val + 1); } long test_blsfill(long val){ return val | (val - 1); } long test_blsic(long val){ return ~val | (val - 1); } long test_t1mskc(long val){ return ~val | (val + 1); } long test_tzmsk(long val){ return ~val & (val - 1); } int main(int argc, char *argv[]) { long op1; long ret; if (argc < 2) { fprintf(stderr, "use %s op1 \n", argv[0]); return -1; } op1 = strtoul(argv[1], NULL, 0); fprintf(stdout, "op 1 %ld (0x%lx)\n", op1, op1); ret = test_bextr(op1); fprintf(stdout, "bextr %ld (0x%lx)\n",ret, ret); ret = test_blcfill(op1); fprintf(stdout, "blcfill %ld (0x%lx)\n",ret, ret); ret = test_blci(op1); fprintf(stdout, "blci %ld (0x%lx)\n",ret, ret); ret = test_blcic(op1); fprintf(stdout, "blcic %ld (0x%lx)\n",ret, ret); ret = test_blcmsk(op1); fprintf(stdout, "blcmsk %ld (0x%lx)\n",ret, ret); ret = test_blcs(op1); fprintf(stdout, "blcs %ld (0x%lx)\n",ret, ret); ret = test_blsfill(op1); fprintf(stdout, "blsfill %ld (0x%lx)\n",ret, ret); ret = test_blsic(op1); fprintf(stdout, "blsic %ld (0x%lx)\n",ret, ret); ret = test_t1mskc(op1); fprintf(stdout, "t1mskc %ld (0x%lx)\n",ret, ret); ret = test_tzmsk(op1); fprintf(stdout, "tzmsk %ld (0x%lx)\n",ret, ret); return 0; } On Thu, Jul 13, 2017 at 11:55 PM, Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> wrote: > Hi again > > Some progress here, I think that I have found a bug in andn, I have > already send a patch. > > I have made a rudimentary testcase for bmi. I will try tomorrow o > build something similar for tbm. > > For reference, I am using this script: > > for a in $(seq 0 255); do for b in $(seq 0 255); do for c in $(seq 0 > 255); do /tmp/qemu/x86_64-linux-user/qemu-x86_64 -cpu qemu64,+bmi1 > ./a.out $a $b $c >/tmp/res.qemu; ./pc $a $b $c > /tmp/res.pc; if ! > diff /tmp/res.pc /tmp/res.qemu; then echo $a $b $c; fi ; done ; done > ; done > > with this build options > gcc kk.c -mbmi -O3 -Wall > gcc kk.c -march=native -O3 -Wall -o pc > > and this code: > > #include > #include > #include > > > long test_blsr(long val){ > > return (val & (val - 1)); > } > > long test_blsi(long val){ > > return (val & (-val)); > } > > long test_blmsk(long val){ > > return (val ^ (val -1)); > } > > long test_andn(long v1, long v2){ > > return (~v1 & v2); > } > > long test_tzcnt(long val) { > #ifdef PC > return val ? __builtin_ctz(val) : 32; > #else > return __tzcnt_u32(val); > #endif > } > > long test_bextr(long src, unsigned char start, unsigned char len) { > #ifdef PC > return (src >> start) & ((1 << len)-1); > #else > return __bextr_u32(src, start | len <<8); > #endif > } > > int main(int argc, char *argv[]) { > long op1, op2, op3; > long ret; > > if (argc < 4) { > fprintf(stderr, "use %s op1 op2 op3\n", argv[0]); > return -1; > } > op1 = strtoul(argv[1], NULL, 0); > op2 = strtoul(argv[2], NULL, 0); > op3 = strtoul(argv[3], NULL, 0); > > fprintf(stdout, "op 1 %ld (0x%lx)\n", op1, op1); > fprintf(stdout, "op 2 %ld (0x%lx)\n", op2, op2); > > ret = test_blsr(op1); > fprintf(stdout, "blsr %ld (0x%lx)\n",ret, ret); > > ret = test_blsi(op1); > fprintf(stdout, "blsi %ld (0x%lx)\n",ret, ret); > > ret = test_blmsk(op1); > fprintf(stdout, "blmsk %ld (0x%lx)\n",ret, ret); > > ret = test_andn(op1,op2); > fprintf(stdout, "andn %ld (0x%lx)\n",ret, ret); > > ret = test_tzcnt(op1); > fprintf(stdout, "tzcnt %ld (0x%lx)\n",ret, ret); > > ret = test_bextr(op1, op2, op3); > fprintf(stdout, "bextr %ld (0x%lx)\n",ret, ret); > > return 0; > } > > On Thu, Jul 13, 2017 at 10:42 PM, Ricardo Ribalda Delgado > <ricardo.riba...@gmail.com> wrote: >> Hi Richard >> >> The simple example works as expected, but my big application
Re: [Qemu-devel] [PATCH v2] target/i386: Fix BLSR and BLSI
Hi again Some progress here, I think that I have found a bug in andn, I have already send a patch. I have made a rudimentary testcase for bmi. I will try tomorrow o build something similar for tbm. For reference, I am using this script: for a in $(seq 0 255); do for b in $(seq 0 255); do for c in $(seq 0 255); do /tmp/qemu/x86_64-linux-user/qemu-x86_64 -cpu qemu64,+bmi1 ./a.out $a $b $c >/tmp/res.qemu; ./pc $a $b $c > /tmp/res.pc; if ! diff /tmp/res.pc /tmp/res.qemu; then echo $a $b $c; fi ; done ; done ; done with this build options gcc kk.c -mbmi -O3 -Wall gcc kk.c -march=native -O3 -Wall -o pc and this code: #include #include #include long test_blsr(long val){ return (val & (val - 1)); } long test_blsi(long val){ return (val & (-val)); } long test_blmsk(long val){ return (val ^ (val -1)); } long test_andn(long v1, long v2){ return (~v1 & v2); } long test_tzcnt(long val) { #ifdef PC return val ? __builtin_ctz(val) : 32; #else return __tzcnt_u32(val); #endif } long test_bextr(long src, unsigned char start, unsigned char len) { #ifdef PC return (src >> start) & ((1 << len)-1); #else return __bextr_u32(src, start | len <<8); #endif } int main(int argc, char *argv[]) { long op1, op2, op3; long ret; if (argc < 4) { fprintf(stderr, "use %s op1 op2 op3\n", argv[0]); return -1; } op1 = strtoul(argv[1], NULL, 0); op2 = strtoul(argv[2], NULL, 0); op3 = strtoul(argv[3], NULL, 0); fprintf(stdout, "op 1 %ld (0x%lx)\n", op1, op1); fprintf(stdout, "op 2 %ld (0x%lx)\n", op2, op2); ret = test_blsr(op1); fprintf(stdout, "blsr %ld (0x%lx)\n",ret, ret); ret = test_blsi(op1); fprintf(stdout, "blsi %ld (0x%lx)\n",ret, ret); ret = test_blmsk(op1); fprintf(stdout, "blmsk %ld (0x%lx)\n",ret, ret); ret = test_andn(op1,op2); fprintf(stdout, "andn %ld (0x%lx)\n",ret, ret); ret = test_tzcnt(op1); fprintf(stdout, "tzcnt %ld (0x%lx)\n",ret, ret); ret = test_bextr(op1, op2, op3); fprintf(stdout, "bextr %ld (0x%lx)\n",ret, ret); return 0; } On Thu, Jul 13, 2017 at 10:42 PM, Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> wrote: > Hi Richard > > The simple example works as expected, but my big application > (gobject-introspection) still crashes with sigsegv :(. > > it seems to be something related to the bmi and tbm instructions. If I > disable them in gcc ( -mno-bmi -mno-tbm), the application > runs ok. > > A look at qemu's code does not show anything obvious, but I am not > that familiar with qemu source yet to find something like this through > static analysis. > > My plan (as soon as I have some time) is to create a small set of apps > to validate bmi/tbm/ (Are you aware of something already existing for > this?) > My stupid guess is that maybe the ops are switched, or the flags are > not properly modified. > > If you want, I can share the application that crashes with you, just > be aware that the number of dependencies is considerable. > > BTW I can only run the gdb stub on version 2.8.0. On git HEAD I am getting > only: > > Quit > (gdb) c > Continuing. > warning: Remote failure reply: E22 > > Program stopped. > 0x0040017bac07 in ?? () > (gdb) c > Continuing. > > > > Thanks for your help, it is greatly appreciated! > > On Wed, Jul 12, 2017 at 9:29 PM, Richard Henderson <r...@twiddle.net> wrote: >> The implementation of these two instructions was swapped. >> At the same time, unify the setup of eflags for the insn group. >> >> Reported-by: Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> >> Signed-off-by: Richard Henderson <r...@twiddle.net> >> --- >> target/i386/translate.c | 26 +- >> 1 file changed, 9 insertions(+), 17 deletions(-) >> >> diff --git a/target/i386/translate.c b/target/i386/translate.c >> index 9d5f1c3..69d3787 100644 >> --- a/target/i386/translate.c >> +++ b/target/i386/translate.c >> @@ -4031,34 +4031,26 @@ static void gen_sse(CPUX86State *env, DisasContext >> *s, int b, >> ot = mo_64_32(s->dflag); >> gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); >> >> +tcg_gen_mov_tl(cpu_cc_src, cpu_T0); >> switch (reg & 7) { >> case 1: /* blsr By,Ey */ >> -tcg_gen_neg_tl(cpu_T1, cpu_T0); >> +tcg_gen_subi_tl(cpu_T1, cpu_T0, 1); >> tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); >> -gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); >> -gen_op_update2_cc(); >> -set_cc_op(s, CC_OP_BMILGB + ot); >> break;
[Qemu-devel] [PATCH] target/i386: Fix ANDN (bmi)
Operands on ANDN are swapped. Tested with the following function: long test_andn(long v1, long v2){ return (~v1 & v2); } Compiled with: gcc kk.c -mbmi -O3 -Wall 0910 : 910:c4 e2 c0 f2 c6 andn %rsi,%rdi,%rax 915:c3 retq 916:66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 91d:00 00 00 and gcc kk.c -march=native -O3 -Wall 0930 : 930: 48 f7 d7not%rdi 933: 48 89 f8mov%rdi,%rax 936: 48 21 f0and%rsi,%rax 939: c3 retq 93a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) The test showed than -mbmi version behaved differently than the -march native version. Signed-off-by: Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> --- target/i386/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/translate.c b/target/i386/translate.c index 203623ef884c..1f39b497c19a 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -3774,7 +3774,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); -tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0); +tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_regs[s->vex_v]); gen_op_mov_reg_v(ot, reg, cpu_T0); gen_op_update1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); -- 2.13.2
Re: [Qemu-devel] [PATCH v2] target/i386: Fix BLSR and BLSI
Hi Richard The simple example works as expected, but my big application (gobject-introspection) still crashes with sigsegv :(. it seems to be something related to the bmi and tbm instructions. If I disable them in gcc ( -mno-bmi -mno-tbm), the application runs ok. A look at qemu's code does not show anything obvious, but I am not that familiar with qemu source yet to find something like this through static analysis. My plan (as soon as I have some time) is to create a small set of apps to validate bmi/tbm/ (Are you aware of something already existing for this?) My stupid guess is that maybe the ops are switched, or the flags are not properly modified. If you want, I can share the application that crashes with you, just be aware that the number of dependencies is considerable. BTW I can only run the gdb stub on version 2.8.0. On git HEAD I am getting only: Quit (gdb) c Continuing. warning: Remote failure reply: E22 Program stopped. 0x0040017bac07 in ?? () (gdb) c Continuing. Thanks for your help, it is greatly appreciated! On Wed, Jul 12, 2017 at 9:29 PM, Richard Henderson <r...@twiddle.net> wrote: > The implementation of these two instructions was swapped. > At the same time, unify the setup of eflags for the insn group. > > Reported-by: Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> > Signed-off-by: Richard Henderson <r...@twiddle.net> > --- > target/i386/translate.c | 26 +- > 1 file changed, 9 insertions(+), 17 deletions(-) > > diff --git a/target/i386/translate.c b/target/i386/translate.c > index 9d5f1c3..69d3787 100644 > --- a/target/i386/translate.c > +++ b/target/i386/translate.c > @@ -4031,34 +4031,26 @@ static void gen_sse(CPUX86State *env, DisasContext > *s, int b, > ot = mo_64_32(s->dflag); > gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); > > +tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > switch (reg & 7) { > case 1: /* blsr By,Ey */ > -tcg_gen_neg_tl(cpu_T1, cpu_T0); > +tcg_gen_subi_tl(cpu_T1, cpu_T0, 1); > tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); > -gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); > -gen_op_update2_cc(); > -set_cc_op(s, CC_OP_BMILGB + ot); > break; > - > case 2: /* blsmsk By,Ey */ > -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); > -tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src); > -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > -set_cc_op(s, CC_OP_BMILGB + ot); > +tcg_gen_subi_tl(cpu_T1, cpu_T0, 1); > +tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1); > break; > - > case 3: /* blsi By, Ey */ > -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); > -tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src); > -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > -set_cc_op(s, CC_OP_BMILGB + ot); > +tcg_gen_neg_tl(cpu_T1, cpu_T0); > +tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); > break; > - > default: > goto unknown_op; > } > +tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > +gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); > +set_cc_op(s, CC_OP_BMILGB + ot); > break; > > default: > -- > 2.9.4 > -- Ricardo Ribalda
Re: [Qemu-devel] [PATCH] target/i386: Fix BLSR and BLSI
This seems to work fine with the example. But my app still throughs sigsegv :( diff --git a/target/i386/translate.c b/target/i386/translate.c index 2c64d2b71ec4..564b9c6057c2 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -4033,32 +4033,23 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, switch (reg & 7) { case 1: /* blsr By,Ey */ -tcg_gen_neg_tl(cpu_T1, cpu_T0); +tcg_gen_subi_tl(cpu_T1, cpu_T0, 1); tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); -gen_op_update2_cc(); -set_cc_op(s, CC_OP_BMILGB + ot); break; - case 2: /* blsmsk By,Ey */ -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); -tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src); -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); -set_cc_op(s, CC_OP_BMILGB + ot); +tcg_gen_subi_tl(cpu_T1, cpu_T0, 1); +tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1); break; - case 3: /* blsi By, Ey */ -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); -tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src); -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); -set_cc_op(s, CC_OP_BMILGB + ot); +tcg_gen_neg_tl(cpu_T1, cpu_T0); +tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); break; - default: goto unknown_op; } +gen_op_update2_cc(); +set_cc_op(s, CC_OP_BMILGB + ot); break; default: On Wed, Jul 12, 2017 at 9:12 PM, Richard Henderson <r...@twiddle.net> wrote: > On 07/12/2017 08:58 AM, Ricardo Ribalda Delgado wrote: >> >> Hi Richard >> >> Thanks again!, When I apply this patch I get the following error: >> >> /tmp/qemu/tcg/tcg.c:2042: tcg fatal error > > > Bah. I misremembered that OR_TMP1 is unusable in this context. > > > r~ -- Ricardo Ribalda
Re: [Qemu-devel] [PATCH] target/i386: Fix BLSR and BLSI
Hi Richard Thanks again!, When I apply this patch I get the following error: /tmp/qemu/tcg/tcg.c:2042: tcg fatal error Regards! On Wed, Jul 12, 2017 at 8:45 PM, Richard Henderson <r...@twiddle.net> wrote: > The implementation of these two instructions was swapped. > At the same time, unify the setup of eflags for the insn group. > > Reported-by: Ricardo Ribalda Delgado <ricardo.riba...@gmail.com> > Signed-off-by: Richard Henderson <r...@twiddle.net> > --- > target/i386/translate.c | 25 - > 1 file changed, 8 insertions(+), 17 deletions(-) > > diff --git a/target/i386/translate.c b/target/i386/translate.c > index 8365a6d..087a2e6 100644 > --- a/target/i386/translate.c > +++ b/target/i386/translate.c > @@ -4029,36 +4029,27 @@ static void gen_sse(CPUX86State *env, DisasContext > *s, int b, > goto illegal_op; > } > ot = mo_64_32(s->dflag); > -gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); > +gen_ldst_modrm(env, s, modrm, ot, OR_TMP1, 0); > > switch (reg & 7) { > case 1: /* blsr By,Ey */ > -tcg_gen_neg_tl(cpu_T1, cpu_T0); > +tcg_gen_subi_tl(cpu_T0, cpu_T1, 1); > tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); > gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); > -gen_op_update2_cc(); > -set_cc_op(s, CC_OP_BMILGB + ot); > break; > - > case 2: /* blsmsk By,Ey */ > -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); > -tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src); > -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > -set_cc_op(s, CC_OP_BMILGB + ot); > +tcg_gen_subi_tl(cpu_T0, cpu_T1, 1); > +tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1); > break; > - > case 3: /* blsi By, Ey */ > -tcg_gen_mov_tl(cpu_cc_src, cpu_T0); > -tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); > -tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src); > -tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); > -set_cc_op(s, CC_OP_BMILGB + ot); > +tcg_gen_neg_tl(cpu_T0, cpu_T1); > +tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); > break; > - > default: > goto unknown_op; > } > +gen_op_update2_cc(); > +set_cc_op(s, CC_OP_BMILGB + ot); > break; > > default: > -- > 2.9.4 > -- Ricardo Ribalda
Re: [Qemu-devel] [PATCH 0/2] target/i386: Implement all TBM instructions
Hi Richard Thanks for your patch! I have applied it to my tree, but i still get SIGSEGV. I think that I might have found the problem. It seems to be related to the bmi instruction blsr, which seems to be not properly implemented. On this example: #include int test_blsr(int val){ return (val & (val - 1)); } int main(int argc, char *argv) { volatile int val = 4096; fprintf(stdout, "%d\n", test_blsr(val)); return 0; } When it is compiled with -march=bdver4 -static -O3 test_blsr , the compiler produces: 00400af0 : 400af0: c4 e2 78 f3 cf blsr %edi,%eax 400af5: c3 retq 400af6: 66 2e 0f 1f 84 00 00nopw %cs:0x0(%rax,%rax,1) 400afd: 00 00 00 If I run the emulator: /tmp/qemu/x86_64-linux-user/qemu-x86_64 -cpu Haswell ./a.out The function prints 4096 A fast look in the code shows that https://github.com/qemu/qemu/blob/master/target/i386/translate.c#L4028 does not really match https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI1_.28Bit_Manipulation_Instruction_Set_1.29 It appears that case 1 and case 3 are swapped. I tried to fix it, but with no results :(. Anyway, the wiki could also be wrong. What is sure is that the code produces different results on qemu than on the target, which is not good Thanks again for your help! On Wed, Jul 12, 2017 at 6:04 AM, Richard Hendersonwrote: > On 07/11/2017 11:21 AM, Richard Henderson wrote: >> >> I am in the process of trying to run the gcc testsuite with -mtbm, >> with and without the patchset, to see (1) if the new insns get used >> and (2) that they run ok. > > > FWIW, make check-gcc RUNTESTFLAGS='--target_board=unix/-mtbm execute.exp' > shows 204 failures on a host that does not support TBM, so the extension is > being used. A browse through exactly one of these used only bextr. Running > the same tests with dejagnu using qemu-x86_64 -cpu qemu64,+tbm shows zero > failures. > > > r~ -- Ricardo Ribalda
Re: [Qemu-devel] qemu-x86_64: Error processing bextr
n is LES or LDS. */ +break; +} +s->pc++; + +/* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */ +if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ +| PREFIX_LOCK | PREFIX_DATA)) { +goto illegal_op; +} +#ifdef TARGET_X86_64 +if (x86_64_hregs) { +goto illegal_op; +} +#endif +#ifdef TARGET_X86_64 +s->rex_x = (~vex2 >> 3) & 8; +s->rex_b = (~vex2 >> 2) & 8; +#endif +vex3 = cpu_ldub_code(env, s->pc++); +rex_w = (vex3 >> 7) & 1; +if ((vex2 & 0x1f) != 0xA) + goto unknown_op; +b = 0x138; +s->vex_v = (~vex3 >> 3) & 0xf; +s->vex_l = (vex3 >> 2) & 1; +prefixes |= pp_prefix[vex3 & 3] | PREFIX_XOP; + } + fprintf(stderr, "XOP end!\n"); +break; } /* Post-process prefixes. */ On Tue, Jul 11, 2017 at 1:54 AM, Richard Henderson <r...@twiddle.net> wrote: > On 07/10/2017 01:17 PM, Ricardo Ribalda Delgado wrote: >> >> 0x0040008179bf <+31>: 8f ea 78 10 d0 08 04 00 00 bextr >> $0x408,%eax,%edx > > ... >> >> It seems that, bextr is not supported by the emulator/cpu, althoug I >> have launched the emualtor with -cpu Haswell, that should support bmi1 >> (https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI1) > > > This is not the BMI1 version of bextr, it's the TBM version of bextr. > > https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#TBM_.28Trailing_Bit_Manipulation.29 > > TBM is not implemented in qemu yet. > > > r~ -- Ricardo Ribalda
[Qemu-devel] qemu-x86_64: Error processing bextr
Hi I have the following assembly snipset (from get_common_indeces in glibc compiled with gcc 6.3 -march=bdver4) 0x0040008179b3 <+19>: 89 15 8b c3 20 00 mov %edx,0x20c38b(%rip)# 0x4000a23d44 <_rtld_local_ro+132> 0x0040008179b9 <+25>: 89 1d 7d c3 20 00 mov %ebx,0x20c37d(%rip)# 0x4000a23d3c <_rtld_local_ro+124> 0x0040008179bf <+31>: 8f ea 78 10 d0 08 04 00 00 bextr $0x408,%eax,%edx 0x0040008179c8 <+40>: 89 0d 72 c3 20 00 mov %ecx,0x20c372(%rip)# 0x4000a23d40 <_rtld_local_ro+128> 0x0040008179ce <+46>: 89 05 64 c3 20 00 mov %eax,0x20c364(%rip)# 0x4000a23d38 <_rtld_local_ro+120> When I run the application using qemu-x86-64, the instruction bextr is not understood by the emulator and results in a SIGSEGV, because it runs: 0x0040008179b9: mov%ebx,0x20c37d(%rip)# 0x4000a23d3c 0x0040008179bf: (bad) 0x0040008179c0: (bad) 0x0040008179c1: js 0x40008179d3 0x0040008179c3: rorb (%rax) It seems that, bextr is not supported by the emulator/cpu, althoug I have launched the emualtor with -cpu Haswell, that should support bmi1 (https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI1) What am I doing wrong? Thanks! cc: Richard Henderson and Blue Swril, that Implemented BEXTR -- Ricardo Ribalda
[Qemu-devel] Re: [PATCH] Elo touchpad 10 bytes emulator v2
Hello Juan Thanks for your comments. About the indentation error... Do you have some kind of auto indent script(like the kernel code has). It is making me crazy trying to collaborate with a lot of projects an all of them with different styles. +#include stdlib.h +#include ../qemu-common.h +#include ../qemu-char.h +#include ../console.h You can remove the ../ from those, Makefile sets correct include paths for this to work. Ok. I used the mssmouse.c as reference. I can change that. (I guess that I should also replace with ) + /*Move event*/ + if (is_downbuttons_state){ + bytes[2]=0x2; Can we use some constant from that bytes[2] values? 0x1, 0x2 and 0x4 don't look specially descriptive. ok Why does the lenght of the FIFO changes here? I think this change in independent of the rest of the patch (no knowledge about the 16550A to know if it should be 16 or 32). I have to send a 2x10 bytes package, and it does not fit the the 16 bytes buffer Any other suggestion about how to do it? Later, Juan. Thanks again for your comments -- Ricardo Ribalda http://www.eps.uam.es/~rribalda/
[Qemu-devel] [PATCH] Elo touchpad 10 bytes emulator v3
From: Ricardo Ribalda Delgado ricardo.riba...@uam.es New char device emulating an Elo serial touchpad. v2: -Emulate id packages (linux recognizes the hw) -Limit output to 96-4000 (thanks to Dmitry Zhurikhin) v3: -Output buffer (thanks to Juan Quintela) -Code Style --- Makefile.objs |2 +- hw/elo.c| 189 +++ hw/elo.h|2 + qemu-char.c |3 + qemu-options.hx |5 +- 5 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 hw/elo.c create mode 100644 hw/elo.h diff --git a/Makefile.objs b/Makefile.objs index b73e2cb..07c2e68 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -75,7 +75,7 @@ common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o u common-obj-y += bt-hci-csr.o common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o common-obj-y += qemu-char.o savevm.o #aio.o -common-obj-y += msmouse.o ps2.o +common-obj-y += msmouse.o ps2.o elo.o common-obj-y += qdev.o qdev-properties.o common-obj-y += qemu-config.o block-migration.o diff --git a/hw/elo.c b/hw/elo.c new file mode 100644 index 000..d5b4124 --- /dev/null +++ b/hw/elo.c @@ -0,0 +1,189 @@ +/* + * QEMU ELO Touchpad via serial port + * + * Copyright (c) 2010 Ricardo Ribalda: QTechnology http://qtec.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include stdlib.h +#include qemu-common.h +#include qemu-char.h +#include console.h +#include elo.h + +#define ELO_DOWN 0x1 +#define ELO_MOVE 0x2 +#define ELO_UP 0x4 +#define ELO_PACKET_SIZE 10 + +typedef struct { +CharDriverState chr; +uint8_t out_buf[ELO_PACKET_SIZE]; +uint8_t send_out; +} EloDriverState; + +static void elo_event(void *opaque, + int ax, int ay, int az, int buttons_state) +{ +EloDriverState *elo=(EloDriverState *)opaque; +CharDriverState *chr = elo-chr; +unsigned char bytes[ELO_PACKET_SIZE]; +static int is_down=0; +int old_ax=0,old_ay=0; +int i; + +/*A touchpad cannot capture flight events*/ +if ((!is_down)(!buttons_state)) +return; + +ax=(ax*(4000-96))/0x7fff; +ax+=96; +ay=(ay*(4000-96))/0x7fff; +ay+=96; + +/*Move event*/ +if (is_downbuttons_state){ +bytes[2]=ELO_MOVE; +is_down++; +if ((old_ay==ay)(old_ax==ax)) +return; +/*SDL move is much more precise than the real elo*/ +if (qemu_chr_can_read(chr)ELO_PACKET_SIZE) +return; +old_ay=ay; +old_ax=ax; +is_down++; +} + +/*Click*/ +if ((!is_down)buttons_state){ + bytes[2]=ELO_DOWN; + is_down=1; + old_ay=ay; + old_ax=ax; +} +/*Release*/ +if (is_down(!buttons_state)){ +bytes[2]=ELO_UP; +is_down=0; +} + +bytes[0]='U'; +bytes[1]='T'; +bytes[3]=ax0xff; +bytes[4]=(ax8)0xff; +bytes[5]=ay0xff; +bytes[6]=(ay8)0xff; +bytes[7]=0x0;/*No presure capabilities*/ +bytes[8]=0x0; +bytes[9]=0xaa; +for(i=0;i9;i++) +bytes[9]+=bytes[i]; + +qemu_chr_read(chr, bytes, ELO_PACKET_SIZE); +return; +} + +static int elo_chr_write(struct CharDriverState *s, const uint8_t *buf, int len) +{ +EloDriverState *elo=(EloDriverState *)s-opaque; +unsigned char bytes[ELO_PACKET_SIZE]; +static int in_cmd=0,i; + +if (buf[0]==0x55) +in_cmd=0; + +/*Only response to ID*/ +in_cmd+=len; +if (in_cmdELO_PACKET_SIZE) +return len; + +/* Only respond cmd ID This should be enough at least for linux*/ +/*Full ref at http://tge.cegep-baie-comeau.qc.ca/fichestech/References/Elo%20Touch%20Screen/smartset/pages/chapter_6.htm#command_descriptions*/ +/*ID*/ +in_cmd=0; +bytes[0]='U'; +bytes[1]='I'; +bytes[2]='0';/*Accu*/ +bytes[3]='0';/*Serial*/ +bytes[4]=0;/*No features*/ +bytes[5]=1; +bytes[6]=2
[Qemu-devel] Re: [PATCH] Elo touchpad 10 bytes emulator v2
Hello Juan New patch is on the mail. It misses a SOB line. Sorry, I don't understand what you mean here, do you mean the sing off? You can remove the ../ from those, Makefile sets correct include paths for this to work. Done + /*Move event*/ + if (is_downbuttons_state){ + bytes[2]=0x2; Can we use some constant from that bytes[2] values? 0x1, 0x2 and 0x4 don't look specially descriptive. Done Why does the lenght of the FIFO changes here? I think this change in independent of the rest of the patch (no knowledge about the 16550A to know if it should be 16 or 32). Fixed using qemu_chr_can_read(). Thanks for your help! Later, Juan. Hope this time the patch is better. Regards -- Ricardo Ribalda http://www.eps.uam.es/~rribalda/
[Qemu-devel] [PATCH] Elo touchpad 10 bytes emulator v2
New char device emulating an Elo serial touchpad. -Emulate id and touch packets -Absolute Output limited to 96-4000 --- Makefile.objs |2 +- hw/elo.c| 153 +++ hw/elo.h|2 + hw/serial.c |2 +- qemu-char.c |3 + qemu-options.hx |5 ++- 6 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 hw/elo.c create mode 100644 hw/elo.h diff --git a/Makefile.objs b/Makefile.objs index b73e2cb..07c2e68 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -75,7 +75,7 @@ common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o u common-obj-y += bt-hci-csr.o common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o common-obj-y += qemu-char.o savevm.o #aio.o -common-obj-y += msmouse.o ps2.o +common-obj-y += msmouse.o ps2.o elo.o common-obj-y += qdev.o qdev-properties.o common-obj-y += qemu-config.o block-migration.o diff --git a/hw/elo.c b/hw/elo.c new file mode 100644 index 000..359333d --- /dev/null +++ b/hw/elo.c @@ -0,0 +1,153 @@ +/* + * QEMU ELO Touchpad via serial port + * + * Copyright (c) 2010 Ricardo Ribalda: QTechnology http://qtec.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include stdlib.h +#include ../qemu-common.h +#include ../qemu-char.h +#include ../console.h +#include elo.h + +static void elo_event(void *opaque, + int ax, int ay, int az, int buttons_state) +{ +CharDriverState *chr = (CharDriverState *)opaque; + +unsigned char bytes[10]; +static int is_down=0; +int old_ax=0,old_ay=0; +int i; + +/*A touchpad cannot capture flight events*/ +if ((!is_down)(!buttons_state)) + return; + +ax=(ax*(4000-96+1))/0x7fff; +ax+=96; +ay=(ay*(4000-96+1))/0x7fff; +ay+=96; + +/*Move event*/ +if (is_downbuttons_state){ + bytes[2]=0x2; + is_down++; + if ((old_ay==ay)(old_ax==ax)) + return; + old_ay=ay; + old_ax=ax; +} + +/*Click*/ +if ((!is_down)buttons_state){ + bytes[2]=0x1; + is_down=1; + old_ay=ay; + old_ax=ax; +} +/*Release*/ +if (is_down(!buttons_state)){ + bytes[2]=0x4; + is_down=0; +} + +bytes[0]='U'; +bytes[1]='T'; +bytes[3]=ax0xff; +bytes[4]=(ax8)0xff; +bytes[5]=ay0xff; +bytes[6]=(ay8)0xff; +bytes[7]=0x0;/*No presure capabilities*/ +bytes[8]=0x0; +bytes[9]=0xaa; +for(i=0;i9;i++) + bytes[9]+=bytes[i]; + +qemu_chr_read(chr, bytes, 10); +} + +static int elo_chr_write (struct CharDriverState *s, const uint8_t *buf, int len) +{ +unsigned char bytes[10]; +static int in_cmd=0,i; + +if (buf[0]==0x55) + in_cmd=0; + +/*Only response to ID*/ +in_cmd+=len; +if (in_cmd10) + return len; + +/* Only respond cmd ID This should be enough at least for linux*/ +/*Full ref at http://tge.cegep-baie-comeau.qc.ca/fichestech/References/Elo%20Touch%20Screen/smartset/pages/chapter_6.htm#command_descriptions*/ +/*ID*/ +in_cmd=0; +bytes[0]='U'; +bytes[1]='I'; +bytes[2]='0';/*Accu*/ +bytes[3]='0';/*Serial*/ +bytes[4]=0;/*No features*/ +bytes[5]=1; +bytes[6]=2; +bytes[7]=1;/*1 response*/ +bytes[8]=0xe; +bytes[9]=0xaa; +for(i=0;i9;i++) + bytes[9]+=bytes[i]; +qemu_chr_read(s, bytes, 10); + +/*ACK no err*/ +in_cmd=0; +bytes[0]='U'; +bytes[1]='A'; +bytes[2]='0'; +bytes[3]='0'; +bytes[4]='0'; +bytes[5]=0; +bytes[6]=0; +bytes[7]=0; +bytes[8]=0; +bytes[9]=0xaa; +for(i=0;i9;i++) + bytes[9]+=bytes[i]; +qemu_chr_read(s, bytes, 10); +in_cmd=0; +return len; +} + +static void elo_chr_close (struct CharDriverState *chr) +{ +qemu_free (chr); +} + +CharDriverState
Re: [Qemu-devel] [PATCH] Elo touchpad 10 bytes emulator
Hello Paul Hmmm, you are right, it should be part of the calibration (userland). As Dmtry says, the output from the chip should be from 96-4000. I have fixed the max values to that. The previous code was done to emulate an old privative app that uses an elo touchscreen. I managed to reverse engineer the code and found the 10 bytes protocol it was using. It also uses a privative library to talk with the touchscreen. Digging in the kernel, I found more of the protocol specification, and digging a little bit more in the internet I have found even more information. Please take a look to the last patch and tell me what do you think Best regards and thanks for your comments. On Mon, Mar 29, 2010 at 17:57, Paul Brook p...@codesourcery.com wrote: New char device emulating an Elo serial touchpad. TODO: The output of the touchpad should be in the range of the resolution. But I don't know a clean way to get the screen resolution. Any help will be very wellcomed Are you sure? I don't see how real hardware would be able to do that. Paul -- Ricardo Ribalda http://www.eps.uam.es/~rribalda/