isCgo[file] = true
        }
 
-       oFiles := make([]string, 0, len(dirInfo.cFiles))
+       cgoOFiles := make([]string, 0, len(dirInfo.cFiles))
        for _, file := range dirInfo.cFiles {
                if !safeName(file) {
                        return nil, os.ErrorString("unsafe name: " + file)
                }
-               oFiles = append(oFiles, file[:len(file)-2]+".o")
+               cgoOFiles = append(cgoOFiles, file[:len(file)-2]+".o")
        }
 
        goFiles := make([]string, 0, len(dirInfo.goFiles))
                }
        }
 
+       oFiles := make([]string, 0, len(dirInfo.sFiles))
+       for _, file := range dirInfo.sFiles {
+               if !safeName(file) {
+                       return nil, os.ErrorString("unsafe name: " + file)
+               }
+               oFiles = append(oFiles, file[:len(file)-2]+".$O")
+       }
+
        var buf bytes.Buffer
-       md := makedata{pkg, goFiles, cgoFiles, oFiles}
+       md := makedata{pkg, goFiles, oFiles, cgoFiles, cgoOFiles}
        if err := makefileTemplate.Execute(&buf, &md); err != nil {
                return nil, err
        }
 
 // makedata is the data type for the makefileTemplate.
 type makedata struct {
-       Pkg      string   // package import path
-       GoFiles  []string // list of non-cgo .go files
-       CgoFiles []string // list of cgo .go files
-       OFiles   []string // list of ofiles for cgo
+       Pkg       string   // package import path
+       GoFiles   []string // list of non-cgo .go files
+       OFiles    []string // list of .$O files
+       CgoFiles  []string // list of cgo .go files
+       CgoOFiles []string // list of cgo .o files, without extension
 }
 
 var makefileTemplate = template.MustParse(`
        {@}\
 {.end}
 
+{.end}
+{.section OFiles}
+OFILES=\
+{.repeated section OFiles}
+       {@}\
+{.end}
+
 {.end}
 {.section CgoFiles}
 CGOFILES=\
 {.end}
 
 {.end}
-{.section OFiles}
+{.section CgoOFiles}
 CGO_OFILES=\
-{.repeated section OFiles}
+{.repeated section CgoOFiles}
        {@}\
 {.end}
 
 
        goFiles  []string // .go files within dir (including cgoFiles)
        cgoFiles []string // .go files that import "C"
        cFiles   []string // .c files within dir
+       sFiles   []string // .s files within dir
        imports  []string // All packages imported by goFiles
        pkgName  string   // Name of package within dir
 }
        goFiles := make([]string, 0, len(dirs))
        cgoFiles := make([]string, 0, len(dirs))
        cFiles := make([]string, 0, len(dirs))
+       sFiles := make([]string, 0, len(dirs))
        importsm := make(map[string]bool)
        pkgName := ""
        for i := range dirs {
                if !goodOSArch(d.Name) {
                        continue
                }
-               if strings.HasSuffix(d.Name, ".c") {
+
+               switch filepath.Ext(d.Name) {
+               case ".go":
+                       if strings.HasSuffix(d.Name, "_test.go") {
+                               continue
+                       }
+               case ".c":
                        cFiles = append(cFiles, d.Name)
                        continue
-               }
-               if !strings.HasSuffix(d.Name, ".go") || strings.HasSuffix(d.Name, "_test.go") {
+               case ".s":
+                       sFiles = append(sFiles, d.Name)
+                       continue
+               default:
                        continue
                }
+
                filename := filepath.Join(dir, d.Name)
                pf, err := parser.ParseFile(fset, filename, nil, parser.ImportsOnly)
                if err != nil {
                imports[i] = p
                i++
        }
-       return &dirInfo{goFiles, cgoFiles, cFiles, imports, pkgName}, nil
+       return &dirInfo{goFiles, cgoFiles, cFiles, sFiles, imports, pkgName}, nil
 }
 
 // goodOSArch returns false if the filename contains a $GOOS or $GOARCH