zcov: / lib/Basic/TargetInfo.cpp


Files: 1 Branches Taken: 73.0% 100 / 137
Generated: 2010-02-10 01:31 Branches Executed: 92.7% 127 / 137
Line Coverage: 87.4% 153 / 175


Programs: 2 Runs 3018


       1                 : //===--- TargetInfo.cpp - Information about Target machine ----------------===//
       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 implements the TargetInfo and TargetInfoImpl interfaces.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Basic/TargetInfo.h"
      15                 : #include "clang/Basic/LangOptions.h"
      16                 : #include "llvm/ADT/APFloat.h"
      17                 : #include "llvm/ADT/STLExtras.h"
      18                 : #include <cstdlib>
      19                 : using namespace clang;
      20                 : 
      21                 : // TargetInfo Constructor.
      22             2535: TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
      23                 :   // Set defaults.  Defaults are set for a 32-bit RISC platform,
      24                 :   // like PPC or SPARC.
      25                 :   // These should be overridden by concrete targets as needed.
      26             2535:   TLSSupported = true;
      27             2535:   PointerWidth = PointerAlign = 32;
      28             2535:   IntWidth = IntAlign = 32;
      29             2535:   LongWidth = LongAlign = 32;
      30             2535:   LongLongWidth = LongLongAlign = 64;
      31             2535:   FloatWidth = 32;
      32             2535:   FloatAlign = 32;
      33             2535:   DoubleWidth = 64;
      34             2535:   DoubleAlign = 64;
      35             2535:   LongDoubleWidth = 64;
      36             2535:   LongDoubleAlign = 64;
      37             2535:   SizeType = UnsignedLong;
      38             2535:   PtrDiffType = SignedLong;
      39             2535:   IntMaxType = SignedLongLong;
      40             2535:   UIntMaxType = UnsignedLongLong;
      41             2535:   IntPtrType = SignedLong;
      42             2535:   WCharType = SignedInt;
      43             2535:   WIntType = SignedInt;
      44             2535:   Char16Type = UnsignedShort;
      45             2535:   Char32Type = UnsignedInt;
      46             2535:   Int64Type = SignedLongLong;
      47             2535:   SigAtomicType = SignedInt;
      48             2535:   FloatFormat = &llvm::APFloat::IEEEsingle;
      49             2535:   DoubleFormat = &llvm::APFloat::IEEEdouble;
      50             2535:   LongDoubleFormat = &llvm::APFloat::IEEEdouble;
      51                 :   DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
      52             2535:                       "i64:64:64-f32:32:32-f64:64:64-n32";
      53             2535:   UserLabelPrefix = "_";
      54             2535: }
      55                 : 
      56                 : // Out of line virtual dtor for TargetInfo.
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                     2532: branch 10 taken
      57             2532: TargetInfo::~TargetInfo() {}
      58                 : 
      59                 : /// getTypeName - Return the user string for the specified integer type enum.
      60                 : /// For example, SignedShort -> "short".
      61            25183: const char *TargetInfo::getTypeName(IntType T) {
                        0: branch 0 not taken
                     2526: branch 1 taken
                        3: branch 2 taken
                    12007: branch 3 taken
                     2172: branch 4 taken
                      989: branch 5 taken
                      556: branch 6 taken
                     4620: branch 7 taken
                     2310: branch 8 taken
      62            25183:   switch (T) {
      63                0:   default: assert(0 && "not an integer!");
      64             2526:   case SignedShort:      return "short";
      65                3:   case UnsignedShort:    return "unsigned short";
      66            12007:   case SignedInt:        return "int";
      67             2172:   case UnsignedInt:      return "unsigned int";
      68              989:   case SignedLong:       return "long int";
      69              556:   case UnsignedLong:     return "long unsigned int";
      70             4620:   case SignedLongLong:   return "long long int";
      71             2310:   case UnsignedLongLong: return "long long unsigned int";
      72                 :   }
      73                 : }
      74                 : 
      75                 : /// getTypeConstantSuffix - Return the constant suffix for the specified
      76                 : /// integer type enum. For example, SignedLong -> "L".
      77            22664: const char *TargetInfo::getTypeConstantSuffix(IntType T) {
                        0: branch 0 not taken
                    12584: branch 1 taken
                     2938: branch 2 taken
                     7139: branch 3 taken
                        3: branch 4 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      78            22664:   switch (T) {
      79                0:   default: assert(0 && "not an integer!");
      80                 :   case SignedShort:
      81            12584:   case SignedInt:        return "";
      82             2938:   case SignedLong:       return "L";
      83             7139:   case SignedLongLong:   return "LL";
      84                 :   case UnsignedShort:
      85                3:   case UnsignedInt:      return "U";
      86                0:   case UnsignedLong:     return "UL";
      87                0:   case UnsignedLongLong: return "ULL";
      88                 :   }
      89                 : }
      90                 : 
      91                 : /// getTypeWidth - Return the width (in bits) of the specified integer type 
      92                 : /// enum. For example, SignedInt -> getIntWidth().
      93            46387: unsigned TargetInfo::getTypeWidth(IntType T) const {
                        0: branch 0 not taken
                     5055: branch 1 taken
                    21956: branch 2 taken
                     5017: branch 3 taken
                    14359: branch 4 taken
      94            46387:   switch (T) {
      95                0:   default: assert(0 && "not an integer!");
      96                 :   case SignedShort:
      97             5055:   case UnsignedShort:    return getShortWidth();
      98                 :   case SignedInt:
      99            21956:   case UnsignedInt:      return getIntWidth();
     100                 :   case SignedLong:
     101             5017:   case UnsignedLong:     return getLongWidth();
     102                 :   case SignedLongLong:
     103            14359:   case UnsignedLongLong: return getLongLongWidth();
     104                 :   };
     105                 : }
     106                 : 
     107                 : /// getTypeAlign - Return the alignment (in bits) of the specified integer type 
     108                 : /// enum. For example, SignedInt -> getIntAlign().
     109                8: unsigned TargetInfo::getTypeAlign(IntType T) const {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        8: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
     110                8:   switch (T) {
     111                0:   default: assert(0 && "not an integer!");
     112                 :   case SignedShort:
     113                0:   case UnsignedShort:    return getShortAlign();
     114                 :   case SignedInt:
     115                8:   case UnsignedInt:      return getIntAlign();
     116                 :   case SignedLong:
     117                0:   case UnsignedLong:     return getLongAlign();
     118                 :   case SignedLongLong:
     119                0:   case UnsignedLongLong: return getLongLongAlign();
     120                 :   };
     121                 : }
     122                 : 
     123                 : /// isTypeSigned - Return whether an integer types is signed. Returns true if
     124                 : /// the type is signed; false otherwise.
     125            15114: bool TargetInfo::isTypeSigned(IntType T) const {
                        0: branch 0 not taken
                    15111: branch 1 taken
                        3: branch 2 taken
     126            15114:   switch (T) {
     127                0:   default: assert(0 && "not an integer!");
     128                 :   case SignedShort:
     129                 :   case SignedInt:
     130                 :   case SignedLong:
     131                 :   case SignedLongLong:   
     132            15111:     return true;
     133                 :   case UnsignedShort:
     134                 :   case UnsignedInt:
     135                 :   case UnsignedLong:
     136                 :   case UnsignedLongLong: 
     137                3:     return false;
     138                 :   };
     139                 : }
     140                 : 
     141                 : /// setForcedLangOptions - Set forced language options.
     142                 : /// Apply changes to the target information with respect to certain
     143                 : /// language options which change the target configuration.
     144             2522: void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
                        1: branch 0 taken
                     2521: branch 1 taken
     145             2522:   if (Opts.ShortWChar) {
     146                1:     WCharType = UnsignedShort;
     147                 :   }
     148             2522: }
     149                 : 
     150                 : //===----------------------------------------------------------------------===//
     151                 : 
     152                 : 
     153               91: static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) {
                       85: branch 1 taken
                        6: branch 2 taken
                        6: branch 4 taken
                       79: branch 5 taken
                       12: branch 6 taken
                       79: branch 7 taken
     154               91:   if (Name[0] == '%' || Name[0] == '#')
     155               12:     Name = Name.substr(1);
     156                 :   
     157               91:   return Name;
     158                 : }
     159                 : 
     160                 : /// isValidGCCRegisterName - Returns whether the passed in string
     161                 : /// is a valid register name according to GCC. This is used by Sema for
     162                 : /// inline asm statements.
     163               73: bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const {
                        0: branch 1 not taken
                       73: branch 2 taken
     164               73:   if (Name.empty())
     165                0:     return false;
     166                 :   
     167                 :   const char * const *Names;
     168                 :   unsigned NumNames;
     169                 : 
     170                 :   // Get rid of any register prefix.
     171               73:   Name = removeGCCRegisterPrefix(Name);
     172                 : 
                       69: branch 2 taken
                        4: branch 3 taken
                        2: branch 6 taken
                       67: branch 7 taken
                        6: branch 8 taken
                       67: branch 9 taken
     173               73:   if (Name == "memory" || Name == "cc")
     174                6:     return true;
     175                 : 
     176               67:   getGCCRegNames(Names, NumNames);
     177                 : 
     178                 :   // If we have a number it maps to an entry in the register name array.
                       11: branch 1 taken
                       56: branch 2 taken
     179               67:   if (isdigit(Name[0])) {
     180                 :     int n;
                       11: branch 1 taken
                        0: branch 2 not taken
     181               11:     if (!Name.getAsInteger(0, n))
                       11: branch 0 taken
                        0: branch 1 not taken
                       10: branch 2 taken
                        1: branch 3 taken
     182               11:       return n >= 0 && (unsigned)n < NumNames;
     183                 :   }
     184                 : 
     185                 :   // Check register names.
                     1134: branch 0 taken
                       31: branch 1 taken
     186             1165:   for (unsigned i = 0; i < NumNames; i++) {
                       25: branch 2 taken
                     1109: branch 3 taken
     187             1134:     if (Name == Names[i])
     188               25:       return true;
     189                 :   }
     190                 : 
     191                 :   // Now check aliases.
     192                 :   const GCCRegAlias *Aliases;
     193                 :   unsigned NumAliases;
     194                 : 
     195               31:   getGCCRegAliases(Aliases, NumAliases);
                      110: branch 0 taken
                        3: branch 1 taken
     196              113:   for (unsigned i = 0; i < NumAliases; i++) {
                      258: branch 1 taken
                        0: branch 2 not taken
     197              258:     for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
                       82: branch 0 taken
                      176: branch 1 taken
     198              258:       if (!Aliases[i].Aliases[j])
     199               82:         break;
                       28: branch 2 taken
                      148: branch 3 taken
     200              176:       if (Aliases[i].Aliases[j] == Name)
     201               28:         return true;
     202                 :     }
     203                 :   }
     204                 : 
     205                3:   return false;
     206                 : }
     207                 : 
     208                 : llvm::StringRef 
     209               18: TargetInfo::getNormalizedGCCRegisterName(llvm::StringRef Name) const {
                       18: branch 1 taken
                        0: branch 2 not taken
     210               18:   assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
     211                 : 
     212                 :   // Get rid of any register prefix.
     213               18:   Name = removeGCCRegisterPrefix(Name);
     214                 : 
     215                 :   const char * const *Names;
     216                 :   unsigned NumNames;
     217                 : 
     218               18:   getGCCRegNames(Names, NumNames);
     219                 : 
     220                 :   // First, check if we have a number.
                        0: branch 1 not taken
                       18: branch 2 taken
     221               18:   if (isdigit(Name[0])) {
     222                 :     int n;
                        0: branch 1 not taken
                        0: branch 2 not taken
     223                0:     if (!Name.getAsInteger(0, n)) {
     224                 :       assert(n >= 0 && (unsigned)n < NumNames &&
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
     225                0:              "Out of bounds register number!");
     226                0:       return Names[n];
     227                 :     }
     228                 :   }
     229                 : 
     230                 :   // Now check aliases.
     231                 :   const GCCRegAlias *Aliases;
     232                 :   unsigned NumAliases;
     233                 : 
     234               18:   getGCCRegAliases(Aliases, NumAliases);
                      197: branch 0 taken
                       10: branch 1 taken
     235              207:   for (unsigned i = 0; i < NumAliases; i++) {
                      396: branch 1 taken
                        0: branch 2 not taken
     236              396:     for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
                      189: branch 0 taken
                      207: branch 1 taken
     237              396:       if (!Aliases[i].Aliases[j])
     238              189:         break;
                        8: branch 2 taken
                      199: branch 3 taken
     239              207:       if (Aliases[i].Aliases[j] == Name)
     240                8:         return Aliases[i].Register;
     241                 :     }
     242                 :   }
     243                 : 
     244               10:   return Name;
     245                 : }
     246                 : 
     247               57: bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
     248               57:   const char *Name = Info.getConstraintStr().c_str();
     249                 :   // An output constraint must start with '=' or '+'
                       18: branch 0 taken
                       39: branch 1 taken
                        0: branch 2 not taken
                       18: branch 3 taken
     250               57:   if (*Name != '=' && *Name != '+')
     251                0:     return false;
     252                 : 
                       18: branch 0 taken
                       39: branch 1 taken
     253               57:   if (*Name == '+')
     254               18:     Info.setIsReadWrite();
     255                 : 
     256               57:   Name++;
                       63: branch 0 taken
                       57: branch 1 taken
     257              177:   while (*Name) {
                       27: branch 0 taken
                        4: branch 1 taken
                        2: branch 2 taken
                       24: branch 3 taken
                        6: branch 4 taken
                        0: branch 5 not taken
     258               63:     switch (*Name) {
     259                 :     default:
                        0: branch 1 not taken
                       27: branch 2 taken
     260               27:       if (!validateAsmConstraint(Name, Info)) {
     261                 :         // FIXME: We temporarily return false
     262                 :         // so we can add more constraints as we hit it.
     263                 :         // Eventually, an unknown constraint should just be treated as 'g'.
     264                0:         return false;
     265                 :       }
     266                 :     case '&': // early clobber.
     267               31:       break;
     268                 :     case '%': // commutative.
     269                 :       // FIXME: Check that there is a another register after this one.
     270                2:       break;
     271                 :     case 'r': // general register.
     272               24:       Info.setAllowsRegister();
     273               24:       break;
     274                 :     case 'm': // memory operand.
     275                6:       Info.setAllowsMemory();
     276                6:       break;
     277                 :     case 'g': // general register, memory operand or immediate integer.
     278                 :     case 'X': // any operand.
     279                0:       Info.setAllowsRegister();
     280                0:       Info.setAllowsMemory();
     281                 :       break;
     282                 :     }
     283                 : 
     284               63:     Name++;
     285                 :   }
     286                 : 
     287               57:   return true;
     288                 : }
     289                 : 
     290                 : bool TargetInfo::resolveSymbolicName(const char *&Name,
     291                 :                                      ConstraintInfo *OutputConstraints,
     292                 :                                      unsigned NumOutputs,
     293                6:                                      unsigned &Index) const {
                        0: branch 0 not taken
                        6: branch 1 taken
     294                6:   assert(*Name == '[' && "Symbolic name did not start with '['");
     295                6:   Name++;
     296                6:   const char *Start = Name;
                       59: branch 0 taken
                        2: branch 1 taken
                       55: branch 2 taken
                        4: branch 3 taken
     297               67:   while (*Name && *Name != ']')
     298               55:     Name++;
     299                 : 
                        2: branch 0 taken
                        4: branch 1 taken
     300                6:   if (!*Name) {
     301                 :     // Missing ']'
     302                2:     return false;
     303                 :   }
     304                 : 
     305                4:   std::string SymbolicName(Start, Name - Start);
     306                 : 
                        4: branch 0 taken
                        1: branch 1 taken
     307                5:   for (Index = 0; Index != NumOutputs; ++Index)
                        3: branch 2 taken
                        1: branch 3 taken
     308                4:     if (SymbolicName == OutputConstraints[Index].getName())
     309                3:       return true;
     310                 : 
     311                1:   return false;
     312                 : }
     313                 : 
     314                 : bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
     315                 :                                          unsigned NumOutputs,
     316               73:                                          ConstraintInfo &Info) const {
     317               73:   const char *Name = Info.ConstraintStr.c_str();
     318                 : 
                       78: branch 0 taken
                       70: branch 1 taken
     319              221:   while (*Name) {
                       34: branch 0 taken
                        6: branch 1 taken
                        0: branch 2 not taken
                       11: branch 3 taken
                        0: branch 4 not taken
                       11: branch 5 taken
                       15: branch 6 taken
                        1: branch 7 taken
     320               78:     switch (*Name) {
     321                 :     default:
     322                 :       // Check if we have a matching constraint
                       34: branch 0 taken
                        0: branch 1 not taken
                       11: branch 2 taken
                       23: branch 3 taken
     323               45:       if (*Name >= '0' && *Name <= '9') {
     324               11:         unsigned i = *Name - '0';
     325                 : 
     326                 :         // Check if matching constraint is out of bounds.
                        0: branch 0 not taken
                       11: branch 1 taken
     327               11:         if (i >= NumOutputs)
     328                0:           return false;
     329                 : 
     330                 :         // The constraint should have the same info as the respective
     331                 :         // output constraint.
     332               11:         Info.setTiedOperand(i, OutputConstraints[i]);
                        0: branch 1 not taken
                       23: branch 2 taken
     333               23:       } else if (!validateAsmConstraint(Name, Info)) {
     334                 :         // FIXME: This error return is in place temporarily so we can
     335                 :         // add more constraints as we hit it.  Eventually, an unknown
     336                 :         // constraint should just be treated as 'g'.
     337                0:         return false;
     338                 :       }
     339               34:       break;
     340                 :     case '[': {
     341                6:       unsigned Index = 0;
                        3: branch 1 taken
                        3: branch 2 taken
     342                6:       if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
     343                3:         return false;
     344                 : 
     345                3:       break;
     346                 :     }
     347                 :     case '%': // commutative
     348                 :       // FIXME: Fail if % is used with the last operand.
     349                0:       break;
     350                 :     case 'i': // immediate integer.
     351                 :     case 'n': // immediate integer with a known value.
     352               11:       break;
     353                 :     case 'I':  // Various constant constraints with target-specific meanings.
     354                 :     case 'J':
     355                 :     case 'K':
     356                 :     case 'L':
     357                 :     case 'M':
     358                 :     case 'N':
     359                 :     case 'O':
     360                 :     case 'P':
     361                0:       break;
     362                 :     case 'r': // general register.
     363               11:       Info.setAllowsRegister();
     364               11:       break;
     365                 :     case 'm': // memory operand.
     366                 :     case 'o': // offsettable memory operand
     367                 :     case 'V': // non-offsettable memory operand
     368               15:       Info.setAllowsMemory();
     369               15:       break;
     370                 :     case 'g': // general register, memory operand or immediate integer.
     371                 :     case 'X': // any operand.
     372                1:       Info.setAllowsRegister();
     373                1:       Info.setAllowsMemory();
     374                 :       break;
     375                 :     }
     376                 : 
     377               75:     Name++;
     378                 :   }
     379                 : 
     380               70:   return true;
     381                 : }

Generated: 2010-02-10 01:31 by zcov