Skip to content

Commit

Permalink
improve performance of the Ingenic SoCs
Browse files Browse the repository at this point in the history
With these patches GCC is able to use XBurst specific instructions LXW,
LXH[U] and LXB[U] to improve performance and reduce code size.

WARNING: the patches doesn't introduce new machine as they shall, thus
using these patches outside of this repo is a risk. However, it allows
to not change any compilation flags in dependent packages to achieve the
goal.

By my observations they can improve performance for about 4% when all
system and apps are rebuilt with improved GCC. Binaries size reduced for
about 1%.

Signed-off-by: Siarhei Volkau <[email protected]>
  • Loading branch information
SiarheiVolkau authored and pcercuei committed Sep 21, 2022
1 parent e11cbbc commit b7b803b
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
From 47fca730a675d8314a434b4c357cdb6726512b1f Mon Sep 17 00:00:00 2001
From: Siarhei Volkau <[email protected]>
Date: Thu, 1 Sep 2022 10:14:34 +0300
Subject: [PATCH] add support of ingenic lx<whb><u> instructions

This is a quick and dirty patch which adds useful ingenic instructions
and unconditionally enables them for any mips32 CPU, this is useful
for testing purposes as no need to explicitly change build flags
in any package where it needed, but of course resulting binaries will
not work on machines other than Ingenic XBurst ones.
You have beed warned.

NOTE: use it in conjunction with corresponding GCC patch.

Signed-off-by: Siarhei Volkau <[email protected]>
---
opcodes/mips-opc.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index db72c039..d0f837b0 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -96,6 +96,7 @@ decode_mips_operand (const char *p)
case 'V': INT_ADJ (10, 16, 511, 2, false); /* (-512 .. 511) << 2 */
case 'W': INT_ADJ (10, 16, 511, 3, false); /* (-512 .. 511) << 3 */
case 'X': BIT (5, 16, 32); /* (32 .. 63) */
+ case 'Y': UINT (2, 9); /* (MXU STRD2) */
case 'Z': REG (5, 0, FP);

case 'a': SINT (8, 6);
@@ -1342,6 +1343,11 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"lwu", "t,A(b)", 0, (int) M_LWU_AB, INSN_MACRO, 0, I3, 0, 0 },
{"lwxc1", "D,t(b)", 0x4c000000, 0xfc00f83f, WR_1|RD_2|RD_3|LM|FP_S, 0, I4_33, 0, I37 },
{"lwxs", "d,t(b)", 0x70000088, 0xfc0007ff, WR_1|RD_2|RD_3|LM, 0, 0, SMT, 0 },
+{"lxw", "d,s,t,+Y", 0x700000e8, 0xfc0001ff, WR_1|RD_2|RD_3|LM, 0, I32, 0, 0 },
+{"lxh", "d,s,t,+Y", 0x70000068, 0xfc0001ff, WR_1|RD_2|RD_3|LM, 0, I32, 0, 0 },
+{"lxhu", "d,s,t,+Y", 0x70000168, 0xfc0001ff, WR_1|RD_2|RD_3|LM, 0, I32, 0, 0 },
+{"lxb", "d,s,t,+Y", 0x70000028, 0xfc0001ff, WR_1|RD_2|RD_3|LM, 0, I32, 0, 0 },
+{"lxbu", "d,s,t,+Y", 0x70000128, 0xfc0001ff, WR_1|RD_2|RD_3|LM, 0, I32, 0, 0 },
{"macc", "d,s,t", 0x00000028, 0xfc0007ff, WR_1|RD_2|RD_3|WR_HILO, 0, N412, 0, 0 },
{"macc", "d,s,t", 0x00000158, 0xfc0007ff, WR_1|RD_2|RD_3|WR_HILO, 0, N5, 0, 0 },
{"maccs", "d,s,t", 0x00000428, 0xfc0007ff, WR_1|RD_2|RD_3|WR_HILO, 0, N412, 0, 0 },
--
2.36.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
From 799df4affeaab3dff911378af7988ad072d60730 Mon Sep 17 00:00:00 2001
From: Siarhei Volkau <[email protected]>
Date: Thu, 1 Sep 2022 10:19:49 +0300
Subject: [PATCH] add support for ingenic mips lx<whb><u> instructions

This is a quick and dirty patch which adds useful ingenic instructions
and unconditionally enables them for any mips32 CPU, this is useful
for testing purposes as no need to explicitly change build flags
in any package where it needed, but of course resulting binaries will
not work on machines other than Ingenic XBurst ones.
You have beed warned.

NOTE: use it in conjunction with corresponding binutils/GAS patch.

Signed-off-by: Siarhei Volkau <[email protected]>
---
gcc/config/mips/mips-dsp.md | 49 +++++++++++++++++++++++++++++++++++++
gcc/config/mips/mips.c | 29 ++++++++++++++++++++--
2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md
index 5a5694f3f..6a9cfd000 100644
--- a/gcc/config/mips/mips-dsp.md
+++ b/gcc/config/mips/mips-dsp.md
@@ -1124,6 +1124,55 @@
DONE;
})

+
+;; Ingenic STRD2 shift modes
+(define_int_iterator STRD2 [(1 "") (2 "") (4 "")])
+(define_int_attr strd2_shift [(1 "0") (2 "1") (4 "2")])
+
+(define_insn "*ingenic_lxw_scale<STRD2:strd2_shift>_extsi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mem:SI (plus:SI
+ (mult:SI (match_operand:SI 1 "register_operand" "d") (const_int STRD2))
+ (match_operand:SI 2 "register_operand" "d")
+ )))]
+ "!TARGET_64BIT && !TARGET_MIPS16"
+ "lxw\t%0,%2,%1,<STRD2:strd2_shift>"
+ [(set_attr "type" "load")
+ (set_attr "mode" "SI")])
+
+(define_insn "*ingenic_lxw_noscale_extsi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mem:SI (plus:SI
+ (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d")
+ )))]
+ "!TARGET_64BIT && !TARGET_MIPS16"
+ "lxw\t%0,%2,%1,0"
+ [(set_attr "type" "load")
+ (set_attr "mode" "SI")])
+
+(define_insn "*ingenic_lx<SHORT:size><u>_scale<STRD2:strd2_shift>_extsi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (any_extend:SI (mem:SHORT (plus:SI
+ (mult:SI (match_operand:SI 1 "register_operand" "d") (const_int STRD2))
+ (match_operand:SI 2 "register_operand" "d")
+ ))))]
+ "!TARGET_64BIT && !TARGET_MIPS16"
+ "lx<SHORT:size><u>\t%0,%2,%1,<STRD2:strd2_shift>"
+ [(set_attr "type" "load")
+ (set_attr "mode" "<SHORT:MODE>")])
+
+(define_insn "*ingenic_lx<SHORT:size><u>_noscale_extsi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (any_extend:SI (mem:SHORT (plus:SI
+ (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d")
+ ))))]
+ "!TARGET_64BIT && !TARGET_MIPS16"
+ "lx<SHORT:size><u>\t%0,%2,%1,0"
+ [(set_attr "type" "load")
+ (set_attr "mode" "<SHORT:MODE>")])
+
(define_insn "mips_l<GPR:size>x_<P:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(mem:GPR (plus:P (match_operand:P 1 "register_operand" "d")
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 315545966..33843d810 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2673,7 +2673,31 @@ mips_lx_address_p (rtx addr, machine_mode mode)
return true;
return false;
}
-
+
+static bool
+ingenic_lx_address_p (rtx addr, machine_mode mode)
+{
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 1)))
+ {
+ rtx offset = XEXP (addr, 0);
+ if (REG_P (offset))
+ return true;
+ else if (GET_CODE (offset) == MULT
+ && REG_P (XEXP (offset, 0))
+ && CONST_INT_P (XEXP (offset, 1))) {
+ if (INTVAL (XEXP (offset, 1)) == 4 || INTVAL (XEXP (offset, 1)) == 2)
+ return true;
+ }/* else if (GET_CODE (offset) == ASHIFT
+ && REG_P (XEXP (offset, 0))
+ && CONST_INT_P (XEXP (offset, 1))) {
+ if (INTVAL (XEXP (offset, 1)) == 2 || INTVAL (XEXP (offset, 1)) == 1)
+ return true;
+ }*/
+ }
+ return false;
+}
+
/* Return true if a value at OFFSET bytes from base register BASE can be
accessed using an unextended MIPS16 instruction. MODE is the mode of
the value.
@@ -4197,7 +4221,8 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
}
/* Check for a scaled indexed address. */
if (mips_lwxs_address_p (addr)
- || mips_lx_address_p (addr, mode))
+ || mips_lx_address_p (addr, mode)
+ || ingenic_lx_address_p(addr, mode))
{
*total = COSTS_N_INSNS (2);
return true;
--
2.36.1

0 comments on commit b7b803b

Please sign in to comment.