Skip to content

Commit

Permalink
This patch enables the usage of constant Enum identifiers within Micr…
Browse files Browse the repository at this point in the history
…osoft style inline assembly statements.

Differential Revision:
https://reviews.llvm.org/D33277
https://reviews.llvm.org/D33278

llvm-svn: 308965
  • Loading branch information
Matan Haroush committed Jul 25, 2017
1 parent cd2255e commit b4b8d10
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 15 deletions.
22 changes: 16 additions & 6 deletions clang/lib/Sema/SemaStmtAsm.cpp
Expand Up @@ -645,8 +645,8 @@ ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
// Referring to parameters is not allowed in naked functions.
if (CheckNakedParmReference(Result.get(), *this))
return ExprError();

QualType T = Result.get()->getType();
Expr *Res = Result.get();
QualType T = Res->getType();

if (T->isDependentType()) {
return Result;
Expand All @@ -658,16 +658,26 @@ ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
}

// Otherwise, it needs to be a complete type.
if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) {
if (RequireCompleteExprType(Res, diag::err_asm_incomplete_type)) {
return ExprError();
}

fillInlineAsmTypeInfo(Context, T, Info);

// We can work with the expression as long as it's not an r-value.
if (!Result.get()->isRValue())
Info.IsVarDecl = true;
if (!Res->isRValue()) {
Info.setKindVariable();
return Result;
}

Expr::EvalResult EvlResult;
// Try to evaluate the identifier as enum constant, currently we do not allow
// other constant integers to be folded.
if (isa<clang::EnumType>(T) &&
Res->EvaluateAsRValue(EvlResult, getASTContext())) {
Info.ConstIntValue = EvlResult.Val.getInt();
Info.setKindConstEnum();
}
return Result;
}

Expand Down Expand Up @@ -774,7 +784,7 @@ Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member,
fillInlineAsmTypeInfo(Context, Result.get()->getType(), Info);

// Fields are "variables" as far as inline assembly is concerned.
Info.IsVarDecl = true;
Info.setKindVariable();

return Result;
}
Expand Down
14 changes: 7 additions & 7 deletions clang/test/CodeGen/ms-inline-asm.c
Expand Up @@ -42,7 +42,7 @@ void t5(void) {
void t6(void) {
__asm int 0x2c
// CHECK: t6
// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"()
}

void t7() {
Expand All @@ -61,7 +61,7 @@ void t7() {
mov eax, ebx
}
// CHECK: t7
// CHECK: call void asm sideeffect inteldialect "int $$0x2cU", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "mov eax, ebx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
Expand Down Expand Up @@ -94,7 +94,7 @@ void t9() {
// CHECK: t9
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
// CHECK-SAME: mov ebx, $$0x07
// CHECK-SAME: mov ebx, $$7
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
Expand Down Expand Up @@ -265,7 +265,7 @@ void t21() {
// CHECK: t21
// CHECK: call void asm sideeffect inteldialect
// CHECK-SAME: push ebx
// CHECK-SAME: mov ebx, $$07H
// CHECK-SAME: mov ebx, $$7
// CHECK-SAME: pop ebx
// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
Expand Down Expand Up @@ -312,13 +312,13 @@ void t24() {
void t25() {
// CHECK: t25
__asm mov eax, 0ffffffffh
// CHECK: mov eax, $$0ffffffffh
// CHECK: mov eax, $$4294967295
__asm mov eax, 0fhU
// CHECK: mov eax, $$15
__asm mov eax, 0a2h
// CHECK: mov eax, $$0a2h
// CHECK: mov eax, $$162
__asm mov eax, 10100010b
// CHECK: mov eax, $$10100010b
// CHECK: mov eax, $$162
__asm mov eax, 10100010BU
// CHECK: mov eax, $$162
// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
Expand Down
60 changes: 60 additions & 0 deletions clang/test/CodeGen/x86-ms-inline-asm-enum_feature.cpp
@@ -0,0 +1,60 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 %s -fasm-blocks -emit-llvm -o - | FileCHECK %s
namespace x {
enum { A = 12 };
struct y_t {
enum { A = 17 };
int r;
} y;
}
// CHECK-LABEL: x86_enum_only
void x86_enum_only(){
const int a = 0;
// CHECK-NOT: mov eax, [$$0]
// Other constant type folding is currently unwanted.
__asm mov eax, [a]
}

// CHECK-LABEL: x86_enum_namespaces
void x86_enum_namespaces() {
enum { A = 1 };
// CHECK: call void asm
// CHECK-SAME: mov eax, $$12
__asm mov eax, x::A
// CHECK-SAME: mov eax, $$17
__asm mov eax, x::y_t::A
// CHECK-NEXT: call void asm
// CHECK-SAME: mov eax, $$1
__asm {mov eax, A}
}

// CHECK-LABEL: x86_enum_arithmethic
void x86_enum_arithmethic() {
enum { A = 1, B };
// CHECK: call void asm
// CHECK-SAME: mov eax, $$21
__asm mov eax, (A + 9) * 2 + A
// CHECK-SAME: mov eax, $$4
__asm mov eax, A << 2
// CHECK-SAME: mov eax, $$2
__asm mov eax, B & 3
// CHECK-SAME: mov eax, $$5
__asm mov eax, 3 + (B & 3)
// CHECK-SAME: mov eax, $$8
__asm mov eax, 2 << A * B
}

// CHECK-LABEL: x86_enum_mem
void x86_enum_mem() {
int arr[4];
enum { A = 4, B };
// CHECK: call void asm
// CHECK-SAME: mov eax, [($$12 + $$9) + $$4 * $$5 + $$3 + $$3 + eax]
__asm { mov eax, [(x::A + 9) + A * B + 3 + 3 + eax] }
// CHECK-NEXT: call void asm
// CHECK-SAME: mov eax, dword ptr $$4$0
__asm { mov eax, dword ptr [arr + A] }
// CHECK-NEXT: call void asm
// CHECK-SAME: mov eax, dword ptr $$8$0
__asm { mov eax, dword ptr A[arr + A] }
}
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/ms-inline-asm-return.cpp
Expand Up @@ -70,7 +70,7 @@ FourChars f_s4() {
}
}
// CHECK-LABEL: define i32 @f_s4()
// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$0x01010101", "={eax},~{eax},{{.*}}"
// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$16843009", "={eax},~{eax},{{.*}}"
// CHECK: store i32 %[[r]], i32* %{{.*}}
// CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}}
// CHECK: ret i32 %[[r_i32]]
Expand All @@ -85,7 +85,7 @@ EightChars f_s8() {
}
}
// CHECK-LABEL: define i64 @f_s8()
// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$01010101h\0A\09mov edx, $$01010101b", "=A,~{eax},{{.*}}"
// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$16843009\0A\09mov edx, $$85", "=A,~{eax},{{.*}}"
// CHECK: store i64 %[[r]], i64* %{{.*}}
// CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}}
// CHECK: ret i64 %[[r_i64]]
Expand Down

0 comments on commit b4b8d10

Please sign in to comment.