This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: mipsisa32-unknown-elf-as: Error: too large constant specified


cgd@broadcom.com wrote:

With the current behaviour, ostensibly correct code working with
32-bit values will now generate invalid results if compiled for a
64-bit ISA,  even if the code never uses 64-bit operands. If I was
porting this piece of 32-bit assembler code to say the n32 or o64 ABI,
then it would generate an *unpredictable* result:

li $2, 0x1234
or $2, $2, 0x80000000
addu $2, $2, 1



well, one would hope this would be something like: "or $2, $2, KSEG0_BASE" or something. (That's what it was like in some of our source, and yes, we had to ... change the #define.)


Yeah, and for KSEG0_BASE that can be explained away, given the shape of the MIPS 64-bit address map.


But it's not so clearly right if you're doing bit manipulation:

#define DEV_STATE_MASK	0xc0000000
#define DEV_STATE_SHIFT 30

	lw	$v0,DEV_REG
	and	$v0,DEV_STATE_MASK
	srl	$v0,DEV_STATE_SHIFT


OK, that's not the best way to code something like this, but you get my drift - it's not going to work when compiled -mips4, since srl's input is now an invalid 32-bit value if bit 31 was set. Having to define it like this is pretty non-obvious:


#define DEV_STATE_MASK 0xffffffffc0000000


One "programming guideline" would be to make sure that when switching
from logical ops to 32-bit arithmetic ops, to sll first if one wants
portable code.


Ick. (c) Eric Christopher.


One could easily do this in a way that doesn't hurt 32-bit code, and
it puts the onus on people who want to run safely on 64-bit machines.
(There are already a lot of changes people really should deal with,
it's just one more.) And it doesn't hurt people who don't intermix
arithmetic and logical ops on the same values, at all.



I'll assume your tongue is firmly in your cheek! That would be a horrible and unnecessary addition to the MIPS architecture - not being able freely to intermix logical and arithmetic ops.


One of the really cool things about the 64-bit MIPS architecture is that there *isn't* a 64-bit mode switch: most 32-bit code just works on a 64-bit CPU, no change required (assuming a 32-bit compatible ABI, of course). The CPU does the right thing - it's just the assembler which has created this portability problem, which we're proposing increasingly complex ways of working around.


That's unambiguous, and puts the onus on the author of the 64-bit
assembler source code.



At the expense of a serious amount of code clarity, IMO.


FWIW, another possible conclusion from your argument is that, really,
the logical psedo-ops are inherently ambiguous, and maybe should be
removed entirely.  8-)


Umm... perhaps not. ;-)



Having a logical op's immediate operand get sign extended magically iff bit 31 is set (or maybe if bits 63:32 are all 0) violates some notion that the assembler will treat input values consistently, and that if one can generate 0x800000000 one can equally generate 0x80000000.

Especially if one uses lots of #defined constants (and who doesn't
these days? 8-), then why should:

       #define FOO (1<<30)
       #define FOO (1<<31)

be expected to behave vastly differently on a 64-bit arch?


Some more thoughts:


(1) if the decision to go 'back' to the sign-extended 32-bit values
was made, IMO *all* 64-bit values should be rejected.



Yes, at least all 64-bit immediates used on non-'d' instructions. But then that would mean adding 'dor', 'dand', etc, which is seen as icky, and I think I agree.



(2) I suspect that either way, a significant change would cause people
-- who probably just had to tweak their code slightly -- to have to
change their code in even more significant ways. (i.e., they just had
to add 0xffffffff to the start of their constants, with a change like
you propose recoding would be required, alas.)



Hey - maybe there should be an assembler command-line option for dusty deck code: -msign-extend-imm32 and -mno-sign-extend-imm32 ;-)


Nigel



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]