From 8650199fbb192c054f85647843b89e1182855718 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sun, 29 Apr 2007 19:17:45 +0000 Subject: [PATCH] Make ARM-specific version of getInlineAsmLength git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36572 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetAsmInfo.h | 2 +- lib/Target/ARM/ARMTargetAsmInfo.cpp | 51 +++++++++++++++++++++++++++++ lib/Target/ARM/ARMTargetAsmInfo.h | 2 ++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index b13a3fb50f4..ceb2a3af475 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -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 diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp index 196348b9e9c..3d24d60c6a6 100644 --- a/lib/Target/ARM/ARMTargetAsmInfo.cpp +++ b/lib/Target/ARM/ARMTargetAsmInfo.cpp @@ -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 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; +} diff --git a/lib/Target/ARM/ARMTargetAsmInfo.h b/lib/Target/ARM/ARMTargetAsmInfo.h index 3fb9bb00661..441be2bd751 100644 --- a/lib/Target/ARM/ARMTargetAsmInfo.h +++ b/lib/Target/ARM/ARMTargetAsmInfo.h @@ -25,6 +25,8 @@ namespace llvm { ARMTargetAsmInfo(const ARMTargetMachine &TM); bool isThumb; + + virtual unsigned getInlineAsmLength(const char *Str) const; };