emit.c.inc (aba2b8ecb90552cb347ac2e33557a3d475830ed4) emit.c.inc (7170a17ec3f29320dc66075cfea671013d4e2511)
1/*
2 * New-style TCG opcode generator for i386 instructions
3 *
4 * Copyright (c) 2022 Red Hat, Inc.
5 *
6 * Author: Paolo Bonzini <pbonzini@redhat.com>
7 *
8 * This library is free software; you can redistribute it and/or

--- 380 unchanged lines hidden (view full) ---

389 fn = s->prefix & PREFIX_DATA ? pd : ps;
390 }
391 if (fn) {
392 fn(cpu_env, OP_PTR0, OP_PTR1, OP_PTR2);
393 } else {
394 gen_illegal_opcode(s);
395 }
396}
1/*
2 * New-style TCG opcode generator for i386 instructions
3 *
4 * Copyright (c) 2022 Red Hat, Inc.
5 *
6 * Author: Paolo Bonzini <pbonzini@redhat.com>
7 *
8 * This library is free software; you can redistribute it and/or

--- 380 unchanged lines hidden (view full) ---

389 fn = s->prefix & PREFIX_DATA ? pd : ps;
390 }
391 if (fn) {
392 fn(cpu_env, OP_PTR0, OP_PTR1, OP_PTR2);
393 } else {
394 gen_illegal_opcode(s);
395 }
396}
397
397#define FP_SSE(uname, lname) \
398static void gen_##uname(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) \
399{ \
400 gen_fp_sse(s, env, decode, \
401 gen_helper_##lname##pd_xmm, \
402 gen_helper_##lname##ps_xmm, \
403 gen_helper_##lname##pd_ymm, \
404 gen_helper_##lname##ps_ymm, \
405 gen_helper_##lname##sd, \
406 gen_helper_##lname##ss); \
407}
408FP_SSE(VADD, add)
409FP_SSE(VMUL, mul)
410FP_SSE(VSUB, sub)
411FP_SSE(VMIN, min)
412FP_SSE(VDIV, div)
413FP_SSE(VMAX, max)
414
398#define FP_SSE(uname, lname) \
399static void gen_##uname(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) \
400{ \
401 gen_fp_sse(s, env, decode, \
402 gen_helper_##lname##pd_xmm, \
403 gen_helper_##lname##ps_xmm, \
404 gen_helper_##lname##pd_ymm, \
405 gen_helper_##lname##ps_ymm, \
406 gen_helper_##lname##sd, \
407 gen_helper_##lname##ss); \
408}
409FP_SSE(VADD, add)
410FP_SSE(VMUL, mul)
411FP_SSE(VSUB, sub)
412FP_SSE(VMIN, min)
413FP_SSE(VDIV, div)
414FP_SSE(VMAX, max)
415
416#define FP_UNPACK_SSE(uname, lname) \
417static void gen_##uname(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) \
418{ \
419 /* PS maps to the DQ integer instruction, PD maps to QDQ. */ \
420 gen_fp_sse(s, env, decode, \
421 gen_helper_##lname##qdq_xmm, \
422 gen_helper_##lname##dq_xmm, \
423 gen_helper_##lname##qdq_ymm, \
424 gen_helper_##lname##dq_ymm, \
425 NULL, NULL); \
426}
427FP_UNPACK_SSE(VUNPCKLPx, punpckl)
428FP_UNPACK_SSE(VUNPCKHPx, punpckh)
429
415/*
416 * 00 = v*ps Vps, Wpd
417 * f3 = v*ss Vss, Wps
418 */
419static inline void gen_unary_fp32_sse(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode,
420 SSEFunc_0_epp ps_xmm,
421 SSEFunc_0_epp ps_ymm,
422 SSEFunc_0_eppp ss)

--- 321 unchanged lines hidden (view full) ---

744
745UNARY_INT_SSE(VPMOVZXBW, pmovzxbw)
746UNARY_INT_SSE(VPMOVZXBD, pmovzxbd)
747UNARY_INT_SSE(VPMOVZXBQ, pmovzxbq)
748UNARY_INT_SSE(VPMOVZXWD, pmovzxwd)
749UNARY_INT_SSE(VPMOVZXWQ, pmovzxwq)
750UNARY_INT_SSE(VPMOVZXDQ, pmovzxdq)
751
430/*
431 * 00 = v*ps Vps, Wpd
432 * f3 = v*ss Vss, Wps
433 */
434static inline void gen_unary_fp32_sse(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode,
435 SSEFunc_0_epp ps_xmm,
436 SSEFunc_0_epp ps_ymm,
437 SSEFunc_0_eppp ss)

--- 321 unchanged lines hidden (view full) ---

759
760UNARY_INT_SSE(VPMOVZXBW, pmovzxbw)
761UNARY_INT_SSE(VPMOVZXBD, pmovzxbd)
762UNARY_INT_SSE(VPMOVZXBQ, pmovzxbq)
763UNARY_INT_SSE(VPMOVZXWD, pmovzxwd)
764UNARY_INT_SSE(VPMOVZXWQ, pmovzxwq)
765UNARY_INT_SSE(VPMOVZXDQ, pmovzxdq)
766
767UNARY_INT_SSE(VMOVSLDUP, pmovsldup)
768UNARY_INT_SSE(VMOVSHDUP, pmovshdup)
769UNARY_INT_SSE(VMOVDDUP, pmovdldup)
770
752UNARY_INT_SSE(VCVTDQ2PD, cvtdq2pd)
753UNARY_INT_SSE(VCVTPD2DQ, cvtpd2dq)
754UNARY_INT_SSE(VCVTTPD2DQ, cvttpd2dq)
755UNARY_INT_SSE(VCVTDQ2PS, cvtdq2ps)
756UNARY_INT_SSE(VCVTPS2DQ, cvtps2dq)
757UNARY_INT_SSE(VCVTTPS2DQ, cvttps2dq)
758
759

--- 1043 unchanged lines hidden (view full) ---

1803 gen_maskmov(s, env, decode, gen_helper_vpmaskmovq_st_xmm, gen_helper_vpmaskmovq_st_ymm);
1804}
1805
1806static void gen_VMASKMOVPS_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1807{
1808 gen_maskmov(s, env, decode, gen_helper_vpmaskmovd_st_xmm, gen_helper_vpmaskmovd_st_ymm);
1809}
1810
771UNARY_INT_SSE(VCVTDQ2PD, cvtdq2pd)
772UNARY_INT_SSE(VCVTPD2DQ, cvtpd2dq)
773UNARY_INT_SSE(VCVTTPD2DQ, cvttpd2dq)
774UNARY_INT_SSE(VCVTDQ2PS, cvtdq2ps)
775UNARY_INT_SSE(VCVTPS2DQ, cvtps2dq)
776UNARY_INT_SSE(VCVTTPS2DQ, cvttps2dq)
777
778

--- 1043 unchanged lines hidden (view full) ---

1822 gen_maskmov(s, env, decode, gen_helper_vpmaskmovq_st_xmm, gen_helper_vpmaskmovq_st_ymm);
1823}
1824
1825static void gen_VMASKMOVPS_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1826{
1827 gen_maskmov(s, env, decode, gen_helper_vpmaskmovd_st_xmm, gen_helper_vpmaskmovd_st_ymm);
1828}
1829
1830static void gen_VMOVHPx_ld(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1831{
1832 gen_ldq_env_A0(s, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
1833 if (decode->op[0].offset != decode->op[1].offset) {
1834 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
1835 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
1836 }
1837}
1838
1839static void gen_VMOVHPx_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1840{
1841 gen_stq_env_A0(s, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
1842}
1843
1844static void gen_VMOVHPx(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1845{
1846 if (decode->op[0].offset != decode->op[2].offset) {
1847 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
1848 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
1849 }
1850 if (decode->op[0].offset != decode->op[1].offset) {
1851 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
1852 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
1853 }
1854}
1855
1856static void gen_VMOVHLPS(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1857{
1858 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
1859 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
1860 if (decode->op[0].offset != decode->op[1].offset) {
1861 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(1)));
1862 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
1863 }
1864}
1865
1866static void gen_VMOVLHPS(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1867{
1868 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[2].offset);
1869 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
1870 if (decode->op[0].offset != decode->op[1].offset) {
1871 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
1872 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
1873 }
1874}
1875
1876/*
1877 * Note that MOVLPx supports 256-bit operation unlike MOVHLPx, MOVLHPx, MOXHPx.
1878 * Use a gvec move to move everything above the bottom 64 bits.
1879 */
1880
1881static void gen_VMOVLPx(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1882{
1883 int vec_len = vector_len(s, decode);
1884
1885 tcg_gen_ld_i64(s->tmp1_i64, cpu_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(0)));
1886 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
1887 tcg_gen_st_i64(s->tmp1_i64, cpu_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
1888}
1889
1890static void gen_VMOVLPx_ld(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1891{
1892 int vec_len = vector_len(s, decode);
1893
1894 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
1895 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
1896 tcg_gen_st_i64(s->tmp1_i64, OP_PTR0, offsetof(ZMMReg, ZMM_Q(0)));
1897}
1898
1899static void gen_VMOVLPx_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1900{
1901 tcg_gen_ld_i64(s->tmp1_i64, OP_PTR2, offsetof(ZMMReg, ZMM_Q(0)));
1902 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
1903}
1904
1905static void gen_VMOVSD_ld(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1906{
1907 TCGv_i64 zero = tcg_constant_i64(0);
1908
1909 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
1910 tcg_gen_st_i64(zero, OP_PTR0, offsetof(ZMMReg, ZMM_Q(1)));
1911 tcg_gen_st_i64(s->tmp1_i64, OP_PTR0, offsetof(ZMMReg, ZMM_Q(0)));
1912}
1913
1914static void gen_VMOVSS(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1915{
1916 int vec_len = vector_len(s, decode);
1917
1918 tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0)));
1919 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
1920 tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0)));
1921}
1922
1923static void gen_VMOVSS_ld(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1924{
1925 int vec_len = vector_len(s, decode);
1926
1927 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
1928 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
1929 tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0)));
1930}
1931
1932static void gen_VMOVSS_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1933{
1934 tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0)));
1935 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
1936}
1937
1811static void gen_VPMASKMOV_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1812{
1813 if (s->vex_w) {
1814 gen_VMASKMOVPD_st(s, env, decode);
1815 } else {
1816 gen_VMASKMOVPS_st(s, env, decode);
1817 }
1818}

--- 63 unchanged lines hidden ---
1938static void gen_VPMASKMOV_st(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
1939{
1940 if (s->vex_w) {
1941 gen_VMASKMOVPD_st(s, env, decode);
1942 } else {
1943 gen_VMASKMOVPS_st(s, env, decode);
1944 }
1945}

--- 63 unchanged lines hidden ---