diff options
author | Jan Beulich <jbeulich@suse.com> | 2019-07-01 08:35:08 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2019-07-01 08:35:08 +0200 |
commit | 5641ec015a191e0584fd4cae57bb3262f7a51735 (patch) | |
tree | 4a0364a281bb459f742a431a19448ef0e76d2083 /gas/config/tc-i386.c | |
parent | 79dec6b7baa243a4ada018a082491990adb6aec1 (diff) | |
download | gdb-5641ec015a191e0584fd4cae57bb3262f7a51735.zip gdb-5641ec015a191e0584fd4cae57bb3262f7a51735.tar.gz gdb-5641ec015a191e0584fd4cae57bb3262f7a51735.tar.bz2 |
x86: optimize AND/OR with twice the same register
It seems to be not uncommon for people to use AND or OR in this form for
just setting the status flags. TEST, which doesn't write to any
register other than EFLAGS, ought to be preferred. Make the change only
for -O2 and above though, at least for now.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 28dd540..56ccd12 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -4040,6 +4040,29 @@ optimize_encoding (void) } } } + else if (optimize > 1 + && !optimize_for_space + && i.reg_operands == 2 + && i.op[0].regs == i.op[1].regs + && ((i.tm.base_opcode & ~(Opcode_D | 1)) == 0x8 + || (i.tm.base_opcode & ~(Opcode_D | 1)) == 0x20) + && (flag_code != CODE_64BIT || !i.types[0].bitfield.dword)) + { + /* Optimize: -O2: + andb %rN, %rN -> testb %rN, %rN + andw %rN, %rN -> testw %rN, %rN + andq %rN, %rN -> testq %rN, %rN + orb %rN, %rN -> testb %rN, %rN + orw %rN, %rN -> testw %rN, %rN + orq %rN, %rN -> testq %rN, %rN + + and outside of 64-bit mode + + andl %rN, %rN -> testl %rN, %rN + orl %rN, %rN -> testl %rN, %rN + */ + i.tm.base_opcode = 0x84 | (i.tm.base_opcode & 1); + } else if (i.reg_operands == 3 && i.op[0].regs == i.op[1].regs && !i.types[2].bitfield.xmmword |