@samitouri / QOSamiQemu / commits / 0a35913d68

target/ppc: Move rlwimi, rlwinm instructions to decodetree

-Moving the following instructions to decodetree specification: rlwimi : M-form rlwimi. : M-form rlwinm : M-form rlwinm. : M-form The changes were verified by validating that the tcg ops generated by those instructions remain the same, which were captured with the "-d in_asm,op" flag. Additionally, validated using small assembly tests confirming the destination register is correctly updated based on rotated and masked source values and confirmed that the value was same before and after the change Signed-off-by: Tanushree Shah <tshah@linux.ibm.com> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Signed-off-by: Chinmay Rath <rathc@linux.ibm.com> Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com> Tested-by: Aniket Sahu <asahu1x@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260827133010.278889-26-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>

Tanushree Shah committed Aug 27, 2026 at 18:59 UTC 0a35913d6870a299c1fefee8bc25789c0bb30730
3 files changed +108 -106
target/ppc/insn32.decode
+6
@@ -312,6 +312,9 @@
312
313 @Z23_te_tbp ...... ....0 te:5 ....0 rmc:2 ........ rc:1 &Z23_te_tb frt=%z23_frtp frb=%z23_frbp
314
315 +&M ra rs sh mb me rc:bool
316 +@M ...... rs:5 ra:5 sh:5 mb:5 me:5 rc:1 &M
317 +
318 ### Fixed-Point Load Instructions
319
320 LBZ 100010 ..... ..... ................ @D
@@ -561,6 +564,9 @@ SRADI 011111 ..... ..... ..... 110011101 . . @XS
564
565 EXTSWSLI 011111 ..... ..... ..... 110111101 . . @XS
566
567 +RLWIMI 010100 ..... ..... ..... ..... ...... @M
568 +RLWINM 010101 ..... ..... ..... ..... ...... @M
569 +
570 ## BCD Assist
571
572 ADDG6S 011111 ..... ..... ..... - 001001010 - @X
target/ppc/translate.c
-106
@@ -2012,110 +2012,6 @@ static void gen_pause(DisasContext *ctx)
2012
2013 /*** Integer rotate ***/
2014
2015 -/* rlwimi & rlwimi. */
2016 -static void gen_rlwimi(DisasContext *ctx)
2017 -{
2018 - TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2019 - TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2020 - uint32_t sh = SH(ctx->opcode);
2021 - uint32_t mb = MB(ctx->opcode);
2022 - uint32_t me = ME(ctx->opcode);
2023 -
2024 - if (sh == (31 - me) && mb <= me) {
2025 - tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
2026 - } else {
2027 - target_ulong mask;
2028 - bool mask_in_32b = true;
2029 - TCGv t1;
2030 -
2031 -#if defined(TARGET_PPC64)
2032 - mb += 32;
2033 - me += 32;
2034 -#endif
2035 - mask = MASK(mb, me);
2036 -
2037 -#if defined(TARGET_PPC64)
2038 - if (mask > 0xffffffffu) {
2039 - mask_in_32b = false;
2040 - }
2041 -#endif
2042 - t1 = tcg_temp_new();
2043 - if (mask_in_32b) {
2044 - TCGv_i32 t0 = tcg_temp_new_i32();
2045 - tcg_gen_trunc_tl_i32(t0, t_rs);
2046 - tcg_gen_rotli_i32(t0, t0, sh);
2047 - tcg_gen_extu_i32_tl(t1, t0);
2048 - } else {
2049 -#if defined(TARGET_PPC64)
2050 - tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
2051 - tcg_gen_rotli_i64(t1, t1, sh);
2052 -#else
2053 - g_assert_not_reached();
2054 -#endif
2055 - }
2056 -
2057 - tcg_gen_andi_tl(t1, t1, mask);
2058 - tcg_gen_andi_tl(t_ra, t_ra, ~mask);
2059 - tcg_gen_or_tl(t_ra, t_ra, t1);
2060 - }
2061 - if (unlikely(Rc(ctx->opcode) != 0)) {
2062 - gen_set_Rc0(ctx, t_ra);
2063 - }
2064 -}
2065 -
2066 -/* rlwinm & rlwinm. */
2067 -static void gen_rlwinm(DisasContext *ctx)
2068 -{
2069 - TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2070 - TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2071 - int sh = SH(ctx->opcode);
2072 - int mb = MB(ctx->opcode);
2073 - int me = ME(ctx->opcode);
2074 - int len = me - mb + 1;
2075 - int rsh = (32 - sh) & 31;
2076 -
2077 - if (sh != 0 && len > 0 && me == (31 - sh)) {
2078 - tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len);
2079 - } else if (me == 31 && rsh + len <= 32) {
2080 - tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
2081 - } else {
2082 - target_ulong mask;
2083 - bool mask_in_32b = true;
2084 -#if defined(TARGET_PPC64)
2085 - mb += 32;
2086 - me += 32;
2087 -#endif
2088 - mask = MASK(mb, me);
2089 -#if defined(TARGET_PPC64)
2090 - if (mask > 0xffffffffu) {
2091 - mask_in_32b = false;
2092 - }
2093 -#endif
2094 - if (mask_in_32b) {
2095 - if (sh == 0) {
2096 - tcg_gen_andi_tl(t_ra, t_rs, mask);
2097 - } else {
2098 - TCGv_i32 t0 = tcg_temp_new_i32();
2099 - tcg_gen_trunc_tl_i32(t0, t_rs);
2100 - tcg_gen_rotli_i32(t0, t0, sh);
2101 - tcg_gen_andi_i32(t0, t0, mask);
2102 - tcg_gen_extu_i32_tl(t_ra, t0);
2103 - }
2104 - } else {
2105 -#if defined(TARGET_PPC64)
2106 - tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
2107 - tcg_gen_rotli_i64(t_ra, t_ra, sh);
2108 - tcg_gen_andi_i64(t_ra, t_ra, mask);
2109 -#else
2110 - g_assert_not_reached();
2111 -#endif
2112 - }
2113 - }
2114 - if (unlikely(Rc(ctx->opcode) != 0)) {
2115 - gen_set_Rc0(ctx, t_ra);
2116 - }
2117 -}
2118 -
2015 /* rlwnm & rlwnm. */
2016 static void gen_rlwnm(DisasContext *ctx)
2017 {
@@ -4794,8 +4690,6 @@ GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
4690 GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300),
4691 GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
4692 GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300),
4797 -GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4798 -GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4693 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4694 /* handles lfdp, lxsd, lxssp */
4695 GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
target/ppc/translate/fixedpoint-impl.c.inc
+102
@@ -1872,6 +1872,108 @@ static bool trans_SRAWI(DisasContext *ctx, arg_SRAWI *a)
1872 return true;
1873 }
1874
1875 +static bool trans_RLWIMI(DisasContext *ctx, arg_RLWIMI *a)
1876 +{
1877 + TCGv t_ra = cpu_gpr[a->ra];
1878 + TCGv t_rs = cpu_gpr[a->rs];
1879 + int mb = a->mb;
1880 + int me = a->me;
1881 +
1882 + if (a->sh == (31 - me) && mb <= me) {
1883 + tcg_gen_deposit_tl(t_ra, t_ra, t_rs, a->sh, me - mb + 1);
1884 + } else {
1885 + target_ulong mask;
1886 + bool mask_in_32b = true;
1887 + TCGv t1;
1888 +
1889 +#if defined(TARGET_PPC64)
1890 + mb += 32;
1891 + me += 32;
1892 +#endif
1893 + mask = MASK(mb, me);
1894 +
1895 +#if defined(TARGET_PPC64)
1896 + if (mask > 0xffffffffu) {
1897 + mask_in_32b = false;
1898 + }
1899 +#endif
1900 + t1 = tcg_temp_new();
1901 + if (mask_in_32b) {
1902 + TCGv_i32 t0 = tcg_temp_new_i32();
1903 + tcg_gen_trunc_tl_i32(t0, t_rs);
1904 + tcg_gen_rotli_i32(t0, t0, a->sh);
1905 + tcg_gen_extu_i32_tl(t1, t0);
1906 + } else {
1907 +#if defined(TARGET_PPC64)
1908 + tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
1909 + tcg_gen_rotli_i64(t1, t1, a->sh);
1910 +#else
1911 + g_assert_not_reached();
1912 +#endif
1913 + }
1914 +
1915 + tcg_gen_andi_tl(t1, t1, mask);
1916 + tcg_gen_andi_tl(t_ra, t_ra, ~mask);
1917 + tcg_gen_or_tl(t_ra, t_ra, t1);
1918 + }
1919 + if (unlikely(a->rc)) {
1920 + gen_set_Rc0(ctx, t_ra);
1921 + }
1922 + return true;
1923 +}
1924 +
1925 +static bool trans_RLWINM(DisasContext *ctx, arg_RLWINM *a)
1926 +{
1927 + TCGv t_ra = cpu_gpr[a->ra];
1928 + TCGv t_rs = cpu_gpr[a->rs];
1929 + int me = a->me;
1930 + int mb = a->mb;
1931 + int len = me - mb + 1;
1932 + int rsh = (32 - a->sh) & 31;
1933 +
1934 + if (a->sh != 0 && len > 0 && me == (31 - a->sh)) {
1935 + tcg_gen_deposit_z_tl(t_ra, t_rs, a->sh, len);
1936 + } else if (me == 31 && rsh + len <= 32) {
1937 + tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
1938 + } else {
1939 + target_ulong mask;
1940 + bool mask_in_32b = true;
1941 +#if defined(TARGET_PPC64)
1942 + mb += 32;
1943 + me += 32;
1944 +#endif
1945 + mask = MASK(mb, me);
1946 +#if defined(TARGET_PPC64)
1947 + if (mask > 0xffffffffu) {
1948 + mask_in_32b = false;
1949 + }
1950 +#endif
1951 + if (mask_in_32b) {
1952 + if (a->sh == 0) {
1953 + tcg_gen_andi_tl(t_ra, t_rs, mask);
1954 + } else {
1955 + TCGv_i32 t0 = tcg_temp_new_i32();
1956 + tcg_gen_trunc_tl_i32(t0, t_rs);
1957 + tcg_gen_rotli_i32(t0, t0, a->sh);
1958 + tcg_gen_andi_i32(t0, t0, mask);
1959 + tcg_gen_extu_i32_tl(t_ra, t0);
1960 + }
1961 + } else {
1962 +#if defined(TARGET_PPC64)
1963 + tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
1964 + tcg_gen_rotli_i64(t_ra, t_ra, a->sh);
1965 + tcg_gen_andi_i64(t_ra, t_ra, mask);
1966 +#else
1967 + g_assert_not_reached();
1968 +#endif
1969 + }
1970 + }
1971 + if (unlikely(a->rc)) {
1972 + gen_set_Rc0(ctx, t_ra);
1973 + }
1974 + return true;
1975 +}
1976 +
1977 static void do_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
1978 TCGv EA, int rt,
1979 TCGCond cond, int addend)