Messages in this thread | | | Date | Sun, 1 Mar 1998 13:59:56 -0800 (PST) | From | Linus Torvalds <> | Subject | Re: egcs 1.0.1 miscompiles Linux 2.0.33 |
| |
On Sun, 1 Mar 1998, Jeffrey A Law wrote: > > I'm not an x86 hacker, so it's not really clear to me how you > would rewrite that asm. But it's clearly going to need to be > rewritten. And until it is, I can't do much on the compiler > side as I don't have a valid testcase.
Ok, so here's a hypothetical example that is not x86-specific. In fact it is not specific to any CPU at all, as I made it up (and as such it is a bad example, but it does show the basic problem..)
Let's say that this particular made up CPU has a strange way of disabling interrupts, where it has to load the value through a special register that gcc doesn't even know about and the instruction saves the old value in the same register. The chip designers decided that you can only use one specific GP register to read and write this exception register (let's call this register "ecx" for no other reason than the fact that only intel is so silly). So we have a instruction like this:
rdwrexception %ecx
that writes the exception register with the value in %ecx, and puts the old exception value into %ecx.
Now, the exception register actually contains more than just the interrupt bits, so when you want to restore the interrupt bits into the exception register you have to do something like this:
# # write safe value to exception register (disable everything) # in order to get the current value # movl $0xffffffff,%ecx rdwrexception %ecx
# # mask off the interrupt bit and set it to the saved value # andl $0xfffffffe,%ecx orl restore_value,%ecx rdwrexception %ecx
And the inline assembly would look a bit like this:
#define restore_flags(restore_value) \ asm("rdwrexception %0\n\t" \ "andl $0xfffffffe,%0\n\t" \ "orl %1,%0\n\t" \ "rdwrexception %0" \ : /* no outputs */ \ :"c" (0xffffffff), \ "g" (restore_value) \ :"cx")
Now, how should I re-write this to avoid the clobber?
I could use "=c" and "0" to tell gcc that %ecx is a read-write thing and will change. But that doesn't tell gcc that it mustn't use %ecx for the value in "restore_value": what if somebody were to say
restore_flags(0xffffffff);
then gcc would decide that as it already has the constant 0xffffffff in %ecx, then it should use %ecx for "restore_value" too. But that would be wrong, because then you'd get
orl %ecx,%ecx
which wouldn't do what you wanted..
See the problem? I think that clobbers are the perfect answer, and as they have worked for previous gcc versions for this same problem, I think it is the _correct_ answer. I'm willing to be convinced otherwise, but I'd really like to know how to do something like the above without using a clobber (and without making the asm code worse: I can easily think of many ways to "fix" the problem if I was willing to make worse assembly code).
Linus
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |