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

Nigel Stephens nigel@mips.com
Wed Oct 15 14:48:00 GMT 2003


Ian Lance Taylor wrote:

>Hmmm, that's not what I see.  When I run with the -mips4 option, I get
>this:
>   0:	3401e000 	li	at,0xe000
>   4:	00010c38 	dsll	at,at,0x10
>   8:	00411025 	or	v0,v0,at
>   c:	2401ffff 	li	at,-1
>  10:	00010c38 	dsll	at,at,0x10
>  14:	34211fff 	ori	at,at,0x1fff
>  18:	00010c38 	dsll	at,at,0x10
>  1c:	3421ffff 	ori	at,at,0xffff
>  20:	00411024 	and	v0,v0,at
>
>Which is what cgd saw also.  I configured for mips-elf.  What did you
>configure for?
>

My eyeballs!  My built-in compiler is obviously a bit buggy. Apologies 
for any confusion.

>Moreover, it's difficult to interpret your suggestion for instructions
>like `or' and `and'.  Those instructions don't have `d' variants; they
>don't need them, because the operation is well defined whether working
>with a 64-bit value or a sign extended 32-bit value.  In this case,
>the assembler is synthesizing an immediate value for `or' and `and'.
>What size should it synthesize for, when assembling for a 64-bit
>target?
>  
>

Indeed. My argument is that it is "surprising" for the assembler to ever 
generate zero-extended 64-bit immediate values for any instruction that 
is not explicitly 64-bit. I agree that the logical operations, which 
don't have 64-bit variants, are a problem - but surely portability of 
existing 32-bit code is crucial. If I'm recompiling a 32-bit C program 
for the n32 ABI, then I don't expect to have to change anything - unless 
I explicitly use long long.

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


[If  the 'or' immediate operand is zero extended by the assembler to 
0x0000000080000000, then  we've now generated an invalid operand for 
"addu", since  32-bit MIPS arithmetical operations are only defined to 
generate valid results if their inputs are correctly sign-extended, in 
other cases their result is "unpredictable".]

I'd have to rewrite the code like this to get the original 32-bit semantics:

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

Now that seems perverse! It would be easy enough for an assembler 
programmer writing 64-bit code from scratch, and wanting a zero-extended 
operand for  'or', 'and', etc, to write their new code thusly:

	dli	$3, 0x80000000
	or	$2, $2, $3


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

The problem is of course the assembler language definition, or rather 
the lack of it - both See MIPS Run and the old SGI assembler manual are 
ambiguous on this point. Sadly I can see that I'm going to lose this 
argument, because SGI got there first with their assembler and did it 
the "wrong" ;-) way.

Nigel




More information about the Binutils mailing list