[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