github.com/axw/llgo@v0.0.0-20160805011314-95b5fe4dca20/irgen/targets.go (about)

     1  //===- targets.go - target data -------------------------------------------===//
     2  //
     3  //                     The LLVM Compiler Infrastructure
     4  //
     5  // This file is distributed under the University of Illinois Open Source
     6  // License. See LICENSE.TXT for details.
     7  //
     8  //===----------------------------------------------------------------------===//
     9  //
    10  // This file contains functions for retrieving target-specific data.
    11  //
    12  //===----------------------------------------------------------------------===//
    13  
    14  package irgen
    15  
    16  import (
    17  	"fmt"
    18  	"strings"
    19  
    20  	"llvm.org/llvm/bindings/go/llvm"
    21  )
    22  
    23  // llvmDataLayout returns the data layout string
    24  // representation for the specified LLVM triple.
    25  func llvmDataLayout(triple string) (string, error) {
    26  	// Triples are several fields separated by '-' characters.
    27  	// The first field is the architecture. The architecture's
    28  	// canonical form may include a '-' character, which would
    29  	// have been translated to '_' for inclusion in a triple.
    30  	arch := parseArch(triple[:strings.IndexRune(triple, '-')])
    31  	for target := llvm.FirstTarget(); target.C != nil; target = target.NextTarget() {
    32  		if arch == target.Name() {
    33  			machine := target.CreateTargetMachine(
    34  				triple, "", "",
    35  				llvm.CodeGenLevelDefault,
    36  				llvm.RelocDefault,
    37  				llvm.CodeModelDefault,
    38  			)
    39  			targetData := machine.CreateTargetData()
    40  			targetDataLayout := targetData.String()
    41  			targetData.Dispose()
    42  			machine.Dispose()
    43  			return targetDataLayout, nil
    44  		}
    45  	}
    46  	return "", fmt.Errorf("Invalid target triple: %s", triple)
    47  }
    48  
    49  // Based on parseArch from LLVM's lib/Support/Triple.cpp.
    50  // This is used to match the target machine type.
    51  func parseArch(arch string) string {
    52  	switch arch {
    53  	case "i386", "i486", "i586", "i686", "i786", "i886", "i986":
    54  		return "x86"
    55  	case "amd64", "x86_64":
    56  		return "x86-64"
    57  	case "powerpc":
    58  		return "ppc"
    59  	case "powerpc64", "ppu":
    60  		return "ppc64"
    61  	case "mblaze":
    62  		return "mblaze"
    63  	case "arm", "xscale":
    64  		return "arm"
    65  	case "thumb":
    66  		return "thumb"
    67  	case "spu", "cellspu":
    68  		return "cellspu"
    69  	case "msp430":
    70  		return "msp430"
    71  	case "mips", "mipseb", "mipsallegrex":
    72  		return "mips"
    73  	case "mipsel", "mipsallegrexel":
    74  		return "mipsel"
    75  	case "mips64", "mips64eb":
    76  		return "mips64"
    77  	case "mipsel64":
    78  		return "mipsel64"
    79  	case "r600", "hexagon", "sparc", "sparcv9", "tce",
    80  		"xcore", "nvptx", "nvptx64", "le32", "amdil":
    81  		return arch
    82  	}
    83  	if strings.HasPrefix(arch, "armv") {
    84  		return "arm"
    85  	} else if strings.HasPrefix(arch, "thumbv") {
    86  		return "thumb"
    87  	}
    88  	return "unknown"
    89  }