[Visium] Add support for overflow arithmetic
Eric Botcazou
ebotcazou@adacore.com
Thu Oct 20 14:41:00 GMT 2016
That's not as straightforward on Visium as on other architectures because the
port doesn't (cannot) expose the CC register before reload, so you need to
emit a regular operation as first instruction in the expander and a branch,
which will be split into a compare and a jump after reload; in other words,
the pattern generates 3 instructions instead of 2 and it's up to the post-
reload compare elimination pass to merge the first instruction and the compare
so as to yield the expected overflow arithmetic operation and the branch.
That's easy for the unsigned arithmetic operations because the comparisons are
simple (result with first operand for PLUS, operands directly for MINUS,
result with 0 for NEG, MULT is not supported) so the pattern matching in the
post-reload compare elimination pass is minimal.
That's more difficult for signed arithmetic operations because the comparisons
are complex (see for example the implementation in the ARM back-end) so the
pattern matching in the post-reload compare elimination pass would IMO be too
ad-hoc and involved; that's why the implementation uses UNSPECs for signed
operations, which means that only one case (UNSPEC) needs to be added to the
pattern matching in the post-reload compare elimination pass.
As a side effect, this both removes the ??? and implements the improvement
mentioned in the following comment of the pass:
/* ??? For the moment we don't handle comparisons for which IN_B
is a register. We accepted these during initial comparison
recognition in order to eliminate duplicate compares.
An improvement here would be to handle x = a - b; if (a cmp b). */
This yields optimal code for 8-bit, 16-bit and 32-bit signed and unsigned
overflow arithmetic operations (except for multiplication).
Tested on visium-elf, applied on the mainline.
2016-10-20 Eric Botcazou <ebotcazou@adacore.com>
* compare-elim.c (conforming_compare): Accept UNSPECs.
(find_comparison_dom_walker::before_dom_children): Deal with
instructions both using and killing the flags register.
(equivalent_reg_at_start): New function extracted from...
(try_eliminate_compare): ...here. Use it and add support for
registers and UNSPECs as second operand of the compare.
* config/visium/visium-modes.def (CCV): New.
* config/visium/predicates.md (visium_v_comparison_operator): New.
(visium_branch_operator): Deal with CCV mode.
* config/visium/visium.c (visium_select_cc_mode): Likewise.
(output_cbranch): Likewise.
* config/visium/visium.md (UNSPEC_{ADD,SUB,NEG}V): New constants.
(uaddv<mode>4): New expander.
(addv<mode>4): Likewise.
(add<mode>3_insn_set_carry): New instruction.
(add<mode>3_insn_set_overflow): Likewise.
(addsi3_insn_set_overflow): Likewise.
(usubv<mode>4): New expander.
(subv<mode>4): Likewise.
(sub<mode>3_insn_set_carry): New instruction.
(sub<mode>3_insn_set_overflow): Likewise.
(subsi3_insn_set_overflow): Likewise.
(unegv<mode>3): New expander.
(negv<mode>3): Likewise.
(neg<mode>2_insn_set_overflow): New instruction.
(addv_tst<mode>): Likewise.
(subv_tst<mode>): Likewise.
(negv_tst<mode>): Likewise.
(cbranch<mode>4_addv_insn): New splitter and instruction.
(cbranch<mode>4_subv_insn): Likewise.
(cbranch<mode>4_negv_insn): Likewise.
testsuite/
* gcc.target/visium/overflow8.c: New.
* gcc.target/visium/overflow16.c: Likewise.
* gcc.target/visium/overflow32: Likewise.
--
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: visium_overflow.diff
Type: text/x-patch
Size: 26915 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20161020/49c13c0d/attachment.bin>
More information about the Gcc-patches
mailing list