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 --- |