llvm.org GIT mirror llvm / 7168a7d
llvm-mc/X86: Implement single instruction encoding interface for MC. - Note, this is a gigantic hack, with the sole purpose of unblocking further work on the assembler (its also possible to test the mathcer more completely now). - Despite being a hack, its actually good enough to work over all of 403.gcc (although some encodings are probably incorrect). This is a testament to the beauty of X86's MachineInstr, no doubt! ;) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80234 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Dunbar 11 years ago
3 changed file(s) with 258 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
2121 class X86TargetMachine;
2222 class FunctionPass;
2323 class MachineCodeEmitter;
24 class MCCodeEmitter;
2425 class JITCodeEmitter;
26 class Target;
2527 class formatted_raw_ostream;
2628
2729 /// createX86ISelDag - This pass converts a legalized DAG into a
5153 FunctionPass *createX86ObjectCodeEmitterPass(X86TargetMachine &TM,
5254 ObjectCodeEmitter &OCE);
5355
56 MCCodeEmitter *createX86MCCodeEmitter(const Target &, TargetMachine &TM);
57
5458 /// createX86EmitCodeToMemory - Returns a pass that converts a register
5559 /// allocated function into raw machine code in a dynamically
5660 /// allocated chunk of memory.
2828 #include "llvm/CodeGen/Passes.h"
2929 #include "llvm/Function.h"
3030 #include "llvm/ADT/Statistic.h"
31 #include "llvm/MC/MCCodeEmitter.h"
32 #include "llvm/MC/MCInst.h"
3133 #include "llvm/Support/Compiler.h"
3234 #include "llvm/Support/Debug.h"
3335 #include "llvm/Support/ErrorHandling.h"
857859 llvm_unreachable(0);
858860 }
859861 }
862
863 // Adapt the Emitter / CodeEmitter interfaces to MCCodeEmitter.
864 //
865 // FIXME: This is a total hack designed to allow work on llvm-mc to proceed
866 // without being blocked on various cleanups needed to support a clean interface
867 // to instruction encoding.
868 //
869 // Look away!
870
871 #include "llvm/DerivedTypes.h"
872
873 namespace {
874 class MCSingleInstructionCodeEmitter : public MachineCodeEmitter {
875 uint8_t Data[256];
876
877 public:
878 MCSingleInstructionCodeEmitter() { reset(); }
879
880 void reset() {
881 BufferBegin = Data;
882 BufferEnd = array_endof(Data);
883 CurBufferPtr = Data;
884 }
885
886 StringRef str() {
887 return StringRef(reinterpret_cast(BufferBegin),
888 CurBufferPtr - BufferBegin);
889 }
890
891 virtual void startFunction(MachineFunction &F) {}
892 virtual bool finishFunction(MachineFunction &F) { return false; }
893 virtual void emitLabel(uint64_t LabelID) {}
894 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {}
895 virtual bool earlyResolveAddresses() const { return false; }
896 virtual void addRelocation(const MachineRelocation &MR) { }
897 virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
898 return 0;
899 }
900 virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
901 return 0;
902 }
903 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
904 return 0;
905 }
906 virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
907 return 0;
908 }
909 virtual void setModuleInfo(MachineModuleInfo* Info) {}
910 };
911
912 class X86MCCodeEmitter : public MCCodeEmitter {
913 X86MCCodeEmitter(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
914 void operator=(const X86MCCodeEmitter &); // DO NOT IMPLEMENT
915
916 private:
917 X86TargetMachine &TM;
918 llvm::Function *DummyF;
919 TargetData *DummyTD;
920 mutable llvm::MachineFunction *DummyMF;
921 llvm::MachineBasicBlock *DummyMBB;
922
923 MCSingleInstructionCodeEmitter *InstrEmitter;
924 Emitter *Emit;
925
926 public:
927 X86MCCodeEmitter(X86TargetMachine &_TM) : TM(_TM) {
928 // Verily, thou shouldst avert thine eyes.
929 const llvm::FunctionType *FTy =
930 FunctionType::get(llvm::Type::getVoidTy(getGlobalContext()), false);
931 DummyF = Function::Create(FTy, GlobalValue::InternalLinkage);
932 DummyTD = new TargetData("");
933 DummyMF = new MachineFunction(DummyF, TM);
934 DummyMBB = DummyMF->CreateMachineBasicBlock();
935
936 InstrEmitter = new MCSingleInstructionCodeEmitter();
937 Emit = new Emitter(TM, *InstrEmitter,
938 *TM.getInstrInfo(),
939 *DummyTD, false);
940 }
941 ~X86MCCodeEmitter() {
942 delete Emit;
943 delete InstrEmitter;
944 delete DummyMF;
945 delete DummyF;
946 }
947
948 bool AddRegToInstr(const MCInst &MI, MachineInstr *Instr,
949 unsigned Start) const {
950 if (Start + 1 > MI.getNumOperands())
951 return false;
952
953 const MCOperand &Op = MI.getOperand(Start);
954 if (!Op.isReg()) return false;
955
956 Instr->addOperand(MachineOperand::CreateReg(Op.getReg(), false));
957 return true;
958 }
959
960 bool AddImmToInstr(const MCInst &MI, MachineInstr *Instr,
961 unsigned Start) const {
962 if (Start + 1 > MI.getNumOperands())
963 return false;
964
965 const MCOperand &Op = MI.getOperand(Start);
966 if (Op.isImm()) {
967 Instr->addOperand(MachineOperand::CreateImm(Op.getImm()));
968 return true;
969 }
970 if (!Op.isMCValue())
971 return false;
972
973 // FIXME: Relocation / fixup.
974 Instr->addOperand(MachineOperand::CreateImm(0));
975 return true;
976 }
977
978 bool AddLMemToInstr(const MCInst &MI, MachineInstr *Instr,
979 unsigned Start) const {
980 return (AddRegToInstr(MI, Instr, Start + 0) &&
981 AddImmToInstr(MI, Instr, Start + 1) &&
982 AddRegToInstr(MI, Instr, Start + 2) &&
983 AddImmToInstr(MI, Instr, Start + 3));
984 }
985
986 bool AddMemToInstr(const MCInst &MI, MachineInstr *Instr,
987 unsigned Start) const {
988 return (AddRegToInstr(MI, Instr, Start + 0) &&
989 AddImmToInstr(MI, Instr, Start + 1) &&
990 AddRegToInstr(MI, Instr, Start + 2) &&
991 AddImmToInstr(MI, Instr, Start + 3) &&
992 AddRegToInstr(MI, Instr, Start + 4));
993 }
994
995 void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
996 // Don't look yet!
997
998 // Convert the MCInst to a MachineInstr so we can (ab)use the regular
999 // emitter.
1000 const X86InstrInfo &II = *TM.getInstrInfo();
1001 const TargetInstrDesc &Desc = II.get(MI.getOpcode());
1002 MachineInstr *Instr = DummyMF->CreateMachineInstr(Desc, DebugLoc());
1003 DummyMBB->push_back(Instr);
1004
1005 unsigned Opcode = MI.getOpcode();
1006 unsigned NumOps = MI.getNumOperands();
1007 unsigned CurOp = 0;
1008 if (NumOps > 1 && Desc.getOperandConstraint(1, TOI::TIED_TO) != -1) {
1009 Instr->addOperand(MachineOperand::CreateReg(0, false));
1010 ++CurOp;
1011 } else if (NumOps > 2 &&
1012 Desc.getOperandConstraint(NumOps-1, TOI::TIED_TO)== 0)
1013 // Skip the last source operand that is tied_to the dest reg. e.g. LXADD32
1014 --NumOps;
1015
1016 bool OK = true;
1017 switch (Desc.TSFlags & X86II::FormMask) {
1018 case X86II::MRMDestReg:
1019 case X86II::MRMSrcReg:
1020 // Matching doesn't fill this in completely, we have to choose operand 0
1021 // for a tied register.
1022 OK &= AddRegToInstr(MI, Instr, 0); CurOp++;
1023 OK &= AddRegToInstr(MI, Instr, CurOp++);
1024 if (CurOp < NumOps)
1025 OK &= AddImmToInstr(MI, Instr, CurOp);
1026 break;
1027
1028 case X86II::RawFrm:
1029 if (CurOp < NumOps) {
1030 // Hack to make branches work.
1031 if (!(Desc.TSFlags & X86II::ImmMask) &&
1032 MI.getOperand(0).isMCValue() &&
1033 MI.getOperand(0).getMCValue().getSymA() &&
1034 !MI.getOperand(0).getMCValue().getSymB())
1035 Instr->addOperand(MachineOperand::CreateMBB(DummyMBB));
1036 else
1037 OK &= AddImmToInstr(MI, Instr, CurOp);
1038 }
1039 break;
1040
1041 case X86II::AddRegFrm:
1042 OK &= AddRegToInstr(MI, Instr, CurOp++);
1043 if (CurOp < NumOps)
1044 OK &= AddImmToInstr(MI, Instr, CurOp);
1045 break;
1046
1047 case X86II::MRM0r: case X86II::MRM1r:
1048 case X86II::MRM2r: case X86II::MRM3r:
1049 case X86II::MRM4r: case X86II::MRM5r:
1050 case X86II::MRM6r: case X86II::MRM7r:
1051 // Matching doesn't fill this in completely, we have to choose operand 0
1052 // for a tied register.
1053 OK &= AddRegToInstr(MI, Instr, 0); CurOp++;
1054 if (CurOp < NumOps)
1055 OK &= AddImmToInstr(MI, Instr, CurOp);
1056 break;
1057
1058 case X86II::MRM0m: case X86II::MRM1m:
1059 case X86II::MRM2m: case X86II::MRM3m:
1060 case X86II::MRM4m: case X86II::MRM5m:
1061 case X86II::MRM6m: case X86II::MRM7m:
1062 OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
1063 if (CurOp < NumOps)
1064 OK &= AddImmToInstr(MI, Instr, CurOp);
1065 break;
1066
1067 case X86II::MRMSrcMem:
1068 OK &= AddRegToInstr(MI, Instr, CurOp++);
1069 if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
1070 Opcode == X86::LEA16r || Opcode == X86::LEA32r)
1071 OK &= AddLMemToInstr(MI, Instr, CurOp);
1072 else
1073 OK &= AddMemToInstr(MI, Instr, CurOp);
1074 break;
1075
1076 case X86II::MRMDestMem:
1077 OK &= AddMemToInstr(MI, Instr, CurOp); CurOp += 5;
1078 OK &= AddRegToInstr(MI, Instr, CurOp);
1079 break;
1080
1081 default:
1082 case X86II::MRMInitReg:
1083 case X86II::Pseudo:
1084 OK = false;
1085 break;
1086 }
1087
1088 if (!OK) {
1089 errs() << "couldn't convert inst '";
1090 MI.print(errs());
1091 errs() << "' to machine instr:\n";
1092 Instr->dump();
1093 }
1094
1095 InstrEmitter->reset();
1096 if (OK)
1097 Emit->emitInstruction(*Instr, &Desc);
1098 OS << InstrEmitter->str();
1099
1100 Instr->eraseFromParent();
1101 }
1102 };
1103 }
1104
1105 // Ok, now you can look.
1106 MCCodeEmitter *llvm::createX86MCCodeEmitter(const Target &,
1107 TargetMachine &TM) {
1108 return new X86MCCodeEmitter(static_cast(TM));
1109 }
4646 // Register the target asm info.
4747 RegisterAsmInfoFn A(TheX86_32Target, createMCAsmInfo);
4848 RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo);
49
50 // Register the code emitter.
51 TargetRegistry::RegisterCodeEmitter(TheX86_32Target, createX86MCCodeEmitter);
52 TargetRegistry::RegisterCodeEmitter(TheX86_64Target, createX86MCCodeEmitter);
4953 }
5054
5155