This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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] |
The PA is a segmented architecture with implicit segment selection. However, segment selection is performed on the base register rather than the effective address. Thus ldw %r1(%r2),%r3 /* *(%r1+%r2) -> %r3 */ Is not the same as ldw %r2(%r1),%r3 /* *(%r2+%r1) -> %r3 */ The first load will reference the segment based on the upper bits of %r2 while the second load will reference the segment based on the upper bits in %r1. The PA port uses REG_POINTER to distinguish between base and index registers in unscaled indexed addressing modes. Unfortunately, GCC tends to mark lots of non-pointer objects with REG_POINTER. The problem is our representation for pointer arithmetic is fundamentally broken -- specifically the front-ends and later various optimizers force both operands in a pointer arithmetic expression to have pointer types. Thus if given something like this at the source level: char *p; int i; for (i = 0; i < 10; i++) foo (p + i); Will effectively be turned into char *p; int i; for (i = 0; i < 10; i++) foo (p + (char *)i); NOP_EXPRs are not valid gimple operands, so gimplification will turn that into something like this: char *p,*temp; int i; for (i = 0; i < 10; i++) { temp = (char *)i; foo (p + temp); } Note that "temp" has a pointer type and thus will be marked with REG_POINTER by stmt.c::expand_decl. In this particular example, both p and temp will be marked as pointers and the PA backend will DTRT (not use unscaled indexed address modes). However, in more complex cases, we can have a base register which is _not_ marked with REG_POINTER and at the same time we can have a temporary which is marked with REG_POINTER even though the temporary is just a loop index. This can and does cause the PA to generate incorrect code. Note very very carefully this means that failure to mark a pointer with REG_POINTER can result in incorrect code on the PA (and possibly ia64 and the mn10300). That is very very bad as it means that it is not safe to have a pointer which is not marked with REG_POINTER. I am still working on fixing GCC's type system to deal with this properly, but in the mean time some changes are necessary to make GCC more sanely set REG_POINTER and avoid some of this losing behavior. It turns out that we can avoid these problems by being more selective about our marking of pointers in stmt.c::expand_decl. Specifically, the problems occur due to the creation of _temporaries_ with pointer types but which actually hold index values (instead of base pointers). So rather than marking every pointer object with REG_POINTER, we just mark those objects which correspond to user variables with REG_POINTER. With this patch the 32bit PA compiler bootstraps when previously it failed during the stage2 build. The target libs do not build yet, but that's a totally unrelated problem. I need to do a major update on my PA64 tools before I can try a bootstrap on PA64 (trying to bootstrap with my circa 2000 tools fails miserably as does trying to bootstrap with the native PA64 tools supplied by HP). Anyway, this patch is still a good step forward.
Attachment:
ZZZ
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |