This is the mail archive of the
mailing list for the GCC project.
Re: MIPS: Trouble with address calculation near the useg/kseg boundary
- From: David Daney <ddaney at caviumnetworks dot com>
- To: Paul Koning <paul_koning at dell dot com>
- Cc: GCC List <gcc at gcc dot gnu dot org>
- Date: Wed, 16 Feb 2011 14:08:54 -0800
- Subject: Re: MIPS: Trouble with address calculation near the useg/kseg boundary
- References: <7DB15F34-037F-4129-815F-B2B3800EF195@dell.com>
On 02/16/2011 01:44 PM, Paul Koning wrote:
I'm running into a crash caused by mishandling of address calculation of an array element address when that array is near the bottom of kseg0 (0xffffffff80000000).
The code essentially does this
foo = v[i - 2].elem;
where i is current zero.
Assume for now the negative array offset is valid -- data structure elements in question exist to both sides of the label "v".
The generated code looks like this:
/* i is in v0 */
addiu v0, -2
sll v0, 3
lui v1, 0x8000
addu v0, v1
lbu a1, 7110(v0)
What's going on here is that&v.elem is 0xfffffffff80007110. The reference is valid -- array elements are 8 bytes so element -2 is still in kseg0.
However, the addu produces value 0000000007ffffff0 in v0 -- the result of adding -16 to the 32 bit value 0x800000000.
Given that I have an ABI with 64 bit registers -- even though it has 32 bit pointers -- I would say the address adjustment should have been done with daddu; if that had been done I would have gotten the correct address.
GCC is 4.5.1, NetBSD target.
This is why it is a bad idea to place anything in the 2^16 byte region
centered on the split.
The Linux kernel works around this by not using the lower 32kb of
ckseg0. It also never user the top 32kb of useg when in 32bit mode.