Woot! Fun stuff. :-) Thanks Dale.
Evan On May 1, 2007, at 6:03 PM, Dale Johannesen wrote: > > > Changes in directory llvm/lib/Target/ARM: > > ARMTargetAsmInfo.h updated: 1.3 -> 1.4 > ARMTargetAsmInfo.cpp updated: 1.18 -> 1.19 > --- > Log message: > > Add some support for (Darwin) code-generating directives in > getInlineAsmLength. > Support is incomplete, but more accurate than gcc's. > > > --- > Diffs of the changes: (+115 -18) > > ARMTargetAsmInfo.cpp | 128 +++++++++++++++++++++++++++++++++++++++ > +++++------- > ARMTargetAsmInfo.h | 5 + > 2 files changed, 115 insertions(+), 18 deletions(-) > > > Index: llvm/lib/Target/ARM/ARMTargetAsmInfo.h > diff -u llvm/lib/Target/ARM/ARMTargetAsmInfo.h:1.3 llvm/lib/Target/ > ARM/ARMTargetAsmInfo.h:1.4 > --- llvm/lib/Target/ARM/ARMTargetAsmInfo.h:1.3 Sun Apr 29 14:17:45 > 2007 > +++ llvm/lib/Target/ARM/ARMTargetAsmInfo.h Tue May 1 20:02:40 2007 > @@ -15,6 +15,7 @@ > #define ARMTARGETASMINFO_H > > #include "llvm/Target/TargetAsmInfo.h" > +#include "ARMSubtarget.h" > > namespace llvm { > > @@ -24,9 +25,11 @@ > struct ARMTargetAsmInfo : public TargetAsmInfo { > ARMTargetAsmInfo(const ARMTargetMachine &TM); > > - bool isThumb; > + const ARMSubtarget *Subtarget; > > virtual unsigned getInlineAsmLength(const char *Str) const; > + unsigned countArguments(const char *p) const; > + unsigned countString(const char *p) const; > }; > > > > > Index: llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp > diff -u llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.18 llvm/lib/ > Target/ARM/ARMTargetAsmInfo.cpp:1.19 > --- llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.18 Sun Apr 29 > 19:30:48 2007 > +++ llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp Tue May 1 20:02:40 2007 > @@ -1,3 +1,4 @@ > + > //===-- ARMTargetAsmInfo.cpp - ARM asm properties --------------- > *- C++ -*-===// > // > // The LLVM Compiler Infrastructure > @@ -18,7 +19,7 @@ > using namespace llvm; > > ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) { > - const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>(); > + Subtarget = &TM.getSubtarget<ARMSubtarget>(); > if (Subtarget->isTargetDarwin()) { > GlobalPrefix = "_"; > PrivateGlobalPrefix = "L"; > @@ -85,13 +86,42 @@ > InlineAsmStart = "@ InlineAsm Start"; > InlineAsmEnd = "@ InlineAsm End"; > LCOMMDirective = "\t.lcomm\t"; > - isThumb = Subtarget->isThumb(); > +} > + > +/// Count the number of comma-separated arguments. > +/// Do not try to detect errors. > +unsigned ARMTargetAsmInfo::countArguments(const char* p) const { > + unsigned count = 0; > + while (*p && isspace(*p) && *p != '\n') > + p++; > + count++; > + while (*p && *p!='\n' && > + strncmp(p, CommentString, strlen(CommentString))!=0) { > + if (*p==',') > + count++; > + p++; > + } > + return count; > +} > + > +/// Count the length of a string enclosed in quote characters. > +/// Do not try to detect errors. > +unsigned ARMTargetAsmInfo::countString(const char* p) const { > + unsigned count = 0; > + while (*p && isspace(*p) && *p!='\n') > + p++; > + if (!*p || *p != '\"') > + return count; > + while (*++p && *p != '\"') > + count++; > + return count; > } > > /// ARM-specific version of TargetAsmInfo::getInlineAsmLength. > unsigned ARMTargetAsmInfo::getInlineAsmLength(const char *Str) > const { > // Count the number of bytes in the asm. > bool atInsnStart = true; > + bool inTextSection = true; > unsigned Length = 0; > for (; *Str; ++Str) { > if (atInsnStart) { > @@ -102,30 +132,94 @@ > for (const char* p = Str; *p && !isspace(*p); p++) > if (*p == ':') { > Str = p+1; > + while (*Str && isspace(*Str) && *Str != '\n') > + Str++; > break; > } > // Ignore everything from comment char(s) to EOL > if (strncmp(Str, CommentString, strlen(CommentString))==-0) > atInsnStart = false; > - else { > + // FIXME do something like the following for non-Darwin > + else if (*Str == '.' && Subtarget->isTargetDarwin()) { > + // Directive. > + atInsnStart = false; > + // Some change the section, but don't generate code. > + if (strncasecmp(Str, ".literal4", strlen(".literal4"))==0 || > + strncasecmp(Str, ".literal8", strlen(".literal8"))==0 || > + strncasecmp(Str, ".const", strlen(".const"))==0 || > + strncasecmp(Str, ".constructor", strlen > (".constructor"))==0 || > + strncasecmp(Str, ".cstring", strlen(".cstring"))==0 || > + strncasecmp(Str, ".data", strlen(".data"))==0 || > + strncasecmp(Str, ".destructor", strlen(".destructor")) > ==0 || > + strncasecmp(Str, ".fvmlib_init0", strlen > (".fvmlib_init0"))==0 || > + strncasecmp(Str, ".fvmlib_init1", strlen > (".fvmlib_init1"))==0 || > + strncasecmp(Str, ".mod_init_func", strlen > (".mod_init_func"))==0 || > + strncasecmp(Str, ".mod_term_func", strlen > (".mod_term_func"))==0 || > + strncasecmp(Str, ".picsymbol_stub", strlen > (".picsymbol_stub"))==0 || > + strncasecmp(Str, ".symbol_stub", strlen > (".symbol_stub"))==0 || > + strncasecmp(Str, ".static_data", strlen > (".static_data"))==0 || > + strncasecmp(Str, ".section", strlen(".section"))==0 || > + strncasecmp(Str, ".lazy_symbol_pointer", strlen > (".lazy_symbol_pointer"))==0 || > + strncasecmp(Str, ".non_lazy_symbol_pointer", strlen > (".non_lazy_symbol_pointer"))==0 || > + strncasecmp(Str, ".dyld", strlen(".dyld"))==0 || > + strncasecmp(Str, ".const_data", strlen(".const_data")) > ==0 || > + strncasecmp(Str, ".objc", strlen(".objc"))==0 > || //// many directives > + strncasecmp(Str, ".static_const", strlen > (".static_const"))==0) > + inTextSection=false; > + else if (strncasecmp(Str, ".text", strlen(".text"))==0) > + inTextSection = true; > + // Some can't really be handled without implementing > significant pieces > + // of an assembler. Others require dynamic adjustment of > block sizes in > + // AdjustBBOffsetsAfter; it's a big compile-time speed hit > to check every > + // instruction in there, and none of these are currently > used in the kernel. > + else if (strncasecmp(Str, ".macro", strlen(".macro"))==0 || > + strncasecmp(Str, ".if", strlen(".if"))==0 || > + strncasecmp(Str, ".align", strlen(".align"))==0 || > + strncasecmp(Str, ".fill", strlen(".fill"))==0 || > + strncasecmp(Str, ".space", strlen(".space"))==0 || > + strncasecmp(Str, ".zerofill", strlen(".zerofill")) > ==0 || > + strncasecmp(Str, ".p2align", strlen(".p2align")) > ==0 || > + strncasecmp(Str, ".p2alignw", strlen(".p2alignw")) > ==0 || > + strncasecmp(Str, ".p2alignl", strlen(".p2alignl")) > ==0 || > + strncasecmp(Str, ".align32", strlen(".p2align32")) > ==0 || > + strncasecmp(Str, ".include", strlen(".include"))==0) > + cerr << "Directive " << Str << " in asm may lead to > invalid offsets for" << > + " constant pools (the assembler will tell you > if this happens).\n"; > + // Some generate code, but this is only interesting in the > text section. > + else if (inTextSection) { > + if (strncasecmp(Str, ".long", strlen(".long"))==0) > + Length += 4*countArguments(Str+strlen(".long")); > + else if (strncasecmp(Str, ".short", strlen(".short"))==0) > + Length += 2*countArguments(Str+strlen(".short")); > + else if (strncasecmp(Str, ".byte", strlen(".byte"))==0) > + Length += 1*countArguments(Str+strlen(".byte")); > + else if (strncasecmp(Str, ".single", strlen(".single"))==0) > + Length += 4*countArguments(Str+strlen(".single")); > + else if (strncasecmp(Str, ".double", strlen(".double"))==0) > + Length += 8*countArguments(Str+strlen(".double")); > + else if (strncasecmp(Str, ".quad", strlen(".quad"))==0) > + Length += 16*countArguments(Str+strlen(".quad")); > + else if (strncasecmp(Str, ".ascii", strlen(".ascii"))==0) > + Length += countString(Str+strlen(".ascii")); > + else if (strncasecmp(Str, ".asciz", strlen(".asciz"))==0) > + Length += countString(Str+strlen(".asciz"))+1; > + } > + } else if (inTextSection) { > // An instruction > atInsnStart = false; > - if (isThumb) { > + if (Subtarget->isThumb()) { > // BL and BLX <non-reg> are 4 bytes, all others 2. > - 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 > - } > + if (strncasecmp(Str, "blx", strlen("blx"))==0) { > + const char* p = Str+3; > + while (*p && isspace(*p)) > + p++; > + if (*p == 'r' || *p=='R') > + Length += 2; // BLX reg > else > - Length += 4; // BL > - } else > + Length += 4; // BLX non-reg > + } else if (strncasecmp(Str, "bl", strlen("bl"))==0) > + Length += 4; // BL > + else > Length += 2; // Thumb anything else > } > else > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits