mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-24 12:20:00 +00:00
[ms-inline asm] Add support for the [] operator. Essentially, [expr1][expr2] is
equivalent to [expr1 + expr2]. See test cases for more examples. rdar://12470392 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166949 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2459bf2427
commit
2fbc239e4f
@ -695,6 +695,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
if (getLexer().isNot(AsmToken::RBrac))
|
||||
return ErrorOperand(Start, "Expected ']' token!");
|
||||
Parser.Lex();
|
||||
End = Tok.getLoc();
|
||||
return X86Operand::CreateMem(Disp, Start, End, Size);
|
||||
}
|
||||
} else if (getLexer().is(AsmToken::Integer)) {
|
||||
@ -704,6 +705,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
if (getLexer().is(AsmToken::RBrac)) {
|
||||
// Handle '[' number ']'
|
||||
Parser.Lex();
|
||||
End = Tok.getLoc();
|
||||
const MCExpr *Disp = MCConstantExpr::Create(Val, getContext());
|
||||
if (SegReg)
|
||||
return X86Operand::CreateMem(SegReg, Disp, 0, 0, Scale,
|
||||
@ -720,9 +722,20 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
return ErrorOperand(Loc, "Unexpected token");
|
||||
}
|
||||
|
||||
if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
|
||||
bool isPlus = getLexer().is(AsmToken::Plus);
|
||||
// Parse ][ as a plus.
|
||||
bool ExpectRBrac = true;
|
||||
if (getLexer().is(AsmToken::RBrac)) {
|
||||
ExpectRBrac = false;
|
||||
Parser.Lex();
|
||||
End = Tok.getLoc();
|
||||
}
|
||||
|
||||
if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus) ||
|
||||
getLexer().is(AsmToken::LBrac)) {
|
||||
ExpectRBrac = true;
|
||||
bool isPlus = getLexer().is(AsmToken::Plus) ||
|
||||
getLexer().is(AsmToken::LBrac);
|
||||
Parser.Lex();
|
||||
SMLoc PlusLoc = Tok.getLoc();
|
||||
if (getLexer().is(AsmToken::Integer)) {
|
||||
int64_t Val = Tok.getIntVal();
|
||||
@ -746,15 +759,29 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
else if (getParser().ParseExpression(Disp, End)) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse ][ as a plus.
|
||||
if (getLexer().is(AsmToken::RBrac)) {
|
||||
ExpectRBrac = false;
|
||||
Parser.Lex();
|
||||
End = Tok.getLoc();
|
||||
if (getLexer().is(AsmToken::LBrac)) {
|
||||
ExpectRBrac = true;
|
||||
Parser.Lex();
|
||||
if (getParser().ParseExpression(Disp, End))
|
||||
return 0;
|
||||
}
|
||||
} else if (ExpectRBrac) {
|
||||
if (getParser().ParseExpression(Disp, End))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (getLexer().isNot(AsmToken::RBrac))
|
||||
if (getParser().ParseExpression(Disp, End)) return 0;
|
||||
|
||||
End = Tok.getLoc();
|
||||
if (getLexer().isNot(AsmToken::RBrac))
|
||||
return ErrorOperand(End, "expected ']' token!");
|
||||
Parser.Lex();
|
||||
End = Tok.getLoc();
|
||||
if (ExpectRBrac) {
|
||||
if (getLexer().isNot(AsmToken::RBrac))
|
||||
return ErrorOperand(End, "expected ']' token!");
|
||||
Parser.Lex();
|
||||
End = Tok.getLoc();
|
||||
}
|
||||
|
||||
// Parse the dot operator (e.g., [ebx].foo.bar).
|
||||
if (Tok.getString().startswith(".")) {
|
||||
|
@ -61,3 +61,110 @@ entry:
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
}
|
||||
|
||||
define void @t21() nounwind {
|
||||
; CHECK: t21
|
||||
entry:
|
||||
br label %foo
|
||||
|
||||
foo: ; preds = %entry
|
||||
call void asm sideeffect inteldialect "mov eax, [4*eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [4*eax + 4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [4*eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [4*eax][4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi + eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi + eax]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi][eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi][eax]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi + 4*eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi + 4*eax]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi][4*eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi][4*eax]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi + eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi + eax + 4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi][eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi][eax + 4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi + eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi + eax][4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi][eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi][eax][4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi + 2*eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi + 2*eax + 4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi][2*eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi][2*eax + 4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi + 2*eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi + 2*eax][4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
call void asm sideeffect inteldialect "mov eax, [esi][2*eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
|
||||
; CHECK: {{## InlineAsm Start|#APP}}
|
||||
; CHECK: .intel_syntax
|
||||
; CHECK: mov eax, [esi][2*eax][4]
|
||||
; CHECK: .att_syntax
|
||||
; CHECK: {{## InlineAsm End|#NO_APP}}
|
||||
|
||||
ret void
|
||||
}
|
||||
|
@ -8,3 +8,53 @@ mov [ebx].4, ecx
|
||||
// CHECK: movl %ecx, 4(%ebx)
|
||||
// CHECK: encoding: [0x89,0x4b,0x04]
|
||||
|
||||
_t21: ## @t21
|
||||
// CHECK: t21
|
||||
mov eax, [4*eax + 4]
|
||||
// CHECK: movl 4(,%eax,4), %eax
|
||||
// CHECK: # encoding: [0x8b,0x04,0x85,0x04,0x00,0x00,0x00]
|
||||
mov eax, [4*eax][4]
|
||||
// CHECK: movl 4(,%eax,4), %eax
|
||||
// CHECK: # encoding: [0x8b,0x04,0x85,0x04,0x00,0x00,0x00]
|
||||
|
||||
mov eax, [esi + eax]
|
||||
// CHECK: movl (%esi,%eax), %eax
|
||||
// CHECK: # encoding: [0x8b,0x04,0x06]
|
||||
mov eax, [esi][eax]
|
||||
// CHECK: movl (%esi,%eax), %eax
|
||||
// CHECK: # encoding: [0x8b,0x04,0x06]
|
||||
|
||||
mov eax, [esi + 4*eax]
|
||||
// CHECK: movl (%esi,%eax,4), %eax
|
||||
// CHECK: # encoding: [0x8b,0x04,0x86]
|
||||
mov eax, [esi][4*eax]
|
||||
// CHECK: movl (%esi,%eax,4), %eax
|
||||
// CHECK: # encoding: [0x8b,0x04,0x86]
|
||||
|
||||
mov eax, [esi + eax + 4]
|
||||
// CHECK: movl 4(%esi,%eax), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
|
||||
mov eax, [esi][eax + 4]
|
||||
// CHECK: movl 4(%esi,%eax), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
|
||||
mov eax, [esi + eax][4]
|
||||
// CHECK: movl 4(%esi,%eax), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
|
||||
mov eax, [esi][eax][4]
|
||||
// CHECK: movl 4(%esi,%eax), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
|
||||
|
||||
mov eax, [esi + 2*eax + 4]
|
||||
// CHECK: movl 4(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
|
||||
mov eax, [esi][2*eax + 4]
|
||||
// CHECK: movl 4(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
|
||||
mov eax, [esi + 2*eax][4]
|
||||
// CHECK: movl 4(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
|
||||
mov eax, [esi][2*eax][4]
|
||||
// CHECK: movl 4(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
|
||||
|
||||
ret
|
||||
|
Loading…
Reference in New Issue
Block a user