| //===- targets.go - target data -------------------------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains functions for retrieving target-specific data. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| package irgen |
| |
| import ( |
| "fmt" |
| "strings" |
| |
| "llvm.org/llvm/bindings/go/llvm" |
| ) |
| |
| // PNaClTriple is the LLVM target triple that should be used to compile |
| // modules to be compatible with PNaCl (Portable Native Client). |
| const PNaClTriple = "armv7-none-linux-gnueabi" |
| |
| // Below are the target data representation constants generated by clang. |
| // For unknown targets, we enumerate all targets known to LLVM and use |
| // the first one with a matching architecture. |
| const ( |
| x86TargetData = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" |
| ) |
| |
| // llvmDataLayout returns the data layout string |
| // representation for the specified LLVM triple. |
| func llvmDataLayout(triple string) (string, error) { |
| // Triples are several fields separated by '-' characters. |
| // The first field is the architecture. The architecture's |
| // canonical form may include a '-' character, which would |
| // have been translated to '_' for inclusion in a triple. |
| arch := parseArch(triple[:strings.IndexRune(triple, '-')]) |
| switch arch { |
| case "x86-64": |
| return x86TargetData, nil |
| } |
| for target := llvm.FirstTarget(); target.C != nil; target = target.NextTarget() { |
| if arch == target.Name() { |
| machine := target.CreateTargetMachine( |
| triple, "", "", |
| llvm.CodeGenLevelDefault, |
| llvm.RelocDefault, |
| llvm.CodeModelDefault, |
| ) |
| target := machine.TargetData().String() |
| machine.Dispose() |
| return target, nil |
| } |
| } |
| return "", fmt.Errorf("Invalid target triple: %s", triple) |
| } |
| |
| // Based on parseArch from LLVM's lib/Support/Triple.cpp. |
| // This is used to match the target machine type. |
| func parseArch(arch string) string { |
| switch arch { |
| case "i386", "i486", "i586", "i686", "i786", "i886", "i986": |
| return "x86" |
| case "amd64", "x86_64": |
| return "x86-64" |
| case "powerpc": |
| return "ppc" |
| case "powerpc64", "ppu": |
| return "ppc64" |
| case "mblaze": |
| return "mblaze" |
| case "arm", "xscale": |
| return "arm" |
| case "thumb": |
| return "thumb" |
| case "spu", "cellspu": |
| return "cellspu" |
| case "msp430": |
| return "msp430" |
| case "mips", "mipseb", "mipsallegrex": |
| return "mips" |
| case "mipsel", "mipsallegrexel": |
| return "mipsel" |
| case "mips64", "mips64eb": |
| return "mips64" |
| case "mipsel64": |
| return "mipsel64" |
| case "r600", "hexagon", "sparc", "sparcv9", "tce", |
| "xcore", "nvptx", "nvptx64", "le32", "amdil": |
| return arch |
| } |
| if strings.HasPrefix(arch, "armv") { |
| return "arm" |
| } else if strings.HasPrefix(arch, "thumbv") { |
| return "thumb" |
| } |
| return "unknown" |
| } |