Make ARM-specific version of getInlineAsmLength
authorDale Johannesen <dalej@apple.com>
Sun, 29 Apr 2007 19:17:45 +0000 (19:17 +0000)
committerDale Johannesen <dalej@apple.com>
Sun, 29 Apr 2007 19:17:45 +0000 (19:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36572 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetAsmInfo.h
lib/Target/ARM/ARMTargetAsmInfo.cpp
lib/Target/ARM/ARMTargetAsmInfo.h

index b13a3fb50f4313faf54a06c940d03a2644275dbb..ceb2a3af475642b33c2a03018252515b3e50d1e6 100644 (file)
@@ -353,7 +353,7 @@ namespace llvm {
 
     /// Measure the specified inline asm to determine an approximation of its
     /// length.
-    unsigned getInlineAsmLength(const char *Str) const;
+    virtual unsigned getInlineAsmLength(const char *Str) const;
 
     /// ExpandInlineAsm - This hook allows the target to expand an inline asm
     /// call to be explicit llvm code if it wants to.  This is useful for
index 196348b9e9c7b4ca0b5611c81a6519fe0fdef37d..3d24d60c6a68aead999a4ccce9f234965216cbba 100644 (file)
@@ -86,3 +86,54 @@ ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
   LCOMMDirective = "\t.lcomm\t";
   isThumb = Subtarget->isThumb();
 }
+
+/// ARM-specific version of TargetAsmInfo::getInlineAsmLength.
+unsigned ARMTargetAsmInfo::getInlineAsmLength(const char *Str) const {
+  // Count the number of bytes in the asm.
+  bool atInsnStart = true;
+  unsigned Length = 0;
+  for (; *Str; ++Str) {
+    if (atInsnStart) {
+      // Skip whitespace
+      while (*Str && isspace(*Str) && *Str != '\n')
+        Str++;
+      // Skip label
+      for (const char* p = Str; *p && !isspace(*p); p++)
+        if (*p == ':') {
+          Str = p+1;
+          break;
+        }
+      // Ignore everything from comment char(s) to EOL
+      if (strncmp(Str, CommentString, strlen(CommentString))==-0)
+        atInsnStart = false;
+      else {
+        // An instruction
+        atInsnStart = false;
+        if (isThumb) {
+          // BL and BLX <non-reg> are 4 bytes, all others 2.
+          const char*p = Str;
+          if ((*Str=='b' || *Str=='B') &&
+              (*(Str+1)=='l' || *(Str+1)=='L')) {
+            if (*(Str+2)=='x' || *(Str+2)=='X') {
+              const char* p = Str+3;
+              while (*p && isspace(*p))
+                p++;
+              if (*p == 'r' || *p=='R')
+                Length += 2;    // BLX reg
+              else
+                Length += 4;    // BLX non-reg
+            }
+            else
+              Length += 4;    // BL
+          } else
+            Length += 2;    // Thumb anything else
+        }
+        else
+          Length += 4;    // ARM
+      }
+    }
+    if (*Str == '\n' || *Str == SeparatorChar)
+      atInsnStart = true;
+  }
+  return Length;
+}
index 3fb9bb006612e712ccfeb9e4dd176a0349892f6b..441be2bd751477d1f0446231aefd0bf51ca22e01 100644 (file)
@@ -25,6 +25,8 @@ namespace llvm {
     ARMTargetAsmInfo(const ARMTargetMachine &TM);
 
     bool isThumb;
+
+    virtual unsigned getInlineAsmLength(const char *Str) const;
   };