Skip to content
Snippets Groups Projects
Commit f9c7775f authored by Takayuki 'January June' Suwa's avatar Takayuki 'January June' Suwa Committed by Max Filippov
Browse files

xtensa: Make use of scaled [U]FLOAT/TRUNC.S instructions

[U]FLOAT.S machine instruction in Xtensa ISA, which converts an integer to
a hardware single-precision FP register, has the ability to divide the
result by power of two (0 to 15th).

Similarly, [U]TRUNC.S instruction, which truncates single-precision FP to
integer, can multiply the source value by power of two in advance, but
neither of these currently uses this function (always specified with 0th
power of two, i.e. a scaling factor of 1).

This patch unleashes the scaling ability of the above instructions.

     /* example */
     float test0(int a) {
       return a / 2.f;
     }
     float test1(unsigned int a) {
       return a / 32768.f;
     }
     int test2(float a) {
       return a * 2;
     }
     unsigned int test3(float a) {
       return a * 32768;
     }

     ;; before
     test0:
     	movi.n	a9, 0x3f
     	float.s	f0, a2, 0
     	slli	a9, a9, 24
     	wfr	f1, a9
     	mul.s	f0, f0, f1
     	rfr	a2, f0
     	ret.n
     test1:
     	movi.n	a9, 7
     	ufloat.s	f0, a2, 0
     	slli	a9, a9, 27
     	wfr	f1, a9
     	mul.s	f0, f0, f1
     	rfr	a2, f0
     	ret.n
     test2:
     	wfr	f1, a2
     	add.s	f0, f1, f1
     	trunc.s	a2, f0, 0
     	ret.n
     test3:
     	movi.n	a9, 0x47
     	slli	a9, a9, 24
     	wfr	f1, a2
     	wfr	f2, a9
     	mul.s	f0, f1, f2
     	utrunc.s	a2, f0, 0
     	ret.n

     ;; after
     test0:
     	float.s	f0, a2, 1
     	rfr	a2, f0
     	ret.n
     test1:
     	ufloat.s	f0, a2, 15
     	rfr	a2, f0
     	ret.n
     test2:
     	wfr	f0, a2
     	trunc.s	a2, f0, 1
     	ret.n
     test3:
     	wfr	f0, a2
     	utrunc.s	a2, f0, 15
     	ret.n

gcc/ChangeLog:

	* config/xtensa/predicates.md
	(fix_scaling_operand, float_scaling_operand): New predicates.
	* config/xtensa/xtensa.md
	(any_fix/m_fix/s_fix, any_float/m_float/s_float):
	New code iterators and their attributes.
	(fix<s_fix>_truncsfsi2): Change from "fix_truncsfsi2".
	(*fix<s_fix>_truncsfsi2_2x, *fix<s_fix>_truncsfsi2_scaled):
	New insn definitions.
	(float<s_float>sisf2): Change from "floatsisf2".
	(*float<s_float>sisf2_scaled): New insn definition.
parent 56c4979d
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment