From: Matt Fleming <matt@console-pimps.org>
To: linux-sh@vger.kernel.org
Subject: Re: [PATCH] sh: Work around GCC bug in set_bl_bit()
Date: Sun, 26 Sep 2010 20:26:41 +0000 [thread overview]
Message-ID: <20100926202641.GF28588@console-pimps.org> (raw)
In-Reply-To: <ed5637cc82664f68c1609e0f511808c412d4cf68.1285498785.git.matt@console-pimps.org>
On Sun, Sep 26, 2010 at 12:08:37PM +0100, Matt Fleming wrote:
> It seems that some versions of GCC do not handle negative constants in
> inline assembly very well, specifically any negative constant less that
> -129. Here is a reduced example of the problematic code,
>
> static inline void set_bl_bit(void)
> {
> unsigned long __dummy0;
>
> __asm__ __volatile__ (
> "and %1, %0\n\t"
> : "=r" (__dummy0)
> : "r" (0xffffff0f)
> : "memory"
> );
> }
>
> Now, what GCC should do is place 0xffffff0f in a constant pool and load
> it into a register with a mov.l instruction. What actually happens is
> that GCC truncates 0xffffff0f to 16-bits (0xff0f), places it in a
> constant pool and loads it with mov.w. Since the BL bit of the status
> register is at bit-position 28, it doesn't even get set.
>
> To work around this issue simply replace 0xffffff0f with 0xffffffff. It
> is safe to include the IMASK field of the sr register in the 'and' mask
> because we're blocking interrupts anyway by setting the BL bit, so
> there's no need to disable them. The original mask was buggy anyway as
> if any bits were set in IMASK we'd drop them on the floor and they'd
> never be restored.
>
> This bug was discovered after applying commit
> 73a38b839b9295216e8d44dabf54de88270e77b8 ("sh: Only use bl bit toggling
> for sleeping idle."), which made my sh7785lcr board reset after calling
> local_irq_enable() in default_idle().
>
> Signed-off-by: Matt Fleming <matt@console-pimps.org>
Someone just kindly pointed out to me that this diagnosis is
incorrect. mov.w will sign-extend the value loaded from memory before
storing it in a register, so there's no problem there and this isn't a
GCC bug. However, there's still something odd going on with my board and
the change to set_bl_bit() to use 0xffffffff instead of 0xffffff0f
_does_ stop my board resetting.
I'll investigate further.
prev parent reply other threads:[~2010-09-26 20:26 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-26 11:08 [PATCH] sh: Work around GCC bug in set_bl_bit() Matt Fleming
2010-09-26 20:26 ` Matt Fleming [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100926202641.GF28588@console-pimps.org \
--to=matt@console-pimps.org \
--cc=linux-sh@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).