This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: Machine description and code generation
- From: "Mathias Roslund" <mathias dot roslund at amidog dot se>
- To: "'Joern Rennecke'" <joern dot rennecke at embecosm dot com>
- Cc: "'GCC'" <gcc at gcc dot gnu dot org>
- Date: Thu, 27 Nov 2014 14:28:15 +0100
- Subject: RE: Machine description and code generation
- Authentication-results: sourceware.org; auth=none
- References: <0da8f1de56a66c2c3394004190e74c32 dot squirrel at amidog dot se> <54514FA6 dot 3020108 at redhat dot com> <000001d00998$d7b114d0$87133e70$ at amidog dot se> <CAMqJFCrovR1iFvWPKPfaeouwVzQza-dxYnFz3+sB=FOeV-NUTA at mail dot gmail dot com>
> From: Joern Rennecke [mailto:joern.rennecke@embecosm.com]
> Sent: Wednesday, November 26, 2014 6:13 PM
> To: Mathias Roslund
> Cc: GCC
> Subject: Re: Machine description and code generation
>
> On 26 November 2014 at 16:48, Mathias Roslund
> <mathias.roslund@amidog.se> wrote:
> > Since then I've added more instructions and gotten to the point where
> > most stuff seems to be working. My current issue is that signed divide
> > and all shift operations insists on sign/zero extending the operands,
> > resulting in 32bit operations even when only 8bit ones would be required.
>
> That's a matter of the input language. In C, you get default promotions to int
> from narrower integer types.
Thanks. I had totally forgotten about the C promotion rules.
> > Interestingly,
> > multiplies and unsigned divides behave as desired, i.e. only operate
> > on the required number of bits.
>
> That's because the results are the same regardless, and the optimizers are
> able to undo the effects of the type promotions.
But isn't the result of an 8bit signed divide the same as the result of a 32bit signed divide when both operands are in the 8bit range? That is, shouldn't the optimizers be able to do the same for signed divide as well as shift operations?
I noticed I can revert the promotion effects using these instruction patterns:
[(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
(div:SI (sign_extend:SI (match_operand:QI 1 "general_operand" "mri"))
(sign_extend:SI (match_operand:QI 2 "general_operand" "mri"))))
]
[(set (match_operand:QI 0 "nonimmediate_operand" "=mr")
(subreg:QI (div:SI (sign_extend:SI (match_operand:QI 1 "general_operand" "mri"))
(sign_extend:SI (match_operand:QI 2 "general_operand" "mri"))) 0))
]
The first pattern will allow me to perform the sign extension after the divide (which will be orders of magnitude faster) while the second will remove the need for any sign extensions all together if the result is truncated to 8bit when stored.
It doesn't feel right to put this in the machine description though.
Best regards,
Mathias Roslund