llvm.org GIT mirror llvm / 2c4b1c4
X86Operand is extracted into individual header. X86Operand is extracted into individual header, because it allows to create an arbitrary memory operand and append it to MCInst. It'll be reused in X86 inline assembly instrumentation. Patch by Yuri Gorshenin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202496 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 6 years ago
3 changed file(s) with 533 addition(s) and 497 deletion(s). Raw diff Collapse all Expand all
77 //===----------------------------------------------------------------------===//
88
99 #include "MCTargetDesc/X86BaseInfo.h"
10 #include "X86AsmParserCommon.h"
11 #include "X86Operand.h"
1012 #include "llvm/ADT/APFloat.h"
1113 #include "llvm/ADT/STLExtras.h"
1214 #include "llvm/ADT/SmallString.h"
3133 using namespace llvm;
3234
3335 namespace {
34 struct X86Operand;
3536
3637 static const char OpPrecedence[] = {
3738 0, // IC_OR
722723
723724 /// }
724725
725 static bool isImmSExti16i8Value(uint64_t Value) {
726 return (( Value <= 0x000000000000007FULL)||
727 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
728 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
729 }
730
731 static bool isImmSExti32i8Value(uint64_t Value) {
732 return (( Value <= 0x000000000000007FULL)||
733 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
734 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
735 }
736
737 static bool isImmZExtu32u8Value(uint64_t Value) {
738 return (Value <= 0x00000000000000FFULL);
739 }
740
741 static bool isImmSExti64i8Value(uint64_t Value) {
742 return (( Value <= 0x000000000000007FULL)||
743 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
744 }
745
746 static bool isImmSExti64i32Value(uint64_t Value) {
747 return (( Value <= 0x000000007FFFFFFFULL)||
748 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
749 }
750 namespace {
751
752 /// X86Operand - Instances of this class represent a parsed X86 machine
753 /// instruction.
754 struct X86Operand : public MCParsedAsmOperand {
755 enum KindTy {
756 Token,
757 Register,
758 Immediate,
759 Memory
760 } Kind;
761
762 SMLoc StartLoc, EndLoc;
763 SMLoc OffsetOfLoc;
764 StringRef SymName;
765 void *OpDecl;
766 bool AddressOf;
767
768 struct TokOp {
769 const char *Data;
770 unsigned Length;
771 };
772
773 struct RegOp {
774 unsigned RegNo;
775 };
776
777 struct ImmOp {
778 const MCExpr *Val;
779 };
780
781 struct MemOp {
782 unsigned SegReg;
783 const MCExpr *Disp;
784 unsigned BaseReg;
785 unsigned IndexReg;
786 unsigned Scale;
787 unsigned Size;
788 };
789
790 union {
791 struct TokOp Tok;
792 struct RegOp Reg;
793 struct ImmOp Imm;
794 struct MemOp Mem;
795 };
796
797 X86Operand(KindTy K, SMLoc Start, SMLoc End)
798 : Kind(K), StartLoc(Start), EndLoc(End) {}
799
800 StringRef getSymName() { return SymName; }
801 void *getOpDecl() { return OpDecl; }
802
803 /// getStartLoc - Get the location of the first token of this operand.
804 SMLoc getStartLoc() const { return StartLoc; }
805 /// getEndLoc - Get the location of the last token of this operand.
806 SMLoc getEndLoc() const { return EndLoc; }
807 /// getLocRange - Get the range between the first and last token of this
808 /// operand.
809 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
810 /// getOffsetOfLoc - Get the location of the offset operator.
811 SMLoc getOffsetOfLoc() const { return OffsetOfLoc; }
812
813 virtual void print(raw_ostream &OS) const {}
814
815 StringRef getToken() const {
816 assert(Kind == Token && "Invalid access!");
817 return StringRef(Tok.Data, Tok.Length);
818 }
819 void setTokenValue(StringRef Value) {
820 assert(Kind == Token && "Invalid access!");
821 Tok.Data = Value.data();
822 Tok.Length = Value.size();
823 }
824
825 unsigned getReg() const {
826 assert(Kind == Register && "Invalid access!");
827 return Reg.RegNo;
828 }
829
830 const MCExpr *getImm() const {
831 assert(Kind == Immediate && "Invalid access!");
832 return Imm.Val;
833 }
834
835 const MCExpr *getMemDisp() const {
836 assert(Kind == Memory && "Invalid access!");
837 return Mem.Disp;
838 }
839 unsigned getMemSegReg() const {
840 assert(Kind == Memory && "Invalid access!");
841 return Mem.SegReg;
842 }
843 unsigned getMemBaseReg() const {
844 assert(Kind == Memory && "Invalid access!");
845 return Mem.BaseReg;
846 }
847 unsigned getMemIndexReg() const {
848 assert(Kind == Memory && "Invalid access!");
849 return Mem.IndexReg;
850 }
851 unsigned getMemScale() const {
852 assert(Kind == Memory && "Invalid access!");
853 return Mem.Scale;
854 }
855
856 bool isToken() const {return Kind == Token; }
857
858 bool isImm() const { return Kind == Immediate; }
859
860 bool isImmSExti16i8() const {
861 if (!isImm())
862 return false;
863
864 // If this isn't a constant expr, just assume it fits and let relaxation
865 // handle it.
866 const MCConstantExpr *CE = dyn_cast(getImm());
867 if (!CE)
868 return true;
869
870 // Otherwise, check the value is in a range that makes sense for this
871 // extension.
872 return isImmSExti16i8Value(CE->getValue());
873 }
874 bool isImmSExti32i8() const {
875 if (!isImm())
876 return false;
877
878 // If this isn't a constant expr, just assume it fits and let relaxation
879 // handle it.
880 const MCConstantExpr *CE = dyn_cast(getImm());
881 if (!CE)
882 return true;
883
884 // Otherwise, check the value is in a range that makes sense for this
885 // extension.
886 return isImmSExti32i8Value(CE->getValue());
887 }
888 bool isImmZExtu32u8() const {
889 if (!isImm())
890 return false;
891
892 // If this isn't a constant expr, just assume it fits and let relaxation
893 // handle it.
894 const MCConstantExpr *CE = dyn_cast(getImm());
895 if (!CE)
896 return true;
897
898 // Otherwise, check the value is in a range that makes sense for this
899 // extension.
900 return isImmZExtu32u8Value(CE->getValue());
901 }
902 bool isImmSExti64i8() const {
903 if (!isImm())
904 return false;
905
906 // If this isn't a constant expr, just assume it fits and let relaxation
907 // handle it.
908 const MCConstantExpr *CE = dyn_cast(getImm());
909 if (!CE)
910 return true;
911
912 // Otherwise, check the value is in a range that makes sense for this
913 // extension.
914 return isImmSExti64i8Value(CE->getValue());
915 }
916 bool isImmSExti64i32() const {
917 if (!isImm())
918 return false;
919
920 // If this isn't a constant expr, just assume it fits and let relaxation
921 // handle it.
922 const MCConstantExpr *CE = dyn_cast(getImm());
923 if (!CE)
924 return true;
925
926 // Otherwise, check the value is in a range that makes sense for this
927 // extension.
928 return isImmSExti64i32Value(CE->getValue());
929 }
930
931 bool isOffsetOf() const {
932 return OffsetOfLoc.getPointer();
933 }
934
935 bool needAddressOf() const {
936 return AddressOf;
937 }
938
939 bool isMem() const { return Kind == Memory; }
940 bool isMem8() const {
941 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
942 }
943 bool isMem16() const {
944 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
945 }
946 bool isMem32() const {
947 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
948 }
949 bool isMem64() const {
950 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
951 }
952 bool isMem80() const {
953 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
954 }
955 bool isMem128() const {
956 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
957 }
958 bool isMem256() const {
959 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
960 }
961 bool isMem512() const {
962 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
963 }
964
965 bool isMemVX32() const {
966 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
967 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
968 }
969 bool isMemVY32() const {
970 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
971 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
972 }
973 bool isMemVX64() const {
974 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
975 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
976 }
977 bool isMemVY64() const {
978 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
979 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
980 }
981 bool isMemVZ32() const {
982 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
983 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
984 }
985 bool isMemVZ64() const {
986 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
987 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
988 }
989
990 bool isAbsMem() const {
991 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
992 !getMemIndexReg() && getMemScale() == 1;
993 }
994
995 bool isSrcIdx() const {
996 return !getMemIndexReg() && getMemScale() == 1 &&
997 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
998 getMemBaseReg() == X86::SI) && isa(getMemDisp()) &&
999 cast(getMemDisp())->getValue() == 0;
1000 }
1001 bool isSrcIdx8() const {
1002 return isMem8() && isSrcIdx();
1003 }
1004 bool isSrcIdx16() const {
1005 return isMem16() && isSrcIdx();
1006 }
1007 bool isSrcIdx32() const {
1008 return isMem32() && isSrcIdx();
1009 }
1010 bool isSrcIdx64() const {
1011 return isMem64() && isSrcIdx();
1012 }
1013
1014 bool isDstIdx() const {
1015 return !getMemIndexReg() && getMemScale() == 1 &&
1016 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
1017 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
1018 getMemBaseReg() == X86::DI) && isa(getMemDisp()) &&
1019 cast(getMemDisp())->getValue() == 0;
1020 }
1021 bool isDstIdx8() const {
1022 return isMem8() && isDstIdx();
1023 }
1024 bool isDstIdx16() const {
1025 return isMem16() && isDstIdx();
1026 }
1027 bool isDstIdx32() const {
1028 return isMem32() && isDstIdx();
1029 }
1030 bool isDstIdx64() const {
1031 return isMem64() && isDstIdx();
1032 }
1033
1034 bool isMemOffs8() const {
1035 return Kind == Memory && !getMemBaseReg() &&
1036 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
1037 }
1038 bool isMemOffs16() const {
1039 return Kind == Memory && !getMemBaseReg() &&
1040 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
1041 }
1042 bool isMemOffs32() const {
1043 return Kind == Memory && !getMemBaseReg() &&
1044 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
1045 }
1046 bool isMemOffs64() const {
1047 return Kind == Memory && !getMemBaseReg() &&
1048 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
1049 }
1050
1051 bool isReg() const { return Kind == Register; }
1052
1053 bool isGR32orGR64() const {
1054 return Kind == Register &&
1055 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
1056 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
1057 }
1058
1059 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1060 // Add as immediates when possible.
1061 if (const MCConstantExpr *CE = dyn_cast(Expr))
1062 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1063 else
1064 Inst.addOperand(MCOperand::CreateExpr(Expr));
1065 }
1066
1067 void addRegOperands(MCInst &Inst, unsigned N) const {
1068 assert(N == 1 && "Invalid number of operands!");
1069 Inst.addOperand(MCOperand::CreateReg(getReg()));
1070 }
1071
1072 static unsigned getGR32FromGR64(unsigned RegNo) {
1073 switch (RegNo) {
1074 default: llvm_unreachable("Unexpected register");
1075 case X86::RAX: return X86::EAX;
1076 case X86::RCX: return X86::ECX;
1077 case X86::RDX: return X86::EDX;
1078 case X86::RBX: return X86::EBX;
1079 case X86::RBP: return X86::EBP;
1080 case X86::RSP: return X86::ESP;
1081 case X86::RSI: return X86::ESI;
1082 case X86::RDI: return X86::EDI;
1083 case X86::R8: return X86::R8D;
1084 case X86::R9: return X86::R9D;
1085 case X86::R10: return X86::R10D;
1086 case X86::R11: return X86::R11D;
1087 case X86::R12: return X86::R12D;
1088 case X86::R13: return X86::R13D;
1089 case X86::R14: return X86::R14D;
1090 case X86::R15: return X86::R15D;
1091 case X86::RIP: return X86::EIP;
1092 }
1093 }
1094
1095 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
1096 assert(N == 1 && "Invalid number of operands!");
1097 unsigned RegNo = getReg();
1098 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
1099 RegNo = getGR32FromGR64(RegNo);
1100 Inst.addOperand(MCOperand::CreateReg(RegNo));
1101 }
1102
1103 void addImmOperands(MCInst &Inst, unsigned N) const {
1104 assert(N == 1 && "Invalid number of operands!");
1105 addExpr(Inst, getImm());
1106 }
1107
1108 void addMemOperands(MCInst &Inst, unsigned N) const {
1109 assert((N == 5) && "Invalid number of operands!");
1110 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
1111 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
1112 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
1113 addExpr(Inst, getMemDisp());
1114 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
1115 }
1116
1117 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
1118 assert((N == 1) && "Invalid number of operands!");
1119 // Add as immediates when possible.
1120 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
1121 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1122 else
1123 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
1124 }
1125
1126 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
1127 assert((N == 2) && "Invalid number of operands!");
1128 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
1129 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
1130 }
1131 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
1132 assert((N == 1) && "Invalid number of operands!");
1133 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
1134 }
1135
1136 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
1137 assert((N == 2) && "Invalid number of operands!");
1138 // Add as immediates when possible.
1139 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
1140 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1141 else
1142 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
1143 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
1144 }
1145
1146 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
1147 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
1148 X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
1149 Res->Tok.Data = Str.data();
1150 Res->Tok.Length = Str.size();
1151 return Res;
1152 }
1153
1154 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
1155 bool AddressOf = false,
1156 SMLoc OffsetOfLoc = SMLoc(),
1157 StringRef SymName = StringRef(),
1158 void *OpDecl = 0) {
1159 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
1160 Res->Reg.RegNo = RegNo;
1161 Res->AddressOf = AddressOf;
1162 Res->OffsetOfLoc = OffsetOfLoc;
1163 Res->SymName = SymName;
1164 Res->OpDecl = OpDecl;
1165 return Res;
1166 }
1167
1168 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
1169 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
1170 Res->Imm.Val = Val;
1171 return Res;
1172 }
1173
1174 /// Create an absolute memory operand.
1175 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
1176 unsigned Size = 0, StringRef SymName = StringRef(),
1177 void *OpDecl = 0) {
1178 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
1179 Res->Mem.SegReg = 0;
1180 Res->Mem.Disp = Disp;
1181 Res->Mem.BaseReg = 0;
1182 Res->Mem.IndexReg = 0;
1183 Res->Mem.Scale = 1;
1184 Res->Mem.Size = Size;
1185 Res->SymName = SymName;
1186 Res->OpDecl = OpDecl;
1187 Res->AddressOf = false;
1188 return Res;
1189 }
1190
1191 /// Create a generalized memory operand.
1192 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
1193 unsigned BaseReg, unsigned IndexReg,
1194 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
1195 unsigned Size = 0,
1196 StringRef SymName = StringRef(),
1197 void *OpDecl = 0) {
1198 // We should never just have a displacement, that should be parsed as an
1199 // absolute memory operand.
1200 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
1201
1202 // The scale should always be one of {1,2,4,8}.
1203 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
1204 "Invalid scale!");
1205 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
1206 Res->Mem.SegReg = SegReg;
1207 Res->Mem.Disp = Disp;
1208 Res->Mem.BaseReg = BaseReg;
1209 Res->Mem.IndexReg = IndexReg;
1210 Res->Mem.Scale = Scale;
1211 Res->Mem.Size = Size;
1212 Res->SymName = SymName;
1213 Res->OpDecl = OpDecl;
1214 Res->AddressOf = false;
1215 return Res;
1216 }
1217 };
1218
1219 } // end anonymous namespace.
1220
1221726 static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
1222727 StringRef &ErrMsg) {
1223728 // If we have both a base register and an index register make sure they are
0 //===-- X86AsmParserCommon.h - Common functions for X86AsmParser ---------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef X86_ASM_PARSER_COMMON_H
10 #define X86_ASM_PARSER_COMMON_H
11
12 namespace llvm {
13
14 inline bool isImmSExti16i8Value(uint64_t Value) {
15 return (( Value <= 0x000000000000007FULL)||
16 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
17 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
18 }
19
20 inline bool isImmSExti32i8Value(uint64_t Value) {
21 return (( Value <= 0x000000000000007FULL)||
22 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
23 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
24 }
25
26 inline bool isImmZExtu32u8Value(uint64_t Value) {
27 return (Value <= 0x00000000000000FFULL);
28 }
29
30 inline bool isImmSExti64i8Value(uint64_t Value) {
31 return (( Value <= 0x000000000000007FULL)||
32 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
33 }
34
35 inline bool isImmSExti64i32Value(uint64_t Value) {
36 return (( Value <= 0x000000007FFFFFFFULL)||
37 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
38 }
39
40 } // End of namespace llvm
41
42 #endif // X86_ASM_PARSER_COMMON_H
0 //===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef X86_OPERAND_H
10 #define X86_OPERAND_H
11
12 #include "X86AsmParserCommon.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
15
16 namespace llvm {
17
18 /// X86Operand - Instances of this class represent a parsed X86 machine
19 /// instruction.
20 struct X86Operand : public MCParsedAsmOperand {
21 enum KindTy {
22 Token,
23 Register,
24 Immediate,
25 Memory
26 } Kind;
27
28 SMLoc StartLoc, EndLoc;
29 SMLoc OffsetOfLoc;
30 StringRef SymName;
31 void *OpDecl;
32 bool AddressOf;
33
34 struct TokOp {
35 const char *Data;
36 unsigned Length;
37 };
38
39 struct RegOp {
40 unsigned RegNo;
41 };
42
43 struct ImmOp {
44 const MCExpr *Val;
45 };
46
47 struct MemOp {
48 unsigned SegReg;
49 const MCExpr *Disp;
50 unsigned BaseReg;
51 unsigned IndexReg;
52 unsigned Scale;
53 unsigned Size;
54 };
55
56 union {
57 struct TokOp Tok;
58 struct RegOp Reg;
59 struct ImmOp Imm;
60 struct MemOp Mem;
61 };
62
63 X86Operand(KindTy K, SMLoc Start, SMLoc End)
64 : Kind(K), StartLoc(Start), EndLoc(End) {}
65
66 StringRef getSymName() { return SymName; }
67 void *getOpDecl() { return OpDecl; }
68
69 /// getStartLoc - Get the location of the first token of this operand.
70 SMLoc getStartLoc() const { return StartLoc; }
71 /// getEndLoc - Get the location of the last token of this operand.
72 SMLoc getEndLoc() const { return EndLoc; }
73 /// getLocRange - Get the range between the first and last token of this
74 /// operand.
75 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
76 /// getOffsetOfLoc - Get the location of the offset operator.
77 SMLoc getOffsetOfLoc() const { return OffsetOfLoc; }
78
79 virtual void print(raw_ostream &OS) const {}
80
81 StringRef getToken() const {
82 assert(Kind == Token && "Invalid access!");
83 return StringRef(Tok.Data, Tok.Length);
84 }
85 void setTokenValue(StringRef Value) {
86 assert(Kind == Token && "Invalid access!");
87 Tok.Data = Value.data();
88 Tok.Length = Value.size();
89 }
90
91 unsigned getReg() const {
92 assert(Kind == Register && "Invalid access!");
93 return Reg.RegNo;
94 }
95
96 const MCExpr *getImm() const {
97 assert(Kind == Immediate && "Invalid access!");
98 return Imm.Val;
99 }
100
101 const MCExpr *getMemDisp() const {
102 assert(Kind == Memory && "Invalid access!");
103 return Mem.Disp;
104 }
105 unsigned getMemSegReg() const {
106 assert(Kind == Memory && "Invalid access!");
107 return Mem.SegReg;
108 }
109 unsigned getMemBaseReg() const {
110 assert(Kind == Memory && "Invalid access!");
111 return Mem.BaseReg;
112 }
113 unsigned getMemIndexReg() const {
114 assert(Kind == Memory && "Invalid access!");
115 return Mem.IndexReg;
116 }
117 unsigned getMemScale() const {
118 assert(Kind == Memory && "Invalid access!");
119 return Mem.Scale;
120 }
121
122 bool isToken() const {return Kind == Token; }
123
124 bool isImm() const { return Kind == Immediate; }
125
126 bool isImmSExti16i8() const {
127 if (!isImm())
128 return false;
129
130 // If this isn't a constant expr, just assume it fits and let relaxation
131 // handle it.
132 const MCConstantExpr *CE = dyn_cast(getImm());
133 if (!CE)
134 return true;
135
136 // Otherwise, check the value is in a range that makes sense for this
137 // extension.
138 return isImmSExti16i8Value(CE->getValue());
139 }
140 bool isImmSExti32i8() const {
141 if (!isImm())
142 return false;
143
144 // If this isn't a constant expr, just assume it fits and let relaxation
145 // handle it.
146 const MCConstantExpr *CE = dyn_cast(getImm());
147 if (!CE)
148 return true;
149
150 // Otherwise, check the value is in a range that makes sense for this
151 // extension.
152 return isImmSExti32i8Value(CE->getValue());
153 }
154 bool isImmZExtu32u8() const {
155 if (!isImm())
156 return false;
157
158 // If this isn't a constant expr, just assume it fits and let relaxation
159 // handle it.
160 const MCConstantExpr *CE = dyn_cast(getImm());
161 if (!CE)
162 return true;
163
164 // Otherwise, check the value is in a range that makes sense for this
165 // extension.
166 return isImmZExtu32u8Value(CE->getValue());
167 }
168 bool isImmSExti64i8() const {
169 if (!isImm())
170 return false;
171
172 // If this isn't a constant expr, just assume it fits and let relaxation
173 // handle it.
174 const MCConstantExpr *CE = dyn_cast(getImm());
175 if (!CE)
176 return true;
177
178 // Otherwise, check the value is in a range that makes sense for this
179 // extension.
180 return isImmSExti64i8Value(CE->getValue());
181 }
182 bool isImmSExti64i32() const {
183 if (!isImm())
184 return false;
185
186 // If this isn't a constant expr, just assume it fits and let relaxation
187 // handle it.
188 const MCConstantExpr *CE = dyn_cast(getImm());
189 if (!CE)
190 return true;
191
192 // Otherwise, check the value is in a range that makes sense for this
193 // extension.
194 return isImmSExti64i32Value(CE->getValue());
195 }
196
197 bool isOffsetOf() const {
198 return OffsetOfLoc.getPointer();
199 }
200
201 bool needAddressOf() const {
202 return AddressOf;
203 }
204
205 bool isMem() const { return Kind == Memory; }
206 bool isMem8() const {
207 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
208 }
209 bool isMem16() const {
210 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
211 }
212 bool isMem32() const {
213 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
214 }
215 bool isMem64() const {
216 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
217 }
218 bool isMem80() const {
219 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
220 }
221 bool isMem128() const {
222 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
223 }
224 bool isMem256() const {
225 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
226 }
227 bool isMem512() const {
228 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
229 }
230
231 bool isMemVX32() const {
232 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
233 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
234 }
235 bool isMemVY32() const {
236 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
237 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
238 }
239 bool isMemVX64() const {
240 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
241 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
242 }
243 bool isMemVY64() const {
244 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
245 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
246 }
247 bool isMemVZ32() const {
248 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
249 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
250 }
251 bool isMemVZ64() const {
252 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
253 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
254 }
255
256 bool isAbsMem() const {
257 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
258 !getMemIndexReg() && getMemScale() == 1;
259 }
260
261 bool isSrcIdx() const {
262 return !getMemIndexReg() && getMemScale() == 1 &&
263 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
264 getMemBaseReg() == X86::SI) && isa(getMemDisp()) &&
265 cast(getMemDisp())->getValue() == 0;
266 }
267 bool isSrcIdx8() const {
268 return isMem8() && isSrcIdx();
269 }
270 bool isSrcIdx16() const {
271 return isMem16() && isSrcIdx();
272 }
273 bool isSrcIdx32() const {
274 return isMem32() && isSrcIdx();
275 }
276 bool isSrcIdx64() const {
277 return isMem64() && isSrcIdx();
278 }
279
280 bool isDstIdx() const {
281 return !getMemIndexReg() && getMemScale() == 1 &&
282 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
283 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
284 getMemBaseReg() == X86::DI) && isa(getMemDisp()) &&
285 cast(getMemDisp())->getValue() == 0;
286 }
287 bool isDstIdx8() const {
288 return isMem8() && isDstIdx();
289 }
290 bool isDstIdx16() const {
291 return isMem16() && isDstIdx();
292 }
293 bool isDstIdx32() const {
294 return isMem32() && isDstIdx();
295 }
296 bool isDstIdx64() const {
297 return isMem64() && isDstIdx();
298 }
299
300 bool isMemOffs8() const {
301 return Kind == Memory && !getMemBaseReg() &&
302 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
303 }
304 bool isMemOffs16() const {
305 return Kind == Memory && !getMemBaseReg() &&
306 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
307 }
308 bool isMemOffs32() const {
309 return Kind == Memory && !getMemBaseReg() &&
310 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
311 }
312 bool isMemOffs64() const {
313 return Kind == Memory && !getMemBaseReg() &&
314 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
315 }
316
317 bool isReg() const { return Kind == Register; }
318
319 bool isGR32orGR64() const {
320 return Kind == Register &&
321 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
322 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
323 }
324
325 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
326 // Add as immediates when possible.
327 if (const MCConstantExpr *CE = dyn_cast(Expr))
328 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
329 else
330 Inst.addOperand(MCOperand::CreateExpr(Expr));
331 }
332
333 void addRegOperands(MCInst &Inst, unsigned N) const {
334 assert(N == 1 && "Invalid number of operands!");
335 Inst.addOperand(MCOperand::CreateReg(getReg()));
336 }
337
338 static unsigned getGR32FromGR64(unsigned RegNo) {
339 switch (RegNo) {
340 default: llvm_unreachable("Unexpected register");
341 case X86::RAX: return X86::EAX;
342 case X86::RCX: return X86::ECX;
343 case X86::RDX: return X86::EDX;
344 case X86::RBX: return X86::EBX;
345 case X86::RBP: return X86::EBP;
346 case X86::RSP: return X86::ESP;
347 case X86::RSI: return X86::ESI;
348 case X86::RDI: return X86::EDI;
349 case X86::R8: return X86::R8D;
350 case X86::R9: return X86::R9D;
351 case X86::R10: return X86::R10D;
352 case X86::R11: return X86::R11D;
353 case X86::R12: return X86::R12D;
354 case X86::R13: return X86::R13D;
355 case X86::R14: return X86::R14D;
356 case X86::R15: return X86::R15D;
357 case X86::RIP: return X86::EIP;
358 }
359 }
360
361 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
362 assert(N == 1 && "Invalid number of operands!");
363 unsigned RegNo = getReg();
364 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
365 RegNo = getGR32FromGR64(RegNo);
366 Inst.addOperand(MCOperand::CreateReg(RegNo));
367 }
368
369 void addImmOperands(MCInst &Inst, unsigned N) const {
370 assert(N == 1 && "Invalid number of operands!");
371 addExpr(Inst, getImm());
372 }
373
374 void addMemOperands(MCInst &Inst, unsigned N) const {
375 assert((N == 5) && "Invalid number of operands!");
376 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
377 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
378 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
379 addExpr(Inst, getMemDisp());
380 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
381 }
382
383 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
384 assert((N == 1) && "Invalid number of operands!");
385 // Add as immediates when possible.
386 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
387 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
388 else
389 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
390 }
391
392 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
393 assert((N == 2) && "Invalid number of operands!");
394 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
395 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
396 }
397 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
398 assert((N == 1) && "Invalid number of operands!");
399 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
400 }
401
402 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
403 assert((N == 2) && "Invalid number of operands!");
404 // Add as immediates when possible.
405 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
406 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
407 else
408 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
409 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
410 }
411
412 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
413 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
414 X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
415 Res->Tok.Data = Str.data();
416 Res->Tok.Length = Str.size();
417 return Res;
418 }
419
420 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
421 bool AddressOf = false,
422 SMLoc OffsetOfLoc = SMLoc(),
423 StringRef SymName = StringRef(),
424 void *OpDecl = 0) {
425 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
426 Res->Reg.RegNo = RegNo;
427 Res->AddressOf = AddressOf;
428 Res->OffsetOfLoc = OffsetOfLoc;
429 Res->SymName = SymName;
430 Res->OpDecl = OpDecl;
431 return Res;
432 }
433
434 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
435 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
436 Res->Imm.Val = Val;
437 return Res;
438 }
439
440 /// Create an absolute memory operand.
441 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
442 unsigned Size = 0, StringRef SymName = StringRef(),
443 void *OpDecl = 0) {
444 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
445 Res->Mem.SegReg = 0;
446 Res->Mem.Disp = Disp;
447 Res->Mem.BaseReg = 0;
448 Res->Mem.IndexReg = 0;
449 Res->Mem.Scale = 1;
450 Res->Mem.Size = Size;
451 Res->SymName = SymName;
452 Res->OpDecl = OpDecl;
453 Res->AddressOf = false;
454 return Res;
455 }
456
457 /// Create a generalized memory operand.
458 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
459 unsigned BaseReg, unsigned IndexReg,
460 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
461 unsigned Size = 0,
462 StringRef SymName = StringRef(),
463 void *OpDecl = 0) {
464 // We should never just have a displacement, that should be parsed as an
465 // absolute memory operand.
466 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
467
468 // The scale should always be one of {1,2,4,8}.
469 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
470 "Invalid scale!");
471 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
472 Res->Mem.SegReg = SegReg;
473 Res->Mem.Disp = Disp;
474 Res->Mem.BaseReg = BaseReg;
475 Res->Mem.IndexReg = IndexReg;
476 Res->Mem.Scale = Scale;
477 Res->Mem.Size = Size;
478 Res->SymName = SymName;
479 Res->OpDecl = OpDecl;
480 Res->AddressOf = false;
481 return Res;
482 }
483 };
484
485 } // End of namespace llvm
486
487 #endif // X86_OPERAND