mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-30 16:17:05 +00:00
[ms-inline asm] Extend support for parsing Intel bracketed memory operands that
have an arbitrary ordering of the base register, index register and displacement. rdar://12527141 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172484 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -684,115 +684,298 @@ static unsigned getIntelMemOperandSize(StringRef OpStr) {
|
|||||||
return Size;
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum IntelBracExprState {
|
||||||
|
IBES_START,
|
||||||
|
IBES_LBRAC,
|
||||||
|
IBES_RBRAC,
|
||||||
|
IBES_REGISTER,
|
||||||
|
IBES_REGISTER_STAR,
|
||||||
|
IBES_REGISTER_STAR_INTEGER,
|
||||||
|
IBES_INTEGER,
|
||||||
|
IBES_INTEGER_STAR,
|
||||||
|
IBES_INDEX_REGISTER,
|
||||||
|
IBES_IDENTIFIER,
|
||||||
|
IBES_DISP_EXPR,
|
||||||
|
IBES_MINUS,
|
||||||
|
IBES_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
class IntelBracExprStateMachine {
|
||||||
|
IntelBracExprState State;
|
||||||
|
unsigned BaseReg, IndexReg, Scale;
|
||||||
|
int64_t Disp;
|
||||||
|
|
||||||
|
unsigned TmpReg;
|
||||||
|
int64_t TmpInteger;
|
||||||
|
|
||||||
|
bool isPlus;
|
||||||
|
|
||||||
|
public:
|
||||||
|
IntelBracExprStateMachine(MCAsmParser &parser) :
|
||||||
|
State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(0),
|
||||||
|
TmpReg(0), TmpInteger(0), isPlus(true) {}
|
||||||
|
|
||||||
|
unsigned getBaseReg() { return BaseReg; }
|
||||||
|
unsigned getIndexReg() { return IndexReg; }
|
||||||
|
unsigned getScale() { return Scale; }
|
||||||
|
int64_t getDisp() { return Disp; }
|
||||||
|
bool isValidEndState() { return State == IBES_RBRAC; }
|
||||||
|
|
||||||
|
void onPlus() {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_INTEGER:
|
||||||
|
State = IBES_START;
|
||||||
|
if (isPlus)
|
||||||
|
Disp += TmpInteger;
|
||||||
|
else
|
||||||
|
Disp -= TmpInteger;
|
||||||
|
break;
|
||||||
|
case IBES_REGISTER:
|
||||||
|
State = IBES_START;
|
||||||
|
// If we already have a BaseReg, then assume this is the IndexReg with a
|
||||||
|
// scale of 1.
|
||||||
|
if (!BaseReg) {
|
||||||
|
BaseReg = TmpReg;
|
||||||
|
} else {
|
||||||
|
assert (!IndexReg && "BaseReg/IndexReg already set!");
|
||||||
|
IndexReg = TmpReg;
|
||||||
|
Scale = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IBES_INDEX_REGISTER:
|
||||||
|
State = IBES_START;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
isPlus = true;
|
||||||
|
}
|
||||||
|
void onMinus() {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_START:
|
||||||
|
State = IBES_MINUS;
|
||||||
|
break;
|
||||||
|
case IBES_INTEGER:
|
||||||
|
State = IBES_START;
|
||||||
|
if (isPlus)
|
||||||
|
Disp += TmpInteger;
|
||||||
|
else
|
||||||
|
Disp -= TmpInteger;
|
||||||
|
break;
|
||||||
|
case IBES_REGISTER:
|
||||||
|
State = IBES_START;
|
||||||
|
// If we already have a BaseReg, then assume this is the IndexReg with a
|
||||||
|
// scale of 1.
|
||||||
|
if (!BaseReg) {
|
||||||
|
BaseReg = TmpReg;
|
||||||
|
} else {
|
||||||
|
assert (!IndexReg && "BaseReg/IndexReg already set!");
|
||||||
|
IndexReg = TmpReg;
|
||||||
|
Scale = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IBES_INDEX_REGISTER:
|
||||||
|
State = IBES_START;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
isPlus = false;
|
||||||
|
}
|
||||||
|
void onRegister(unsigned Reg) {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_START:
|
||||||
|
State = IBES_REGISTER;
|
||||||
|
TmpReg = Reg;
|
||||||
|
break;
|
||||||
|
case IBES_INTEGER_STAR:
|
||||||
|
assert (!IndexReg && "IndexReg already set!");
|
||||||
|
State = IBES_INDEX_REGISTER;
|
||||||
|
IndexReg = Reg;
|
||||||
|
Scale = TmpInteger;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onDispExpr() {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_START:
|
||||||
|
State = IBES_DISP_EXPR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onInteger(int64_t TmpInt) {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_START:
|
||||||
|
State = IBES_INTEGER;
|
||||||
|
TmpInteger = TmpInt;
|
||||||
|
break;
|
||||||
|
case IBES_MINUS:
|
||||||
|
State = IBES_INTEGER;
|
||||||
|
TmpInteger = TmpInt;
|
||||||
|
break;
|
||||||
|
case IBES_REGISTER_STAR:
|
||||||
|
assert (!IndexReg && "IndexReg already set!");
|
||||||
|
State = IBES_INDEX_REGISTER;
|
||||||
|
IndexReg = TmpReg;
|
||||||
|
Scale = TmpInt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onStar() {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_INTEGER:
|
||||||
|
State = IBES_INTEGER_STAR;
|
||||||
|
break;
|
||||||
|
case IBES_REGISTER:
|
||||||
|
State = IBES_REGISTER_STAR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onLBrac() {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_RBRAC:
|
||||||
|
State = IBES_START;
|
||||||
|
isPlus = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onRBrac() {
|
||||||
|
switch (State) {
|
||||||
|
default:
|
||||||
|
State = IBES_ERROR;
|
||||||
|
break;
|
||||||
|
case IBES_DISP_EXPR:
|
||||||
|
State = IBES_RBRAC;
|
||||||
|
break;
|
||||||
|
case IBES_INTEGER:
|
||||||
|
State = IBES_RBRAC;
|
||||||
|
if (isPlus)
|
||||||
|
Disp += TmpInteger;
|
||||||
|
else
|
||||||
|
Disp -= TmpInteger;
|
||||||
|
break;
|
||||||
|
case IBES_REGISTER:
|
||||||
|
State = IBES_RBRAC;
|
||||||
|
// If we already have a BaseReg, then assume this is the IndexReg with a
|
||||||
|
// scale of 1.
|
||||||
|
if (!BaseReg) {
|
||||||
|
BaseReg = TmpReg;
|
||||||
|
} else {
|
||||||
|
assert (!IndexReg && "BaseReg/IndexReg already set!");
|
||||||
|
IndexReg = TmpReg;
|
||||||
|
Scale = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IBES_INDEX_REGISTER:
|
||||||
|
State = IBES_RBRAC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||||
unsigned Size) {
|
unsigned Size) {
|
||||||
unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
|
|
||||||
const AsmToken &Tok = Parser.getTok();
|
const AsmToken &Tok = Parser.getTok();
|
||||||
SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
|
SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
|
||||||
|
|
||||||
const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
|
|
||||||
// Parse [ BaseReg + Scale*IndexReg + Disp ] or [ symbol ]
|
|
||||||
|
|
||||||
// Eat '['
|
// Eat '['
|
||||||
if (getLexer().isNot(AsmToken::LBrac))
|
if (getLexer().isNot(AsmToken::LBrac))
|
||||||
return ErrorOperand(Start, "Expected '[' token!");
|
return ErrorOperand(Start, "Expected '[' token!");
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
|
unsigned TmpReg = 0;
|
||||||
|
|
||||||
|
// Try to handle '[' 'symbol' ']'
|
||||||
if (getLexer().is(AsmToken::Identifier)) {
|
if (getLexer().is(AsmToken::Identifier)) {
|
||||||
// Parse BaseReg
|
if (ParseRegister(TmpReg, Start, End)) {
|
||||||
if (ParseRegister(BaseReg, Start, End)) {
|
const MCExpr *Disp;
|
||||||
// Handle '[' 'symbol' ']'
|
if (getParser().ParseExpression(Disp, End))
|
||||||
if (getParser().ParseExpression(Disp, End)) return 0;
|
return 0;
|
||||||
|
|
||||||
if (getLexer().isNot(AsmToken::RBrac))
|
if (getLexer().isNot(AsmToken::RBrac))
|
||||||
return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
|
return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
|
||||||
End = Parser.getTok().getEndLoc();
|
End = Parser.getTok().getEndLoc();
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
return X86Operand::CreateMem(Disp, Start, End, Size);
|
return X86Operand::CreateMem(Disp, Start, End, Size);
|
||||||
}
|
}
|
||||||
} else if (getLexer().is(AsmToken::Integer)) {
|
}
|
||||||
|
|
||||||
|
// Parse [ BaseReg + Scale*IndexReg + Disp ].
|
||||||
|
bool Done = false;
|
||||||
|
IntelBracExprStateMachine SM(Parser);
|
||||||
|
|
||||||
|
// If we parsed a register, then the end loc has already been set and
|
||||||
|
// the identifier has already been lexed. We also need to update the
|
||||||
|
// state.
|
||||||
|
if (TmpReg)
|
||||||
|
SM.onRegister(TmpReg);
|
||||||
|
|
||||||
|
const MCExpr *Disp = 0;
|
||||||
|
while (!Done) {
|
||||||
|
bool UpdateLocLex = true;
|
||||||
|
|
||||||
|
// The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
|
||||||
|
// identifier. Don't try an parse it as a register.
|
||||||
|
if (Tok.getString().startswith("."))
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (getLexer().getKind()) {
|
||||||
|
default: {
|
||||||
|
if (SM.isValidEndState()) {
|
||||||
|
Done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ErrorOperand(Tok.getLoc(), "Unexpected token!");
|
||||||
|
}
|
||||||
|
case AsmToken::Identifier: {
|
||||||
|
// This could be a register or a displacement expression.
|
||||||
|
if(!ParseRegister(TmpReg, Start, End)) {
|
||||||
|
SM.onRegister(TmpReg);
|
||||||
|
UpdateLocLex = false;
|
||||||
|
break;
|
||||||
|
} else if (!getParser().ParseExpression(Disp, End)) {
|
||||||
|
SM.onDispExpr();
|
||||||
|
UpdateLocLex = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
|
||||||
|
}
|
||||||
|
case AsmToken::Integer: {
|
||||||
int64_t Val = Tok.getIntVal();
|
int64_t Val = Tok.getIntVal();
|
||||||
Parser.Lex();
|
SM.onInteger(Val);
|
||||||
SMLoc Loc = Tok.getLoc();
|
break;
|
||||||
if (getLexer().is(AsmToken::RBrac)) {
|
|
||||||
// Handle '[' number ']'
|
|
||||||
End = Parser.getTok().getEndLoc();
|
|
||||||
Parser.Lex();
|
|
||||||
const MCExpr *Disp = MCConstantExpr::Create(Val, getContext());
|
|
||||||
if (SegReg)
|
|
||||||
return X86Operand::CreateMem(SegReg, Disp, 0, 0, Scale,
|
|
||||||
Start, End, Size);
|
|
||||||
return X86Operand::CreateMem(Disp, Start, End, Size);
|
|
||||||
} else if (getLexer().is(AsmToken::Star)) {
|
|
||||||
// Handle '[' Scale*IndexReg ']'
|
|
||||||
Parser.Lex();
|
|
||||||
SMLoc IdxRegLoc = Tok.getLoc();
|
|
||||||
if (ParseRegister(IndexReg, IdxRegLoc, End))
|
|
||||||
return ErrorOperand(IdxRegLoc, "Expected register");
|
|
||||||
Scale = Val;
|
|
||||||
} else
|
|
||||||
return ErrorOperand(Loc, "Unexpected token");
|
|
||||||
}
|
}
|
||||||
|
case AsmToken::Plus: SM.onPlus(); break;
|
||||||
// Parse ][ as a plus.
|
case AsmToken::Minus: SM.onMinus(); break;
|
||||||
bool ExpectRBrac = true;
|
case AsmToken::Star: SM.onStar(); break;
|
||||||
if (getLexer().is(AsmToken::RBrac)) {
|
case AsmToken::LBrac: SM.onLBrac(); break;
|
||||||
ExpectRBrac = false;
|
case AsmToken::RBrac: SM.onRBrac(); break;
|
||||||
End = Parser.getTok().getEndLoc();
|
|
||||||
Parser.Lex();
|
|
||||||
}
|
}
|
||||||
|
if (!Done && UpdateLocLex) {
|
||||||
if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus) ||
|
End = Tok.getLoc();
|
||||||
getLexer().is(AsmToken::LBrac)) {
|
Parser.Lex(); // Consume the token.
|
||||||
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();
|
|
||||||
Parser.Lex();
|
|
||||||
if (getLexer().is(AsmToken::Star)) {
|
|
||||||
Parser.Lex();
|
|
||||||
SMLoc IdxRegLoc = Tok.getLoc();
|
|
||||||
if (ParseRegister(IndexReg, IdxRegLoc, End))
|
|
||||||
return ErrorOperand(IdxRegLoc, "Expected register");
|
|
||||||
Scale = Val;
|
|
||||||
} else if (getLexer().is(AsmToken::RBrac)) {
|
|
||||||
const MCExpr *ValExpr = MCConstantExpr::Create(Val, getContext());
|
|
||||||
Disp = isPlus ? ValExpr : MCConstantExpr::Create(0-Val, getContext());
|
|
||||||
} else
|
|
||||||
return ErrorOperand(PlusLoc, "unexpected token after +");
|
|
||||||
} else if (getLexer().is(AsmToken::Identifier)) {
|
|
||||||
// This could be an index register or a displacement expression.
|
|
||||||
if (!IndexReg)
|
|
||||||
ParseRegister(IndexReg, Start, End);
|
|
||||||
else if (getParser().ParseExpression(Disp, End))
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse ][ as a plus.
|
if (!Disp)
|
||||||
if (getLexer().is(AsmToken::RBrac)) {
|
Disp = MCConstantExpr::Create(SM.getDisp(), getContext());
|
||||||
ExpectRBrac = false;
|
|
||||||
End = Parser.getTok().getEndLoc();
|
|
||||||
Parser.Lex();
|
|
||||||
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 (ExpectRBrac) {
|
|
||||||
if (getLexer().isNot(AsmToken::RBrac))
|
|
||||||
return ErrorOperand(End, "expected ']' token!");
|
|
||||||
End = Parser.getTok().getEndLoc();
|
|
||||||
Parser.Lex();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the dot operator (e.g., [ebx].foo.bar).
|
// Parse the dot operator (e.g., [ebx].foo.bar).
|
||||||
if (Tok.getString().startswith(".")) {
|
if (Tok.getString().startswith(".")) {
|
||||||
@@ -806,10 +989,18 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
|||||||
Disp = NewDisp;
|
Disp = NewDisp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle [-42]
|
int BaseReg = SM.getBaseReg();
|
||||||
if (!BaseReg && !IndexReg)
|
int IndexReg = SM.getIndexReg();
|
||||||
return X86Operand::CreateMem(Disp, Start, End, Size);
|
|
||||||
|
|
||||||
|
// handle [-42]
|
||||||
|
if (!BaseReg && !IndexReg) {
|
||||||
|
if (!SegReg)
|
||||||
|
return X86Operand::CreateMem(Disp, Start, End);
|
||||||
|
else
|
||||||
|
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Scale = SM.getScale();
|
||||||
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
|
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
|
||||||
Start, End, Size);
|
Start, End, Size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,4 +65,186 @@ _main:
|
|||||||
mov RAX, QWORD PTR FS:[320]
|
mov RAX, QWORD PTR FS:[320]
|
||||||
// CHECK: vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm1
|
// CHECK: vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm1
|
||||||
vpgatherdd XMM10, DWORD PTR [R15 + 2*XMM9], XMM8
|
vpgatherdd XMM10, DWORD PTR [R15 + 2*XMM9], XMM8
|
||||||
|
// CHECK: movsd -8, %xmm5
|
||||||
|
movsd XMM5, QWORD PTR [-8]
|
||||||
|
// CHECK: movl %ecx, (%eax)
|
||||||
|
mov [eax], ecx
|
||||||
|
// CHECK: movl %ecx, (,%ebx,4)
|
||||||
|
mov [4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, (,%ebx,4)
|
||||||
|
mov [ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 1024
|
||||||
|
mov [1024], ecx
|
||||||
|
// CHECK: movl %ecx, 4132
|
||||||
|
mov [0x1024], ecx
|
||||||
|
// CHECK: movl %ecx, 32
|
||||||
|
mov [16 + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 0
|
||||||
|
mov [16 - 16], ecx
|
||||||
|
// CHECK: movl %ecx, 32
|
||||||
|
mov [16][16], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [eax + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [eax + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [4*ebx + eax], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [ebx*4 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [eax][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [eax][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [4*ebx][eax], ecx
|
||||||
|
// CHECK: movl %ecx, (%eax,%ebx,4)
|
||||||
|
mov [ebx*4][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 12(%eax)
|
||||||
|
mov [eax + 12], ecx
|
||||||
|
// CHECK: movl %ecx, 12(%eax)
|
||||||
|
mov [12 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [eax + 16 + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16 + eax + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16 + 16 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 12(%eax)
|
||||||
|
mov [eax][12], ecx
|
||||||
|
// CHECK: movl %ecx, 12(%eax)
|
||||||
|
mov [12][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [eax][16 + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [eax + 16][16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [eax][16][16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16][eax + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16 + eax][16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16][16 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16 + 16][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [eax][16][16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16][eax][16], ecx
|
||||||
|
// CHECK: movl %ecx, 32(%eax)
|
||||||
|
mov [16][16][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [4*ebx + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [ebx*4 + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [4*ebx][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [ebx*4][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [16 + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [16 + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [16][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(,%ebx,4)
|
||||||
|
mov [16][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + 4*ebx + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + 16 + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx + eax + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx + 16 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][4*ebx + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][16 + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx][eax + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx][16 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax + 4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + 4*ebx][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + 16][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx + eax][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx + 16][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][4*ebx][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][16][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx][eax][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [4*ebx][16][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax][4*ebx], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + ebx*4 + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + 16 + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4 + eax + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4 + 16 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][ebx*4 + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][16 + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4][eax + 16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4][16 + eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax + ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + ebx*4][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax + 16][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4 + eax][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4 + 16][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16 + eax][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][ebx*4][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [eax][16][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4][eax][16], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [ebx*4][16][eax], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, 16(%eax,%ebx,4)
|
||||||
|
mov [16][eax][ebx*4], ecx
|
||||||
|
// CHECK: movl %ecx, -16(%eax,%ebx,4)
|
||||||
|
mov [eax][ebx*4 - 16], ecx
|
||||||
ret
|
ret
|
||||||
|
|||||||
Reference in New Issue
Block a user