<< Back to previous view

[PCC-80] change to i386 structure copies broken OSX Created: 19/Aug/09  Updated: 01/May/14

Status: Closed
Project: pcc
Component/s: i386 target
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Gregory McGarry Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Environment: OSX/i386 10.5

File Attachments: GZip Archive pftn.i.gz    

 Description   
Between 2009-08-16 and 2009-08-17 a change was introduced to the i386 target to handle structure copies differently. This change removed code the MACHO systems.

The symptom is that pcc (compiled with gcc) fails to compile itself:

pcc -DGCC_COMPAT -DPCC_DEBUG -Dos_darwin -Dmach_i386 -D_ISOC99_SOURCE -I. -I. -I../.. -I../../mip -I../../arch/i386 -I../../os/darwin -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Wsign-compare -Wtruncate -c -o pftn.o pftn.c
pftn.c, line 1839: compiler error: Cannot generate code, node 0x845270 op OREG

I'm not sure why there is a problem here. Maybe the register constraints are causing a problem. A good way to test changes for OSX is to compile with -k, since OSX requires all code to be compiled PIC. Maybe the problem will appear on other systems using -k.


Here is the diff on that date:

Index: pcc/arch/i386/local2.c
diff -u pcc/arch/i386/local2.c:1.129 pcc/arch/i386/local2.c:1.130
--- pcc/arch/i386/local2.c:1.129 Fri Aug 14 20:38:09 2009
+++ pcc/arch/i386/local2.c Sun Aug 16 09:39:57 2009
@@ -1,4 +1,4 @@
-/* $Id: local2.c,v 1.129 2009/08/14 18:38:09 ragge Exp $ */
+/* $Id: local2.c,v 1.130 2009/08/16 07:39:57 ragge Exp $ */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -562,25 +562,52 @@
  break;
 
  case 'Q': /* emit struct assign */
- /* XXX - optimize for small structs */
-#if defined(MACHOABI)
- printf("\tsubl $4,%%esp\n");
-#endif
- printf("\tpushl $%d\n", p->n_stsize);
- expand(p, INAREG, "\tpushl AR\n");
- expand(p, INAREG, "\tleal AL,%eax\n\tpushl %eax\n");
-#if defined(MACHOABI)
- if (kflag) {
- printf("\tcall L%s$stub\n", EXPREFIX "memcpy");
- addstub(&stublist, EXPREFIX "memcpy");
- } else {
- printf("\tcall %s\n", EXPREFIX "memcpy");
+ /*
+ * With <= 16 bytes, put out mov's, otherwise use movsb/w/l.
+ * esi/edi/ecx are available.
+ */
+ switch (p->n_stsize) {
+ case 1:
+ expand(p, INAREG, " movb (AR),%cl\n");
+ expand(p, INAREG, " movb %cl,AL\n");
+ break;
+ case 2:
+ expand(p, INAREG, " movw (AR),%cx\n");
+ expand(p, INAREG, " movw %cx,AL\n");
+ break;
+ case 4:
+ expand(p, INAREG, " movl (AR),%ecx\n");
+ expand(p, INAREG, " movl %ecx,AL\n");
+ break;
+ default:
+ expand(p, INAREG, " leal AL,%edi\n");
+ expand(p, INAREG, " movl AR,%esi\n");
+ if (p->n_stsize <= 16 && (p->n_stsize & 3) == 0) {
+ printf(" movl (%%esi),%%ecx\n");
+ printf(" movl %%ecx,(%%edi)\n");
+ printf(" movl 4(%%esi),%%ecx\n");
+ printf(" movl %%ecx,4(%%edi)\n");
+ if (p->n_stsize > 8) {
+ printf(" movl 8(%%esi),%%ecx\n");
+ printf(" movl %%ecx,8(%%edi)\n");
+ }
+ if (p->n_stsize == 16) {
+ printf("\tmovl 12(%%esi),%%ecx\n");
+ printf("\tmovl %%ecx,12(%%edi)\n");
+ }
+ } else {
+ if (p->n_stsize > 4) {
+ printf("\tmovl $%d,%%ecx\n",
+ p->n_stsize >> 2);
+ printf(" rep movsl\n");
+ }
+ if (p->n_stsize & 2)
+ printf(" movsw\n");
+ if (p->n_stsize & 1)
+ printf(" movsb\n");
+ }
+ break;
  }
- printf("\taddl $16,%%esp\n");
-#else
- printf("\tcall %s\n", EXPREFIX "memcpy");
- printf("\taddl $12,%%esp\n");
-#endif
  break;
 
  case 'S': /* emit eventual move after cast from longlong */
Index: pcc/arch/i386/order.c
diff -u pcc/arch/i386/order.c:1.54 pcc/arch/i386/order.c:1.55
--- pcc/arch/i386/order.c:1.54 Sat Sep 27 09:35:22 2008
+++ pcc/arch/i386/order.c Sun Aug 16 09:39:57 2009
@@ -1,4 +1,4 @@
-/* $Id: order.c,v 1.54 2008/09/27 07:35:22 ragge Exp $ */
+/* $Id: order.c,v 1.55 2009/08/16 07:39:57 ragge Exp $ */
 /*
  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
  * All rights reserved.
@@ -159,6 +159,16 @@
  }
 
  case STASG:
+ {
+ static struct rspecial s[] = {
+ { NEVER, ESI }, { NEVER, EDI },
+ { NORIGHT, ESI }, { NORIGHT, EDI },
+ { NOLEFT, ESI }, { NOLEFT, EDI },
+ { NOLEFT, ECX }, { NORIGHT, ECX },
+ { NEVER, ECX }, { 0 } };
+ return s;
+ }
+
  case STARG:
  {
  static struct rspecial s[] = {


 Comments   
Comment by Anders Magnusson [ 19/Aug/09 11:57 AM ]
Can you provide a preprocessed file of it?
Comment by Gregory McGarry [ 20/Aug/09 01:17 AM ]
Here's a preprocessed pftn.c which generated the failure:

pcc -DGCC_COMPAT -DPCC_DEBUG -Dos_darwin -Dmach_i386 -D_ISOC99_SOURCE -I. -I. -I../.. -I../../mip -I../../arch/i386 -I../../os/darwin -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Wsign-compare -Wtruncate -c -o pftn.o pftn.c
pftn.c, line 1839: compiler error: Cannot generate code, node 0x845270 op OREG

Comment by Gregory McGarry [ 24/Aug/09 10:57 AM ]
I can confirm that copying this pftn.i file to a win32 machine and compiling with -k does not work. So it's not an OSX-specific issue.

{code}
    0x83e950) STASG, PTR unionty, 0x0, 0x811e30
        0x8376a0) U*, unionty, 0x0, 0x811e30
            0x83c870) +, PTR unionty, 0x0, 0x811e30
                0x83f780) U*, PTR unionty, 0x0, 0x811e30
                    0x832620) -, PTR PTR unionty, 0x0, 0x811e30
                        0x83f840) REG, 0, 6, PTR PTR unionty, 0x0, 0x811e30
                        0x838190) ICON, 48, 0, int, 0x0, 0x41fd8
                0x831430) <<, int, 0x0, 0x41fd8
                    0x82f710) U*, int, 0x0, 0x41fd8
                        0x83a350) -, PTR int, 0x0, 0x41fd8
                            0x8328c0) REG, 0, 6, PTR int, 0x0, 0x41fd8
                            0x83f480) ICON, 40, 0, int, 0x0, 0x41fd8
                    0x832290) ICON, 2, 0, int, 0x0, 0x41fd8
        0x82fdf0) +, PTR unionty, 0x0, 0x811e30
            0x82fac0) U*, PTR unionty, 0x0, 0x811e30
                0x83fd20) -, PTR PTR strty, 0x0, 0x821350
                    0x83ffe0) REG, 0, 6, PTR PTR strty, 0x0, 0x821350
                    0x833700) ICON, 12, 0, int, 0x0, 0x41fd8
            0x83fea0) ICON, 4, 0, int, 0x0, 0x41fd8
{code}
Comment by Gregory McGarry [ 09/Sep/09 08:46 AM ]
I can confirm that pcc won't compile

src/sbin/routed/if.c

of the NetBSD source tree due to the structure copy at line 1025.

I'm sure that the problem is due to pressure on the number of available registers.
Comment by Anders Magnusson [ 16/Jun/10 01:42 PM ]
I just tested the attached file using a cross-compiled ccom (with --target=i386-darwin8) and didn't get any errors. Is this still a problem?
Comment by Anders Magnusson [ 01/May/14 04:01 PM ]
Seems to have solved itself in the time being.
Generated at Sun Aug 31 10:18:43 CEST 2014 using JIRA Enterprise Edition, Version: 3.13.1-#333.