Lines 597-628
int main(int argc, char **argv)
Link Here
|
597 |
printf("skipped\n"); |
597 |
printf("skipped\n"); |
598 |
#endif |
598 |
#endif |
599 |
|
599 |
|
600 |
#define decl_insn(which) extern const unsigned char which[], which##_len[] |
|
|
601 |
#define put_insn(which, insn) ".pushsection .test, \"ax\", @progbits\n" \ |
602 |
#which ": " insn "\n" \ |
603 |
".equ " #which "_len, .-" #which "\n" \ |
604 |
".popsection" |
605 |
#define set_insn(which) (regs.eip = (unsigned long)memcpy(instr, which, \ |
606 |
(unsigned long)which##_len)) |
607 |
#define check_eip(which) (regs.eip == (unsigned long)instr + \ |
608 |
(unsigned long)which##_len) |
609 |
|
610 |
printf("%-40s", "Testing movq %mm3,(%ecx)..."); |
600 |
printf("%-40s", "Testing movq %mm3,(%ecx)..."); |
611 |
if ( stack_exec && cpu_has_mmx ) |
601 |
if ( stack_exec && cpu_has_mmx ) |
612 |
{ |
602 |
{ |
613 |
decl_insn(movq_to_mem); |
603 |
extern const unsigned char movq_to_mem[]; |
614 |
|
604 |
|
615 |
asm volatile ( "pcmpeqb %%mm3, %%mm3\n" |
605 |
asm volatile ( "pcmpeqb %%mm3, %%mm3\n" |
616 |
put_insn(movq_to_mem, "movq %%mm3, (%0)") |
606 |
".pushsection .test, \"a\", @progbits\n" |
617 |
:: "c" (NULL) ); |
607 |
"movq_to_mem: movq %%mm3, (%0)\n" |
|
|
608 |
".popsection" :: "c" (NULL) ); |
618 |
|
609 |
|
619 |
set_insn(movq_to_mem); |
610 |
memcpy(instr, movq_to_mem, 15); |
620 |
memset(res, 0x33, 64); |
611 |
memset(res, 0x33, 64); |
621 |
memset(res + 8, 0xff, 8); |
612 |
memset(res + 8, 0xff, 8); |
|
|
613 |
regs.eip = (unsigned long)&instr[0]; |
622 |
regs.ecx = (unsigned long)res; |
614 |
regs.ecx = (unsigned long)res; |
623 |
rc = x86_emulate(&ctxt, &emulops); |
615 |
rc = x86_emulate(&ctxt, &emulops); |
624 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) || |
616 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ) |
625 |
!check_eip(movq_to_mem) ) |
|
|
626 |
goto fail; |
617 |
goto fail; |
627 |
printf("okay\n"); |
618 |
printf("okay\n"); |
628 |
} |
619 |
} |
Lines 632-648
int main(int argc, char **argv)
Link Here
|
632 |
printf("%-40s", "Testing movq (%edx),%mm5..."); |
623 |
printf("%-40s", "Testing movq (%edx),%mm5..."); |
633 |
if ( stack_exec && cpu_has_mmx ) |
624 |
if ( stack_exec && cpu_has_mmx ) |
634 |
{ |
625 |
{ |
635 |
decl_insn(movq_from_mem); |
626 |
extern const unsigned char movq_from_mem[]; |
636 |
|
627 |
|
637 |
asm volatile ( "pcmpgtb %%mm5, %%mm5\n" |
628 |
asm volatile ( "pcmpgtb %%mm5, %%mm5\n" |
638 |
put_insn(movq_from_mem, "movq (%0), %%mm5") |
629 |
".pushsection .test, \"a\", @progbits\n" |
639 |
:: "d" (NULL) ); |
630 |
"movq_from_mem: movq (%0), %%mm5\n" |
|
|
631 |
".popsection" :: "d" (NULL) ); |
640 |
|
632 |
|
641 |
set_insn(movq_from_mem); |
633 |
memcpy(instr, movq_from_mem, 15); |
|
|
634 |
regs.eip = (unsigned long)&instr[0]; |
642 |
regs.ecx = 0; |
635 |
regs.ecx = 0; |
643 |
regs.edx = (unsigned long)res; |
636 |
regs.edx = (unsigned long)res; |
644 |
rc = x86_emulate(&ctxt, &emulops); |
637 |
rc = x86_emulate(&ctxt, &emulops); |
645 |
if ( rc != X86EMUL_OKAY || !check_eip(movq_from_mem) ) |
638 |
if ( rc != X86EMUL_OKAY ) |
646 |
goto fail; |
639 |
goto fail; |
647 |
asm ( "pcmpeqb %%mm3, %%mm3\n\t" |
640 |
asm ( "pcmpeqb %%mm3, %%mm3\n\t" |
648 |
"pcmpeqb %%mm5, %%mm3\n\t" |
641 |
"pcmpeqb %%mm5, %%mm3\n\t" |
Lines 657-675
int main(int argc, char **argv)
Link Here
|
657 |
printf("%-40s", "Testing movdqu %xmm2,(%ecx)..."); |
650 |
printf("%-40s", "Testing movdqu %xmm2,(%ecx)..."); |
658 |
if ( stack_exec && cpu_has_sse2 ) |
651 |
if ( stack_exec && cpu_has_sse2 ) |
659 |
{ |
652 |
{ |
660 |
decl_insn(movdqu_to_mem); |
653 |
extern const unsigned char movdqu_to_mem[]; |
661 |
|
654 |
|
662 |
asm volatile ( "pcmpeqb %%xmm2, %%xmm2\n" |
655 |
asm volatile ( "pcmpeqb %%xmm2, %%xmm2\n" |
663 |
put_insn(movdqu_to_mem, "movdqu %%xmm2, (%0)") |
656 |
".pushsection .test, \"a\", @progbits\n" |
664 |
:: "c" (NULL) ); |
657 |
"movdqu_to_mem: movdqu %%xmm2, (%0)\n" |
|
|
658 |
".popsection" :: "c" (NULL) ); |
665 |
|
659 |
|
666 |
set_insn(movdqu_to_mem); |
660 |
memcpy(instr, movdqu_to_mem, 15); |
667 |
memset(res, 0x55, 64); |
661 |
memset(res, 0x55, 64); |
668 |
memset(res + 8, 0xff, 16); |
662 |
memset(res + 8, 0xff, 16); |
|
|
663 |
regs.eip = (unsigned long)&instr[0]; |
669 |
regs.ecx = (unsigned long)res; |
664 |
regs.ecx = (unsigned long)res; |
670 |
rc = x86_emulate(&ctxt, &emulops); |
665 |
rc = x86_emulate(&ctxt, &emulops); |
671 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) || |
666 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ) |
672 |
!check_eip(movdqu_to_mem) ) |
|
|
673 |
goto fail; |
667 |
goto fail; |
674 |
printf("okay\n"); |
668 |
printf("okay\n"); |
675 |
} |
669 |
} |
Lines 679-695
int main(int argc, char **argv)
Link Here
|
679 |
printf("%-40s", "Testing movdqu (%edx),%xmm4..."); |
673 |
printf("%-40s", "Testing movdqu (%edx),%xmm4..."); |
680 |
if ( stack_exec && cpu_has_sse2 ) |
674 |
if ( stack_exec && cpu_has_sse2 ) |
681 |
{ |
675 |
{ |
682 |
decl_insn(movdqu_from_mem); |
676 |
extern const unsigned char movdqu_from_mem[]; |
683 |
|
677 |
|
684 |
asm volatile ( "pcmpgtb %%xmm4, %%xmm4\n" |
678 |
asm volatile ( "pcmpgtb %%xmm4, %%xmm4\n" |
685 |
put_insn(movdqu_from_mem, "movdqu (%0), %%xmm4") |
679 |
".pushsection .test, \"a\", @progbits\n" |
686 |
:: "d" (NULL) ); |
680 |
"movdqu_from_mem: movdqu (%0), %%xmm4\n" |
|
|
681 |
".popsection" :: "d" (NULL) ); |
687 |
|
682 |
|
688 |
set_insn(movdqu_from_mem); |
683 |
memcpy(instr, movdqu_from_mem, 15); |
|
|
684 |
regs.eip = (unsigned long)&instr[0]; |
689 |
regs.ecx = 0; |
685 |
regs.ecx = 0; |
690 |
regs.edx = (unsigned long)res; |
686 |
regs.edx = (unsigned long)res; |
691 |
rc = x86_emulate(&ctxt, &emulops); |
687 |
rc = x86_emulate(&ctxt, &emulops); |
692 |
if ( rc != X86EMUL_OKAY || !check_eip(movdqu_from_mem) ) |
688 |
if ( rc != X86EMUL_OKAY ) |
693 |
goto fail; |
689 |
goto fail; |
694 |
asm ( "pcmpeqb %%xmm2, %%xmm2\n\t" |
690 |
asm ( "pcmpeqb %%xmm2, %%xmm2\n\t" |
695 |
"pcmpeqb %%xmm4, %%xmm2\n\t" |
691 |
"pcmpeqb %%xmm4, %%xmm2\n\t" |
Lines 704-723
int main(int argc, char **argv)
Link Here
|
704 |
printf("%-40s", "Testing vmovdqu %ymm2,(%ecx)..."); |
700 |
printf("%-40s", "Testing vmovdqu %ymm2,(%ecx)..."); |
705 |
if ( stack_exec && cpu_has_avx ) |
701 |
if ( stack_exec && cpu_has_avx ) |
706 |
{ |
702 |
{ |
707 |
decl_insn(vmovdqu_to_mem); |
703 |
extern const unsigned char vmovdqu_to_mem[]; |
708 |
|
704 |
|
709 |
asm volatile ( "vpcmpeqb %%xmm2, %%xmm2, %%xmm2\n" |
705 |
asm volatile ( "vpcmpeqb %%xmm2, %%xmm2, %%xmm2\n" |
710 |
put_insn(vmovdqu_to_mem, "vmovdqu %%ymm2, (%0)") |
706 |
".pushsection .test, \"a\", @progbits\n" |
711 |
:: "c" (NULL) ); |
707 |
"vmovdqu_to_mem: vmovdqu %%ymm2, (%0)\n" |
|
|
708 |
".popsection" :: "c" (NULL) ); |
712 |
|
709 |
|
713 |
set_insn(vmovdqu_to_mem); |
710 |
memcpy(instr, vmovdqu_to_mem, 15); |
714 |
memset(res, 0x55, 128); |
711 |
memset(res, 0x55, 128); |
715 |
memset(res + 16, 0xff, 16); |
712 |
memset(res + 16, 0xff, 16); |
716 |
memset(res + 20, 0x00, 16); |
713 |
memset(res + 20, 0x00, 16); |
|
|
714 |
regs.eip = (unsigned long)&instr[0]; |
717 |
regs.ecx = (unsigned long)res; |
715 |
regs.ecx = (unsigned long)res; |
718 |
rc = x86_emulate(&ctxt, &emulops); |
716 |
rc = x86_emulate(&ctxt, &emulops); |
719 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 16, 64) || |
717 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 16, 64) ) |
720 |
!check_eip(vmovdqu_to_mem) ) |
|
|
721 |
goto fail; |
718 |
goto fail; |
722 |
printf("okay\n"); |
719 |
printf("okay\n"); |
723 |
} |
720 |
} |
Lines 727-733
int main(int argc, char **argv)
Link Here
|
727 |
printf("%-40s", "Testing vmovdqu (%edx),%ymm4..."); |
724 |
printf("%-40s", "Testing vmovdqu (%edx),%ymm4..."); |
728 |
if ( stack_exec && cpu_has_avx ) |
725 |
if ( stack_exec && cpu_has_avx ) |
729 |
{ |
726 |
{ |
730 |
decl_insn(vmovdqu_from_mem); |
727 |
extern const unsigned char vmovdqu_from_mem[]; |
731 |
|
728 |
|
732 |
#if 0 /* Don't use AVX2 instructions for now */ |
729 |
#if 0 /* Don't use AVX2 instructions for now */ |
733 |
asm volatile ( "vpcmpgtb %%ymm4, %%ymm4, %%ymm4\n" |
730 |
asm volatile ( "vpcmpgtb %%ymm4, %%ymm4, %%ymm4\n" |
Lines 735-749
int main(int argc, char **argv)
Link Here
|
735 |
asm volatile ( "vpcmpgtb %%xmm4, %%xmm4, %%xmm4\n\t" |
732 |
asm volatile ( "vpcmpgtb %%xmm4, %%xmm4, %%xmm4\n\t" |
736 |
"vinsertf128 $1, %%xmm4, %%ymm4, %%ymm4\n" |
733 |
"vinsertf128 $1, %%xmm4, %%ymm4, %%ymm4\n" |
737 |
#endif |
734 |
#endif |
738 |
put_insn(vmovdqu_from_mem, "vmovdqu (%0), %%ymm4") |
735 |
".pushsection .test, \"a\", @progbits\n" |
739 |
:: "d" (NULL) ); |
736 |
"vmovdqu_from_mem: vmovdqu (%0), %%ymm4\n" |
|
|
737 |
".popsection" :: "d" (NULL) ); |
740 |
|
738 |
|
741 |
set_insn(vmovdqu_from_mem); |
739 |
memcpy(instr, vmovdqu_from_mem, 15); |
742 |
memset(res + 4, 0xff, 16); |
740 |
memset(res + 4, 0xff, 16); |
|
|
741 |
regs.eip = (unsigned long)&instr[0]; |
743 |
regs.ecx = 0; |
742 |
regs.ecx = 0; |
744 |
regs.edx = (unsigned long)res; |
743 |
regs.edx = (unsigned long)res; |
745 |
rc = x86_emulate(&ctxt, &emulops); |
744 |
rc = x86_emulate(&ctxt, &emulops); |
746 |
if ( rc != X86EMUL_OKAY || !check_eip(vmovdqu_from_mem) ) |
745 |
if ( rc != X86EMUL_OKAY ) |
747 |
goto fail; |
746 |
goto fail; |
748 |
#if 0 /* Don't use AVX2 instructions for now */ |
747 |
#if 0 /* Don't use AVX2 instructions for now */ |
749 |
asm ( "vpcmpeqb %%ymm2, %%ymm2, %%ymm2\n\t" |
748 |
asm ( "vpcmpeqb %%ymm2, %%ymm2, %%ymm2\n\t" |
Lines 770-788
int main(int argc, char **argv)
Link Here
|
770 |
memset(res + 10, 0x66, 8); |
769 |
memset(res + 10, 0x66, 8); |
771 |
if ( stack_exec && cpu_has_sse2 ) |
770 |
if ( stack_exec && cpu_has_sse2 ) |
772 |
{ |
771 |
{ |
773 |
decl_insn(movsd_to_mem); |
772 |
extern const unsigned char movsd_to_mem[]; |
774 |
|
773 |
|
775 |
asm volatile ( "movlpd %0, %%xmm5\n\t" |
774 |
asm volatile ( "movlpd %0, %%xmm5\n\t" |
776 |
"movhpd %0, %%xmm5\n" |
775 |
"movhpd %0, %%xmm5\n" |
777 |
put_insn(movsd_to_mem, "movsd %%xmm5, (%1)") |
776 |
".pushsection .test, \"a\", @progbits\n" |
778 |
:: "m" (res[10]), "c" (NULL) ); |
777 |
"movsd_to_mem: movsd %%xmm5, (%1)\n" |
|
|
778 |
".popsection" :: "m" (res[10]), "c" (NULL) ); |
779 |
|
779 |
|
780 |
set_insn(movsd_to_mem); |
780 |
memcpy(instr, movsd_to_mem, 15); |
|
|
781 |
regs.eip = (unsigned long)&instr[0]; |
781 |
regs.ecx = (unsigned long)(res + 2); |
782 |
regs.ecx = (unsigned long)(res + 2); |
782 |
regs.edx = 0; |
783 |
regs.edx = 0; |
783 |
rc = x86_emulate(&ctxt, &emulops); |
784 |
rc = x86_emulate(&ctxt, &emulops); |
784 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) || |
785 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ) |
785 |
!check_eip(movsd_to_mem) ) |
|
|
786 |
goto fail; |
786 |
goto fail; |
787 |
printf("okay\n"); |
787 |
printf("okay\n"); |
788 |
} |
788 |
} |
Lines 795-811
int main(int argc, char **argv)
Link Here
|
795 |
printf("%-40s", "Testing movaps (%edx),%xmm7..."); |
795 |
printf("%-40s", "Testing movaps (%edx),%xmm7..."); |
796 |
if ( stack_exec && cpu_has_sse ) |
796 |
if ( stack_exec && cpu_has_sse ) |
797 |
{ |
797 |
{ |
798 |
decl_insn(movaps_from_mem); |
798 |
extern const unsigned char movaps_from_mem[]; |
799 |
|
799 |
|
800 |
asm volatile ( "xorps %%xmm7, %%xmm7\n" |
800 |
asm volatile ( "xorps %%xmm7, %%xmm7\n" |
801 |
put_insn(movaps_from_mem, "movaps (%0), %%xmm7") |
801 |
".pushsection .test, \"a\", @progbits\n" |
802 |
:: "d" (NULL) ); |
802 |
"movaps_from_mem: movaps (%0), %%xmm7\n" |
|
|
803 |
".popsection" :: "d" (NULL) ); |
803 |
|
804 |
|
804 |
set_insn(movaps_from_mem); |
805 |
memcpy(instr, movaps_from_mem, 15); |
|
|
806 |
regs.eip = (unsigned long)&instr[0]; |
805 |
regs.ecx = 0; |
807 |
regs.ecx = 0; |
806 |
regs.edx = (unsigned long)res; |
808 |
regs.edx = (unsigned long)res; |
807 |
rc = x86_emulate(&ctxt, &emulops); |
809 |
rc = x86_emulate(&ctxt, &emulops); |
808 |
if ( rc != X86EMUL_OKAY || !check_eip(movaps_from_mem) ) |
810 |
if ( rc != X86EMUL_OKAY ) |
809 |
goto fail; |
811 |
goto fail; |
810 |
asm ( "cmpeqps %1, %%xmm7\n\t" |
812 |
asm ( "cmpeqps %1, %%xmm7\n\t" |
811 |
"movmskps %%xmm7, %0" : "=r" (rc) : "m" (res[8]) ); |
813 |
"movmskps %%xmm7, %0" : "=r" (rc) : "m" (res[8]) ); |
Lines 821-838
int main(int argc, char **argv)
Link Here
|
821 |
memset(res + 10, 0x77, 8); |
823 |
memset(res + 10, 0x77, 8); |
822 |
if ( stack_exec && cpu_has_avx ) |
824 |
if ( stack_exec && cpu_has_avx ) |
823 |
{ |
825 |
{ |
824 |
decl_insn(vmovsd_to_mem); |
826 |
extern const unsigned char vmovsd_to_mem[]; |
825 |
|
827 |
|
826 |
asm volatile ( "vbroadcastsd %0, %%ymm5\n" |
828 |
asm volatile ( "vbroadcastsd %0, %%ymm5\n" |
827 |
put_insn(vmovsd_to_mem, "vmovsd %%xmm5, (%1)") |
829 |
".pushsection .test, \"a\", @progbits\n" |
828 |
:: "m" (res[10]), "c" (NULL) ); |
830 |
"vmovsd_to_mem: vmovsd %%xmm5, (%1)\n" |
|
|
831 |
".popsection" :: "m" (res[10]), "c" (NULL) ); |
829 |
|
832 |
|
830 |
set_insn(vmovsd_to_mem); |
833 |
memcpy(instr, vmovsd_to_mem, 15); |
|
|
834 |
regs.eip = (unsigned long)&instr[0]; |
831 |
regs.ecx = (unsigned long)(res + 2); |
835 |
regs.ecx = (unsigned long)(res + 2); |
832 |
regs.edx = 0; |
836 |
regs.edx = 0; |
833 |
rc = x86_emulate(&ctxt, &emulops); |
837 |
rc = x86_emulate(&ctxt, &emulops); |
834 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) || |
838 |
if ( (rc != X86EMUL_OKAY) || memcmp(res, res + 8, 32) ) |
835 |
!check_eip(vmovsd_to_mem) ) |
|
|
836 |
goto fail; |
839 |
goto fail; |
837 |
printf("okay\n"); |
840 |
printf("okay\n"); |
838 |
} |
841 |
} |
Lines 845-861
int main(int argc, char **argv)
Link Here
|
845 |
printf("%-40s", "Testing vmovaps (%edx),%ymm7..."); |
848 |
printf("%-40s", "Testing vmovaps (%edx),%ymm7..."); |
846 |
if ( stack_exec && cpu_has_avx ) |
849 |
if ( stack_exec && cpu_has_avx ) |
847 |
{ |
850 |
{ |
848 |
decl_insn(vmovaps_from_mem); |
851 |
extern const unsigned char vmovaps_from_mem[]; |
849 |
|
852 |
|
850 |
asm volatile ( "vxorps %%ymm7, %%ymm7, %%ymm7\n" |
853 |
asm volatile ( "vxorps %%ymm7, %%ymm7, %%ymm7\n" |
851 |
put_insn(vmovaps_from_mem, "vmovaps (%0), %%ymm7") |
854 |
".pushsection .test, \"a\", @progbits\n" |
852 |
:: "d" (NULL) ); |
855 |
"vmovaps_from_mem: vmovaps (%0), %%ymm7\n" |
|
|
856 |
".popsection" :: "d" (NULL) ); |
853 |
|
857 |
|
854 |
set_insn(vmovaps_from_mem); |
858 |
memcpy(instr, vmovaps_from_mem, 15); |
|
|
859 |
regs.eip = (unsigned long)&instr[0]; |
855 |
regs.ecx = 0; |
860 |
regs.ecx = 0; |
856 |
regs.edx = (unsigned long)res; |
861 |
regs.edx = (unsigned long)res; |
857 |
rc = x86_emulate(&ctxt, &emulops); |
862 |
rc = x86_emulate(&ctxt, &emulops); |
858 |
if ( rc != X86EMUL_OKAY || !check_eip(vmovaps_from_mem) ) |
863 |
if ( rc != X86EMUL_OKAY ) |
859 |
goto fail; |
864 |
goto fail; |
860 |
asm ( "vcmpeqps %1, %%ymm7, %%ymm0\n\t" |
865 |
asm ( "vcmpeqps %1, %%ymm7, %%ymm0\n\t" |
861 |
"vmovmskps %%ymm0, %0" : "=r" (rc) : "m" (res[8]) ); |
866 |
"vmovmskps %%ymm0, %0" : "=r" (rc) : "m" (res[8]) ); |
Lines 866-876
int main(int argc, char **argv)
Link Here
|
866 |
else |
871 |
else |
867 |
printf("skipped\n"); |
872 |
printf("skipped\n"); |
868 |
|
873 |
|
869 |
#undef decl_insn |
|
|
870 |
#undef put_insn |
871 |
#undef set_insn |
872 |
#undef check_eip |
873 |
|
874 |
for ( j = 1; j <= 2; j++ ) |
874 |
for ( j = 1; j <= 2; j++ ) |
875 |
{ |
875 |
{ |
876 |
#if defined(__i386__) |
876 |
#if defined(__i386__) |