llvm.org GIT mirror llvm / f068304
rip out the 'heinous' x86 MCCodeEmitter implementation. We still have the templated X86 JIT emitter, *and* the almost-copy in X86InstrInfo for getting instruction sizes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96059 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 9 years ago
5 changed file(s) with 4 addition(s) and 340 deletion(s). Raw diff Collapse all Expand all
4949 FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,
5050 JITCodeEmitter &JCE);
5151
52 MCCodeEmitter *createHeinousX86MCCodeEmitter(const Target &, TargetMachine &TM,
53 MCContext &Ctx);
5452 MCCodeEmitter *createX86_32MCCodeEmitter(const Target &, TargetMachine &TM,
5553 MCContext &Ctx);
5654 MCCodeEmitter *createX86_64MCCodeEmitter(const Target &, TargetMachine &TM,
870870
871871 MCE.processDebugLoc(MI.getDebugLoc(), false);
872872 }
873
874 // Adapt the Emitter / CodeEmitter interfaces to MCCodeEmitter.
875 //
876 // FIXME: This is a total hack designed to allow work on llvm-mc to proceed
877 // without being blocked on various cleanups needed to support a clean interface
878 // to instruction encoding.
879 //
880 // Look away!
881
882 #include "llvm/DerivedTypes.h"
883
884 namespace {
885 class MCSingleInstructionCodeEmitter : public MachineCodeEmitter {
886 uint8_t Data[256];
887 const MCInst *CurrentInst;
888 SmallVectorImpl *FixupList;
889
890 public:
891 MCSingleInstructionCodeEmitter() { reset(0, 0); }
892
893 void reset(const MCInst *Inst, SmallVectorImpl *Fixups) {
894 CurrentInst = Inst;
895 FixupList = Fixups;
896 BufferBegin = Data;
897 BufferEnd = array_endof(Data);
898 CurBufferPtr = Data;
899 }
900
901 StringRef str() {
902 return StringRef(reinterpret_cast(BufferBegin),
903 CurBufferPtr - BufferBegin);
904 }
905
906 virtual void startFunction(MachineFunction &F) {}
907 virtual bool finishFunction(MachineFunction &F) { return false; }
908 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
909 virtual bool earlyResolveAddresses() const { return false; }
910 virtual void addRelocation(const MachineRelocation &MR) {
911 unsigned Offset = 0, OpIndex = 0, Kind = MR.getRelocationType();
912
913 // This form is only used in one case, for branches.
914 if (MR.isBasicBlock()) {
915 Offset = unsigned(MR.getMachineCodeOffset());
916 OpIndex = 0;
917 } else {
918 assert(MR.isJumpTableIndex() && "Unexpected relocation!");
919
920 Offset = unsigned(MR.getMachineCodeOffset());
921
922 // The operand index is encoded as the first byte of the fake operand.
923 OpIndex = MR.getJumpTableIndex();
924 }
925
926 MCOperand Op = CurrentInst->getOperand(OpIndex);
927 assert(Op.isExpr() && "FIXME: Not yet implemented!");
928 FixupList->push_back(MCFixup::Create(Offset, Op.getExpr(),
929 MCFixupKind(FirstTargetFixupKind + Kind)));
930 }
931 virtual void setModuleInfo(MachineModuleInfo* Info) {}
932
933 // Interface functions which should never get called in our usage.
934
935 virtual void emitLabel(uint64_t LabelID) {
936 assert(0 && "Unexpected code emitter call!");
937 }
938 virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
939 assert(0 && "Unexpected code emitter call!");
940 return 0;
941 }
942 virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
943 assert(0 && "Unexpected code emitter call!");
944 return 0;
945 }
946 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
947 assert(0 && "Unexpected code emitter call!");
948 return 0;
949 }
950 virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
951 assert(0 && "Unexpected code emitter call!");
952 return 0;
953 }
954 };
955
956 class X86MCCodeEmitter : public MCCodeEmitter {
957 X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
958 void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
959
960 private:
961 X86TargetMachine &TM;
962 llvm::Function *DummyF;
963 TargetData *DummyTD;
964 mutable llvm::MachineFunction *DummyMF;
965 llvm::MachineBasicBlock *DummyMBB;
966
967 MCSingleInstructionCodeEmitter *InstrEmitter;
968 Emitter *Emit;
969
970 public:
971 X86MCCodeEmitter(X86TargetMachine &_TM) : TM(_TM) {
972 // Verily, thou shouldst avert thine eyes.
973 const llvm::FunctionType *FTy =
974 FunctionType::get(llvm::Type::getVoidTy(getGlobalContext()), false);
975 DummyF = Function::Create(FTy, GlobalValue::InternalLinkage);
976 DummyTD = new TargetData("");
977 DummyMF = new MachineFunction(DummyF, TM, 0);
978 DummyMBB = DummyMF->CreateMachineBasicBlock();
979
980 InstrEmitter = new MCSingleInstructionCodeEmitter();
981 Emit = new Emitter(TM, *InstrEmitter,
982 *TM.getInstrInfo(),
983 *DummyTD, false);
984 }
985 ~X86MCCodeEmitter() {
986 delete Emit;
987 delete InstrEmitter;
988 delete DummyMF;
989 delete DummyF;
990 }
991
992 unsigned getNumFixupKinds() const {
993 return 5;
994 }
995
996 MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
997 static MCFixupKindInfo Infos[] = {
998 { "reloc_pcrel_word", 0, 4 * 8 },
999 { "reloc_picrel_word", 0, 4 * 8 },
1000 { "reloc_absolute_word", 0, 4 * 8 },
1001 { "reloc_absolute_word_sext", 0, 4 * 8 },
1002 { "reloc_absolute_dword", 0, 8 * 8 }
1003 };
1004
1005 assert(Kind >= FirstTargetFixupKind && Kind < MaxTargetFixupKind &&
1006 "Invalid kind!");
1007 return Infos[Kind - FirstTargetFixupKind];
1008 }
1009
1010 bool AddRegToInstr(const MCInst &MI, MachineInstr *Instr,
1011 unsigned Start) const {
1012 if (Start + 1 > MI.getNumOperands())
1013 return false;
1014
1015 const MCOperand &Op = MI.getOperand(Start);
1016 if (!Op.isReg()) return false;
1017
1018 Instr->addOperand(MachineOperand::CreateReg(Op.getReg(), false));
1019 return true;
1020 }
1021
1022 bool AddImmToInstr(const MCInst &MI, MachineInstr *Instr,
1023 unsigned Start) const {
1024 if (Start + 1 > MI.getNumOperands())
1025 return false;
1026
1027 const MCOperand &Op = MI.getOperand(Start);
1028 if (Op.isImm()) {
1029 Instr->addOperand(MachineOperand::CreateImm(Op.getImm()));
1030 return true;
1031 }
1032 if (!Op.isExpr())
1033 return false;
1034
1035 const MCExpr *Expr = Op.getExpr();
1036 if (const MCConstantExpr *CE = dyn_cast(Expr)) {
1037 Instr->addOperand(MachineOperand::CreateImm(CE->getValue()));
1038 return true;
1039 }
1040
1041 // Fake this as an external symbol to the code emitter to add a relcoation
1042 // entry we will recognize.
1043 Instr->addOperand(MachineOperand::CreateJTI(Start, 0));
1044 return true;
1045 }
1046
1047 bool AddLMemToInstr(const MCInst &MI, MachineInstr *Instr,
1048 unsigned Start) const {
1049 return (AddRegToInstr(MI, Instr, Start + 0) &&
1050 AddImmToInstr(MI, Instr, Start + 1) &&
1051 AddRegToInstr(MI, Instr, Start + 2) &&
1052 AddImmToInstr(MI, Instr, Start + 3));
1053 }
1054
1055 bool AddMemToInstr(const MCInst &MI, MachineInstr *Instr,
1056 unsigned Start) const {
1057 return (AddRegToInstr(MI, Instr, Start + 0) &&
1058 AddImmToInstr(MI, Instr, Start + 1) &&
1059 AddRegToInstr(MI, Instr, Start + 2) &&
1060 AddImmToInstr(MI, Instr, Start + 3) &&
1061 AddRegToInstr(MI, Instr, Start + 4));
1062 }
1063
1064 void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
1065 SmallVectorImpl &Fixups) const {
1066 // Don't look yet!
1067
1068 // Convert the MCInst to a MachineInstr so we can (ab)use the regular
1069 // emitter.
1070 const X86InstrInfo &II = *TM.getInstrInfo();
1071 const TargetInstrDesc &Desc = II.get(MI.getOpcode());
1072 MachineInstr *Instr = DummyMF->CreateMachineInstr(Desc, DebugLoc());
1073 DummyMBB->push_back(Instr);
1074
1075 unsigned Opcode = MI.getOpcode();
1076 unsigned NumOps = MI.getNumOperands();
1077 unsigned CurOp = 0;
1078 bool AddTied = false;
1079 if (NumOps > 1 && Desc.getOperandConstraint(1, TOI::TIED_TO) != -1)
1080 AddTied = true;
1081 else if (NumOps > 2 &&
1082 Desc.getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0)
1083 // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
1084 --NumOps;
1085
1086 bool OK = true;
1087 switch (Desc.TSFlags & X86II::FormMask) {
1088 case X86II::MRMDestReg:
1089 case X86II::MRMSrcReg:
1090 // Matching doesn't fill this in completely, we have to choose operand 0
1091 // for a tied register.
1092 OK &= AddRegToInstr(MI, Instr, CurOp++);
1093 if (AddTied)
1094 OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
1095 OK &= AddRegToInstr(MI, Instr, CurOp++);
1096 if (CurOp < NumOps)
1097 OK &= AddImmToInstr(MI, Instr, CurOp);
1098 break;
1099
1100 case X86II::RawFrm:
1101 if (CurOp < NumOps) {
1102 // Hack to make branches work.
1103 if (!(Desc.TSFlags & X86II::ImmMask) &&
1104 MI.getOperand(0).isExpr() &&
1105 isa(MI.getOperand(0).getExpr()))
1106 Instr->addOperand(MachineOperand::CreateMBB(DummyMBB));
1107 else
1108 OK &= AddImmToInstr(MI, Instr, CurOp);
1109 }
1110 break;
1111
1112 case X86II::AddRegFrm:
1113 // Matching doesn't fill this in completely, we have to choose operand 0
1114 // for a tied register.
1115 OK &= AddRegToInstr(MI, Instr, CurOp++);
1116 if (AddTied)
1117 OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
1118 if (CurOp < NumOps)
1119 OK &= AddImmToInstr(MI, Instr, CurOp);
1120 break;
1121
1122 case X86II::MRM0r: case X86II::MRM1r:
1123 case X86II::MRM2r: case X86II::MRM3r:
1124 case X86II::MRM4r: case X86II::MRM5r:
1125 case X86II::MRM6r: case X86II::MRM7r:
1126 // Matching doesn't fill this in completely, we have to choose operand 0
1127 // for a tied register.
1128 OK &= AddRegToInstr(MI, Instr, CurOp++);
1129 if (AddTied)
1130 OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
1131 if (CurOp < NumOps)
1132 OK &= AddImmToInstr(MI, Instr, CurOp);
1133 break;
1134
1135 case X86II::MRM0m: case X86II::MRM1m:
1136 case X86II::MRM2m: case X86II::MRM3m:
1137 case X86II::MRM4m: case X86II::MRM5m:
1138 case X86II::MRM6m: case X86II::MRM7m:
1139 OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
1140 if (CurOp < NumOps)
1141 OK &= AddImmToInstr(MI, Instr, CurOp);
1142 break;
1143
1144 case X86II::MRMSrcMem:
1145 // Matching doesn't fill this in completely, we have to choose operand 0
1146 // for a tied register.
1147 OK &= AddRegToInstr(MI, Instr, CurOp++);
1148 if (AddTied)
1149 OK &= AddRegToInstr(MI, Instr, CurOp++ - 1);
1150 if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
1151 Opcode == X86::LEA16r || Opcode == X86::LEA32r)
1152 OK &= AddLMemToInstr(MI, Instr, CurOp);
1153 else
1154 OK &= AddMemToInstr(MI, Instr, CurOp);
1155 break;
1156
1157 case X86II::MRMDestMem:
1158 OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
1159 OK &= AddRegToInstr(MI, Instr, CurOp);
1160 break;
1161
1162 default:
1163 case X86II::MRMInitReg:
1164 case X86II::Pseudo:
1165 OK = false;
1166 break;
1167 }
1168
1169 if (!OK) {
1170 dbgs() << "couldn't convert inst '";
1171 MI.dump();
1172 dbgs() << "' to machine instr:\n";
1173 Instr->dump();
1174 }
1175
1176 InstrEmitter->reset(&MI, &Fixups);
1177 if (OK)
1178 Emit->emitInstruction(*Instr, &Desc);
1179 OS << InstrEmitter->str();
1180
1181 Instr->eraseFromParent();
1182 }
1183 };
1184 }
1185
1186 #include "llvm/Support/CommandLine.h"
1187
1188 static cl::opt EnableNewEncoder("enable-new-x86-encoder",
1189 cl::ReallyHidden);
1190
1191
1192 // Ok, now you can look.
1193 MCCodeEmitter *llvm::createHeinousX86MCCodeEmitter(const Target &T,
1194 TargetMachine &TM,
1195 MCContext &Ctx) {
1196
1197 // FIXME: Remove the heinous one when the new one works.
1198 if (EnableNewEncoder) {
1199 if (TM.getTargetData()->getPointerSize() == 4)
1200 return createX86_32MCCodeEmitter(T, TM, Ctx);
1201 return createX86_64MCCodeEmitter(T, TM, Ctx);
1202 }
1203
1204 return new X86MCCodeEmitter(static_cast(TM));
1205 }
4747 RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo);
4848
4949 // Register the code emitter.
50 // FIXME: Remove the heinous one when the new one works.
5150 TargetRegistry::RegisterCodeEmitter(TheX86_32Target,
52 createHeinousX86MCCodeEmitter);
51 createX86_32MCCodeEmitter);
5352 TargetRegistry::RegisterCodeEmitter(TheX86_64Target,
54 createHeinousX86MCCodeEmitter);
53 createX86_64MCCodeEmitter);
5554 }
5655
5756
None // RUN: llvm-mc -triple i386-unknown-unknown --show-encoding --enable-new-x86-encoder %s | FileCheck %s
0 // RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s
11
22 lfence
33 // CHECK: lfence
None // RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding --enable-new-x86-encoder %s | FileCheck %s
0 // RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck %s
11
22 movl foo(%rip), %eax
33 // CHECK: movl foo(%rip), %eax