mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +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)) { |  | ||||||
|       int64_t Val = Tok.getIntVal(); |  | ||||||
|       Parser.Lex(); |  | ||||||
|       SMLoc Loc = Tok.getLoc(); |  | ||||||
|       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"); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Parse ][ as a plus. |   // Parse [ BaseReg + Scale*IndexReg + Disp ]. | ||||||
|   bool ExpectRBrac = true; |   bool Done = false; | ||||||
|   if (getLexer().is(AsmToken::RBrac)) { |   IntelBracExprStateMachine SM(Parser); | ||||||
|     ExpectRBrac = false; |  | ||||||
|     End = Parser.getTok().getEndLoc(); |  | ||||||
|     Parser.Lex(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus) || |   // If we parsed a register, then the end loc has already been set and | ||||||
|       getLexer().is(AsmToken::LBrac)) { |   // the identifier has already been lexed.  We also need to update the | ||||||
|     ExpectRBrac = true; |   // state. | ||||||
|     bool isPlus = getLexer().is(AsmToken::Plus) || |   if (TmpReg) | ||||||
|       getLexer().is(AsmToken::LBrac); |     SM.onRegister(TmpReg); | ||||||
|     Parser.Lex();  |  | ||||||
|     SMLoc PlusLoc = Tok.getLoc(); |   const MCExpr *Disp = 0; | ||||||
|     if (getLexer().is(AsmToken::Integer)) { |   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); | ||||||
|       if (getLexer().is(AsmToken::Star)) { |       break; | ||||||
|         Parser.Lex(); |     } | ||||||
|         SMLoc IdxRegLoc = Tok.getLoc(); |     case AsmToken::Plus:    SM.onPlus(); break; | ||||||
|         if (ParseRegister(IndexReg, IdxRegLoc, End)) |     case AsmToken::Minus:   SM.onMinus(); break; | ||||||
|           return ErrorOperand(IdxRegLoc, "Expected register"); |     case AsmToken::Star:    SM.onStar(); break; | ||||||
|         Scale = Val; |     case AsmToken::LBrac:   SM.onLBrac(); break; | ||||||
|       } else if (getLexer().is(AsmToken::RBrac)) { |     case AsmToken::RBrac:   SM.onRBrac(); break; | ||||||
|         const MCExpr *ValExpr = MCConstantExpr::Create(Val, getContext()); |     } | ||||||
|         Disp = isPlus ? ValExpr : MCConstantExpr::Create(0-Val, getContext()); |     if (!Done && UpdateLocLex) { | ||||||
|       } else |       End = Tok.getLoc(); | ||||||
|         return ErrorOperand(PlusLoc, "unexpected token after +"); |       Parser.Lex(); // Consume the token. | ||||||
|     } 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); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -56,13 +56,195 @@ _main: | |||||||
| // CHECK:	fld	%st(0) | // CHECK:	fld	%st(0) | ||||||
| 	fld	ST(0) | 	fld	ST(0) | ||||||
| // CHECK:	movl	%fs:(%rdi), %eax | // CHECK:	movl	%fs:(%rdi), %eax | ||||||
|         mov     EAX, DWORD PTR FS:[RDI] |     mov EAX, DWORD PTR FS:[RDI] | ||||||
| // CHECK:	leal	(,%rdi,4), %r8d | // CHECK: leal (,%rdi,4), %r8d | ||||||
|         lea     R8D, DWORD PTR [4*RDI] |     lea R8D, DWORD PTR [4*RDI] | ||||||
| // CHECK:        movl    _fnan(,%ecx,4), %ecx | // CHECK: movl _fnan(,%ecx,4), %ecx | ||||||
|         mov     ECX, DWORD PTR [4*ECX + _fnan] |     mov ECX, DWORD PTR [4*ECX + _fnan] | ||||||
| // CHECK:       movq    %fs:320, %rax | // CHECK: movq %fs:320, %rax | ||||||
|         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