mirror of
https://github.com/pret/agbcc.git
synced 2026-08-25 03:44:20 -05:00
Add -ftst flag for Thumb TST instruction generation
Add two new Thumb instruction patterns gated behind a -ftst flag, following the same mechanism as -fprologue-bugfix: *andsi3_tst: when the AND result is dead and only flags are needed, the combiner merges AND+CMP into a single TST instruction instead of emitting `and Rd, Rm; cmp Rd, #0`. *andsi3_setflags: when the AND result is live AND flags are needed, eliminates the redundant `cmp Rd, #0` after AND. In Thumb mode, AND always sets the CPSR flags, so the CMP is unnecessary. This is needed for matching decompilation of GBA games where the original SDK compiler emitted TST instructions that pret/agbcc does not generate. The flag is opt-in to avoid breaking existing matches in projects that rely on the AND+CMP sequence. Files changed: - gcc/thumb.md: Add *andsi3_tst and *andsi3_setflags patterns - gcc/thumb.h: Update comment acknowledging TST support - gcc/toplev.c: Register -ftst in f_options[] table - gcc/flags.h: Declare extern int flag_tst
This commit is contained in:
@@ -457,3 +457,6 @@ extern int flag_fixed_debug_line_info;
|
||||
|
||||
/* Nonzero if prologue bug should be fixed. */
|
||||
extern int flag_prologue_bugfix;
|
||||
|
||||
/* Nonzero if the TST instruction should be used instead of AND+CMP. */
|
||||
extern int flag_tst;
|
||||
|
||||
@@ -33,8 +33,8 @@ Boston, MA 02111-1307, USA. */
|
||||
reload. These should be eliminated if possible by tightening the
|
||||
predicates and/or constraints. This will give faster/smaller code. */
|
||||
|
||||
/* ??? There is no pattern for the TST instuction. Check for other unsupported
|
||||
instructions. */
|
||||
/* The TST instruction is emitted via the *andsi3_tst pattern in thumb.md.
|
||||
Check for other unsupported instructions. */
|
||||
|
||||
#define TARGET_VERSION fputs (" (ARM/THUMB:generic)", stderr);
|
||||
|
||||
|
||||
20
gcc/thumb.md
20
gcc/thumb.md
@@ -820,6 +820,26 @@
|
||||
""
|
||||
"cmp\\t%0, #0")
|
||||
|
||||
(define_insn "*andsi3_tst"
|
||||
[(set (cc0)
|
||||
(and:SI (match_operand:SI 0 "s_register_operand" "l")
|
||||
(match_operand:SI 1 "s_register_operand" "l")))]
|
||||
"flag_tst"
|
||||
"tst\\t%1, %0")
|
||||
|
||||
;; Thumb AND always sets flags. When the AND result is live AND flags are
|
||||
;; needed, the combiner produces a PARALLEL. This pattern eliminates the
|
||||
;; redundant cmp after and by using the implicit flag-setting of Thumb AND.
|
||||
(define_insn "*andsi3_setflags"
|
||||
[(parallel
|
||||
[(set (cc0)
|
||||
(and:SI (match_operand:SI 1 "s_register_operand" "%0")
|
||||
(match_operand:SI 2 "s_register_operand" "l")))
|
||||
(set (match_operand:SI 0 "s_register_operand" "=l")
|
||||
(and:SI (match_dup 1) (match_dup 2)))])]
|
||||
"flag_tst"
|
||||
"and\\t%0, %0, %2")
|
||||
|
||||
(define_insn "cmnsi"
|
||||
[(set (cc0) (compare (match_operand:SI 0 "s_register_operand" "l")
|
||||
(neg:SI (match_operand:SI 1 "s_register_operand" "l"))))]
|
||||
|
||||
@@ -591,6 +591,9 @@ int flag_fixed_debug_line_info = 0;
|
||||
/* Fix prologue bug in new compiler. */
|
||||
int flag_prologue_bugfix = 0;
|
||||
|
||||
/* Use TST instruction instead of AND+CMP for bitwise flag tests. */
|
||||
int flag_tst = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *string;
|
||||
@@ -739,6 +742,8 @@ lang_independent_options f_options[] =
|
||||
{"prologue-bugfix", &flag_prologue_bugfix, 1,
|
||||
"Prevent unnecessary saving of the lr register to the stack"},
|
||||
#endif
|
||||
{"tst", &flag_tst, 1,
|
||||
"Use TST instruction instead of AND+CMP for bitwise flag tests"},
|
||||
};
|
||||
|
||||
#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
Reference in New Issue
Block a user