From: Saleem Abdulrasool Date: Wed, 18 Jun 2014 20:57:28 +0000 (+0000) Subject: MCAsmParser: full support for gas' '.if{cond} expression' directives X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;ds=sidebyside;h=791ff5af548986d9ba11f6847421c4478a85f4c7;p=oota-llvm.git MCAsmParser: full support for gas' '.if{cond} expression' directives Patch by Janne Grunau! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211218 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index cbff7beccae..932d0f3318e 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -345,8 +345,9 @@ private: DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, - DK_IF, DK_IFNE, DK_IFB, DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, - DK_IFNDEF, DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF, + DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB, + DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, + DK_ELSEIF, DK_ELSE, DK_ENDIF, DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, @@ -433,8 +434,8 @@ private: bool parseDirectiveInclude(); // ".include" bool parseDirectiveIncbin(); // ".incbin" - // ".if" or ".ifne" - bool parseDirectiveIf(SMLoc DirectiveLoc); + // ".if", ".ifeq", ".ifge", ".ifgt" , ".ifle", ".iflt" or ".ifne" + bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind); // ".ifb" or ".ifnb", depending on ExpectBlank. bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); // ".ifc" or ".ifnc", depending on ExpectEqual. @@ -1229,8 +1230,13 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { default: break; case DK_IF: + case DK_IFEQ: + case DK_IFGE: + case DK_IFGT: + case DK_IFLE: + case DK_IFLT: case DK_IFNE: - return parseDirectiveIf(IDLoc); + return parseDirectiveIf(IDLoc, DirKind); case DK_IFB: return parseDirectiveIfb(IDLoc, true); case DK_IFNB: @@ -3792,9 +3798,8 @@ bool AsmParser::parseDirectiveIncbin() { } /// parseDirectiveIf -/// ::= .if expression -/// ::= .ifne expression -bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { +/// ::= .if{,eq,ge,gt,le,lt,ne} expression +bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; if (TheCondState.Ignore) { @@ -3809,6 +3814,29 @@ bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { Lex(); + switch (DirKind) { + default: + llvm_unreachable("unsupported directive"); + case DK_IF: + case DK_IFNE: + break; + case DK_IFEQ: + ExprValue = ExprValue == 0; + break; + case DK_IFGE: + ExprValue = ExprValue >= 0; + break; + case DK_IFGT: + ExprValue = ExprValue > 0; + break; + case DK_IFLE: + ExprValue = ExprValue <= 0; + break; + case DK_IFLT: + ExprValue = ExprValue < 0; + break; + } + TheCondState.CondMet = ExprValue; TheCondState.Ignore = !TheCondState.CondMet; } @@ -4111,6 +4139,11 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; DirectiveKindMap[".if"] = DK_IF; + DirectiveKindMap[".ifeq"] = DK_IFEQ; + DirectiveKindMap[".ifge"] = DK_IFGE; + DirectiveKindMap[".ifgt"] = DK_IFGT; + DirectiveKindMap[".ifle"] = DK_IFLE; + DirectiveKindMap[".iflt"] = DK_IFLT; DirectiveKindMap[".ifne"] = DK_IFNE; DirectiveKindMap[".ifb"] = DK_IFB; DirectiveKindMap[".ifnb"] = DK_IFNB; diff --git a/test/MC/AsmParser/conditional_asm.s b/test/MC/AsmParser/conditional_asm.s index b9bee33c6a1..ecbceb1dc36 100644 --- a/test/MC/AsmParser/conditional_asm.s +++ b/test/MC/AsmParser/conditional_asm.s @@ -11,6 +11,66 @@ .endif .endif +# CHECK: .byte 0 +# CHECK-NOT: .byte 1 +.ifeq 32 - 32 + .byte 0 +.else + .byte 1 +.endif + +# CHECK: .byte 0 +# CHECK: .byte 1 +# CHECK-NOT: .byte 2 +.ifge 32 - 31 + .byte 0 +.endif +.ifge 32 - 32 + .byte 1 +.endif +.ifge 32 - 33 + .byte 2 +.endif + +# CHECK: .byte 0 +# CHECK-NOT: .byte 1 +# CHECK-NOT: .byte 2 +.ifgt 32 - 31 + .byte 0 +.endif +.ifgt 32 - 32 + .byte 1 +.endif +.ifgt 32 - 33 + .byte 2 +.endif + +# CHECK-NOT: .byte 0 +# CHECK: .byte 1 +# CHECK: .byte 2 +.ifle 32 - 31 + .byte 0 +.endif +.ifle 32 - 32 + .byte 1 +.endif +.ifle 32 - 33 + .byte 2 +.endif + +# CHECK-NOT: .byte 0 +# CHECK-NOT: .byte 1 +# CHECK: .byte 2 +.iflt 32 - 31 + .byte 0 +.endif +.iflt 32 - 32 + .byte 1 +.endif +.iflt 32 - 33 + .byte 2 +.endif + # CHECK: .byte 1 # CHECK-NOT: .byte 0 .ifne 32 - 32 diff --git a/test/MC/AsmParser/if-diagnostics.s b/test/MC/AsmParser/if-diagnostics.s new file mode 100644 index 00000000000..d102a5686d9 --- /dev/null +++ b/test/MC/AsmParser/if-diagnostics.s @@ -0,0 +1,29 @@ +// RUN: not llvm-mc -triple i386 %s -o /dev/null 2>&1 | FileCheck %s + +.if +.endif + +// CHECK: error: unknown token in expression +// CHECK: .if +// CHECK: ^ + +.ifeq 0, 3 +.endif + +// CHECK:error: unexpected token in '.if' directive +// CHECK: .ifeq 0, 3 +// CHECK: ^ + +.iflt "string1" +.endif + +// CHECK: error: expected absolute expression +// CHECK: .iflt "string1" +// CHECK: ^ + +.ifge test +.endif + +// CHECK: error: expected absolute expression +// CHECK: .ifge test +// CHECK: ^