<< Back to previous view

[PCC-411] pcc can generate assembly that gnu as doesn't like Created: 19/Sep/12  Updated: 25/Sep/12

Status: Resolved
Project: pcc
Component/s: amd64 target
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Nicolas Joly Assignee: Anders Magnusson
Resolution: Fixed Votes: 0
Environment: NetBSD lanfeust.sis.pasteur.fr 6.99.11 NetBSD 6.99.11 (LANFEUST) #9: Tue Sep 18 15:45:01 CEST 2012 njoly@lanfeust.sis.pasteur.fr:/local/src/NetBSD/obj.amd64/sys/arch/amd64/compile/LANFEUST amd64
pcc 1.1.0.DEVEL 20120919 for x86_64-unknown-netbsd6.99.11
GNU assembler (NetBSD Binutils nb1) 2.21.1


 Description   
While trying to compile NetBSD amd64 GENERIC kernel with pcc, it fails on one file (pmap,c) where GNU as report some errors :

/tmp/ctm.01415b: Assembler messages:
/tmp/ctm.01415b:2569: Error: 0x7f8000000000 out range of signed 32bit displacement
/tmp/ctm.01415b:2576: Error: 0x7f8000000000 out range of signed 32bit displacement
/tmp/ctm.01415b:4923: Error: 0x7fbfdfeff000 out range of signed 32bit displacement
as terminated with status 1

Looking in generated assembly, the 3 offending lines look mostly the same with a huge constant :

2569: movq 140187732541440(,%rdx,1),%rax
2576: orq %rdx,140187732541440(,%rax,1)
4923: movq 140462072524800(,%rdx,8),%rcx


 Comments   
Comment by Anders Magnusson [ 19/Sep/12 07:08 PM ]
Fixed. amd64 cannot have offset to registers that are outside int numbers.
Comment by Nicolas Joly [ 25/Sep/12 09:48 AM ]
Thanks Anders, but the problem is still there ...

A few experiments show that the problematic constructs come from adrput() in the OREG case (arch/amd64/local2.c) which does not take into account the change you made recently.

        case OREG:
                r = p->n_rval;
                if (p->n_name[0])
                        printf("%s%s", p->n_name, p->n_lval ? "+" : "");
                if (p->n_lval)
                        fprintf(io, "%lld", p->n_lval);
                if (R2TEST(r)) {
                        int r1 = R2UPK1(r);
                        int r2 = R2UPK2(r);
                        int sh = R2UPK3(r);

                        fprintf(io, "(%s,%s,%d)",
                            r1 == MAXREGS ? "" : rnames[r1],
                            r2 == MAXREGS ? "" : rnames[r2], sh);
                } else
                        fprintf(io, "(%s)", rnames[p->n_rval]);
                return;
Comment by Anders Magnusson [ 25/Sep/12 09:53 AM ]
Strange. My change disallowed the creation of OREGs if the constant value were too large (or small).
Do you have a test case exposing this bug?
Comment by Nicolas Joly [ 25/Sep/12 10:05 AM ]
Unfortunately no ... I'll try to extract something from the pmap.c kernel source to reproduce the problem.
Comment by Nicolas Joly [ 25/Sep/12 01:55 PM ]
Here it is ...

njoly@lanfeust [tmp/pcc]> cat pmap2.c
typedef unsigned long int pd_entry_t;

#define NBPD_L4 (1UL << 39)
#define L4_SLOT_PTE 255
#define PTE_BASE ((pd_entry_t *) (L4_SLOT_PTE * NBPD_L4))

int
pmap_pdp_ctor(void *v)
{
        pd_entry_t *pdir = v;
        int idx = 0;

        pdir[idx] = PTE_BASE[idx];

        return (0);
}

njoly@lanfeust [tmp/pcc]> pcc --version
pcc 1.1.0.DEVEL 20120925 for x86_64-unknown-netbsd6.99.11
njoly@lanfeust [tmp/pcc]> pcc -c pmap2.c
/tmp/ctm.13052b: Assembler messages:
/tmp/ctm.13052b:17: Error: 0x7f8000000000 out range of signed 32bit displacement
as terminated with status 1
njoly@lanfeust [tmp/pcc]> echo $?
1

njoly@lanfeust [tmp/pcc]> gcc --version
gcc (NetBSD nb1 20120916) 4.5.4
njoly@lanfeust [tmp/pcc]> gcc -c pmap2.c
njoly@lanfeust [tmp/pcc]> echo $?
0
Comment by Anders Magnusson [ 25/Sep/12 05:09 PM ]
Heh, there were a check for OREG in offstar where it wasn't checked. Fixed now, thanks.
Generated at Fri Aug 29 14:02:06 CEST 2014 using JIRA Enterprise Edition, Version: 3.13.1-#333.