summaryrefslogtreecommitdiffstats
path: root/lib/Target/X86
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-10-25 22:55:53 +0000
committerChris Lattner <sabre@nondot.org>2002-10-25 22:55:53 +0000
commit726140821f96e3472a8eccef0c67c0b5ad65a1d9 (patch)
tree39e64fba6031b0208095b08d1302fcb4b0972c3f /lib/Target/X86
parenta750de9bfb75f547c670a3c96d836a6dcefc2529 (diff)
downloadexternal_llvm-726140821f96e3472a8eccef0c67c0b5ad65a1d9.zip
external_llvm-726140821f96e3472a8eccef0c67c0b5ad65a1d9.tar.gz
external_llvm-726140821f96e3472a8eccef0c67c0b5ad65a1d9.tar.bz2
Initial checkin of X86 backend.
We can instruction select exactly one instruction 'ret void'. Wow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4284 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp133
-rw-r--r--lib/Target/X86/Makefile4
-rw-r--r--lib/Target/X86/Printer.cpp21
-rw-r--r--lib/Target/X86/README.txt143
-rw-r--r--lib/Target/X86/X86.h61
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp21
-rw-r--r--lib/Target/X86/X86ISelSimple.cpp133
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp29
-rw-r--r--lib/Target/X86/X86InstrInfo.def40
-rw-r--r--lib/Target/X86/X86InstrInfo.h30
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp19
-rw-r--r--lib/Target/X86/X86RegisterInfo.def68
-rw-r--r--lib/Target/X86/X86RegisterInfo.h17
13 files changed, 719 insertions, 0 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
new file mode 100644
index 0000000..361f459
--- /dev/null
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -0,0 +1,133 @@
+//===-- InstSelectSimple.cpp - A simple instruction selector for x86 ------===//
+//
+// This file defines a simple peephole instruction selector for the x86 platform
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86InstructionInfo.h"
+#include "llvm/Function.h"
+#include "llvm/iTerminators.h"
+#include "llvm/Type.h"
+#include "llvm/CodeGen/MFunction.h"
+#include "llvm/CodeGen/MInstBuilder.h"
+#include "llvm/Support/InstVisitor.h"
+#include <map>
+
+namespace {
+ struct ISel : public InstVisitor<ISel> { // eventually will be a FunctionPass
+ MFunction *F; // The function we are compiling into
+ MBasicBlock *BB; // The current basic block we are compiling
+
+ unsigned CurReg;
+ std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs
+
+ ISel(MFunction *f)
+ : F(f), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
+
+ /// runOnFunction - Top level implementation of instruction selection for
+ /// the entire function.
+ ///
+ bool runOnFunction(Function &F) {
+ visit(F);
+ RegMap.clear();
+ return false; // We never modify the LLVM itself.
+ }
+
+ /// visitBasicBlock - This method is called when we are visiting a new basic
+ /// block. This simply creates a new MBasicBlock to emit code into and adds
+ /// it to the current MFunction. Subsequent visit* for instructions will be
+ /// invoked for all instructions in the basic block.
+ ///
+ void visitBasicBlock(BasicBlock &LLVM_BB) {
+ BB = new MBasicBlock();
+ // FIXME: Use the auto-insert form when it's available
+ F->getBasicBlockList().push_back(BB);
+ }
+
+ // Visitation methods for various instructions. These methods simply emit
+ // fixed X86 code for each instruction.
+ //
+ void visitReturnInst(ReturnInst &RI);
+ void visitAdd(BinaryOperator &B);
+
+ void visitInstruction(Instruction &I) {
+ std::cerr << "Cannot instruction select: " << I;
+ abort();
+ }
+
+ /// getReg - This method turns an LLVM value into a register number. This
+ /// is guaranteed to produce the same register number for a particular value
+ /// every time it is queried.
+ ///
+ unsigned getReg(Value &V) { return getReg(&V); } // Allow references
+ unsigned getReg(Value *V) {
+ unsigned &Reg = RegMap[V];
+ if (Reg == 0)
+ Reg = CurReg++;
+
+ // FIXME: Constants should be thrown into registers here and appended to
+ // the end of the current basic block!
+
+ return Reg;
+ }
+
+ };
+}
+
+/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such,
+/// we have the following possibilities:
+///
+/// ret void: No return value, simply emit a 'ret' instruction
+/// ret sbyte, ubyte : Extend value into EAX and return
+/// ret short, ushort: Extend value into EAX and return
+/// ret int, uint : Move value into EAX and return
+/// ret pointer : Move value into EAX and return
+/// ret long, ulong : Move value into EAX/EDX (?) and return
+/// ret float/double : ? Top of FP stack? XMM0?
+///
+void ISel::visitReturnInst(ReturnInst &I) {
+ if (I.getNumOperands() != 0) { // Not 'ret void'?
+ // Move result into a hard register... then emit a ret
+ visitInstruction(I); // abort
+ }
+
+ // Emit a simple 'ret' instruction... appending it to the end of the basic
+ // block
+ new MInstruction(BB, X86::RET);
+}
+
+
+/// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
+void ISel::visitAdd(BinaryOperator &B) {
+ unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
+ unsigned DestReg = getReg(B);
+
+ switch (B.getType()->getPrimitiveSize()) {
+ case 1: // UByte, SByte
+ BuildMInst(BB, X86::ADDrr8, DestReg).addReg(Op0r).addReg(Op1r);
+ break;
+ case 2: // UShort, Short
+ BuildMInst(BB, X86::ADDrr16, DestReg).addReg(Op0r).addReg(Op1r);
+ break;
+ case 4: // UInt, Int
+ BuildMInst(BB, X86::ADDrr32, DestReg).addReg(Op0r).addReg(Op1r);
+ break;
+
+ case 8: // ULong, Long
+ default:
+ visitInstruction(B); // abort
+ }
+}
+
+
+
+/// X86SimpleInstructionSelection - This function converts an LLVM function into
+/// a machine code representation is a very simple peep-hole fashion. The
+/// generated code sucks but the implementation is nice and simple.
+///
+MFunction *X86SimpleInstructionSelection(Function &F) {
+ MFunction *Result = new MFunction();
+ ISel(Result).runOnFunction(F);
+ return Result;
+}
diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile
new file mode 100644
index 0000000..ba71b6b
--- /dev/null
+++ b/lib/Target/X86/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../..
+LIBRARYNAME = x86
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp
new file mode 100644
index 0000000..88aa89c
--- /dev/null
+++ b/lib/Target/X86/Printer.cpp
@@ -0,0 +1,21 @@
+//===-- X86/Printer.cpp - Convert X86 code to human readable rep. ---------===//
+//
+// This file contains a printer that converts from our internal representation
+// of LLVM code to a nice human readable form that is suitable for debuggging.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include <iostream>
+
+/// X86PrintCode - Print out the specified machine code function to the
+/// specified stream. This function should work regardless of whether or not
+/// the function is in SSA form or not, although when in SSA form, we obviously
+/// don't care about being consumable by an assembler.
+///
+void X86PrintCode(const MFunction *MF, std::ostream &O) {
+ O << "x86 printing not implemented yet!\n";
+
+ // This should use the X86InstructionInfo::print method to print assembly for
+ // each instruction
+}
diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt
new file mode 100644
index 0000000..c310bff
--- /dev/null
+++ b/lib/Target/X86/README.txt
@@ -0,0 +1,143 @@
+//===- README.txt - Information about the X86 backend and related files ---===//
+//
+// This file contains random notes and points of interest about the X86 backend.
+//
+// Snippets of this document will probably become the final report for CS497
+//
+//===----------------------------------------------------------------------===//
+
+===========
+I. Overview
+===========
+
+This directory contains a machine description for the X86 processor. Currently
+this machine description is used for a high performance code generator used by a
+LLVM JIT. One of the main objectives that we would like to support with this
+project is to build a nice clean code generator that may be extended in the
+future in a variety of ways: new targets, new optimizations, new
+transformations, etc.
+
+This document describes the current state of the LLVM JIT, along with
+implementation notes, design decisions, and other stuff.
+
+
+===================================
+II. Architecture / Design Decisions
+===================================
+
+We designed the infrastructure for the machine specific representation to be as
+light-weight as possible, while also being able to support as many targets as
+possible with our framework. This framework should allow us to share many
+common machine specific transformations (register allocation, instruction
+scheduling, etc...) among all of the backends that may eventually be supported
+by the JIT, and unify the JIT and static compiler backends.
+
+At the high-level, LLVM code is translated to a machine specific representation
+formed out of MFunction, MBasicBlock, and MInstruction instances (defined in
+include/llvm/CodeGen). This representation is completely target agnostic,
+representing instructions in their most abstract form: an opcode, a destination,
+and a series of operands. This representation is designed to support both SSA
+representation for machine code, as well as a register allocated, non-SSA form.
+
+Because the M* representation must work regardless of the target machine, it
+contains very little semantic information about the program. To get semantic
+information about the program, a layer of Target description datastructures are
+used, defined in include/llvm/Target.
+
+Currently the Sparc backend and the X86 backend do not share a common
+representation. This is an intentional decision, and will be rectified in the
+future (after the project is done).
+
+
+=======================
+III. Source Code Layout
+=======================
+
+The LLVM-JIT is composed of source files primarily in the following locations:
+
+include/llvm/CodeGen
+--------------------
+
+This directory contains header files that are used to represent the program in a
+machine specific representation. It currently also contains a bunch of stuff
+used by the Sparc backend that we don't want to get mixed up in.
+
+include/llvm/Target
+-------------------
+
+This directory contains header files that are used to interpret the machine
+specific representation of the program. This allows us to write generic
+transformations that will work on any target that implements the interfaces
+defined in this directory. Again, this also contains a bunch of stuff from the
+Sparc Backend that we don't want to deal with.
+
+lib/CodeGen
+-----------
+This directory will contain all of the target independant transformations (for
+example, register allocation) that we write. These transformations should only
+use information exposed through the Target interface, it should not include any
+target specific header files.
+
+lib/Target/X86
+--------------
+This directory contains the machine description for X86 that is required to the
+rest of the compiler working. It contains any code that is truely specific to
+the X86 backend, for example the instruction selector and machine code emitter.
+
+tools/jello
+-----------
+This directory contains the top-level code for the JIT compiler.
+
+test/Regression/Jello
+---------------------
+This directory contains regression tests for the JIT. Initially it contains a
+bunch of really trivial testcases that we should build up to supporting.
+
+
+==========================
+IV. TODO / Future Projects
+==========================
+
+There are a large number of things remaining to do. Here is a partial list:
+
+Critial path:
+-------------
+
+0. Finish providing SSA form. This involves keeping track of some information
+ when instructions are added to the function, but should not affect that API
+ for creating new MInstructions or adding them to the program. There are
+ also various FIXMEs in the M* files that need to get taken care of in the
+ near term.
+1. Finish dumb instruction selector
+2. Write dumb register allocator
+3. Write assembly language emitter
+4. Write machine code emitter
+
+Next Phase:
+-----------
+1. Implement linear time optimal instruction selector
+2. Implement smarter (linear scan?) register allocator
+
+After this project:
+-------------------
+1. Implement lots of nifty runtime optimizations
+2. Implement a static compiler backend for x86
+3. Migrate Sparc backend to new representation
+4. Implement new spiffy targets: IA64? X86-64? M68k? Who knows...
+
+Infrastructure Improvements:
+----------------------------
+
+1. Bytecode is designed to be able to read particular functions from the
+ bytecode without having to read the whole program. Bytecode reader should be
+ extended to allow on demand loading of functions.
+
+2. PassManager needs to be able to run just a single function through a pipeline
+ of FunctionPass's. When this happens, all of our code will become
+ FunctionPass's for real.
+
+3. llvmgcc needs to be modified to output 32-bit little endian LLVM files.
+ Preferably it will be parameterizable so that multiple binaries need not
+ exist. Until this happens, we will be restricted to using type safe
+ programs (most of the Olden suite and many smaller tests), which should be
+ sufficient for our 497 project.
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
new file mode 100644
index 0000000..135e55a
--- /dev/null
+++ b/lib/Target/X86/X86.h
@@ -0,0 +1,61 @@
+//===-- X86.h - Top-level interface for X86 representation ------*- C++ -*-===//
+//
+// This file contains the entry points for global functions defined in the x86
+// target library, as used by the LLVM JIT.
+//
+// FIXME: This file will be dramatically changed in the future
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_X86_H
+#define TARGET_X86_H
+
+#include <iosfwd>
+class MFunction;
+class Function;
+
+/// X86PrintCode - Print out the specified machine code function to the
+/// specified stream. This function should work regardless of whether or not
+/// the function is in SSA form or not.
+///
+void X86PrintCode(const MFunction *MF, std::ostream &O);
+
+/// X86SimpleInstructionSelection - This function converts an LLVM function into
+/// a machine code representation is a very simple peep-hole fashion. The
+/// generated code sucks but the implementation is nice and simple.
+///
+MFunction *X86SimpleInstructionSelection(Function &F);
+
+/// X86SimpleRegisterAllocation - This function converts the specified machine
+/// code function from SSA form to use explicit registers by spilling every
+/// register. Wow, great policy huh?
+///
+inline void X86SimpleRegisterAllocation(MFunction *MF) {}
+
+/// X86EmitCodeToMemory - This function converts a register allocated function
+/// into raw machine code in a dynamically allocated chunk of memory. A pointer
+/// to the start of the function is returned.
+///
+inline void *X86EmitCodeToMemory(MFunction *MF) { return 0; }
+
+
+// Put symbolic names in a namespace to avoid causing these to clash with all
+// kinds of other things...
+//
+namespace X86 {
+ // Defines a large number of symbolic names for X86 registers. This defines a
+ // mapping from register name to register number.
+ //
+ enum Register {
+#define R(ENUM, NAME, FLAGS, TSFLAGS) ENUM,
+#include "X86RegisterInfo.def"
+ };
+
+ // This defines a large number of symbolic names for X86 instruction opcodes.
+ enum Opcode {
+#define I(ENUM, NAME, FLAGS, TSFLAGS) ENUM,
+#include "X86InstructionInfo.def"
+ };
+}
+
+#endif
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
new file mode 100644
index 0000000..88aa89c
--- /dev/null
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -0,0 +1,21 @@
+//===-- X86/Printer.cpp - Convert X86 code to human readable rep. ---------===//
+//
+// This file contains a printer that converts from our internal representation
+// of LLVM code to a nice human readable form that is suitable for debuggging.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include <iostream>
+
+/// X86PrintCode - Print out the specified machine code function to the
+/// specified stream. This function should work regardless of whether or not
+/// the function is in SSA form or not, although when in SSA form, we obviously
+/// don't care about being consumable by an assembler.
+///
+void X86PrintCode(const MFunction *MF, std::ostream &O) {
+ O << "x86 printing not implemented yet!\n";
+
+ // This should use the X86InstructionInfo::print method to print assembly for
+ // each instruction
+}
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp
new file mode 100644
index 0000000..361f459
--- /dev/null
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -0,0 +1,133 @@
+//===-- InstSelectSimple.cpp - A simple instruction selector for x86 ------===//
+//
+// This file defines a simple peephole instruction selector for the x86 platform
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86InstructionInfo.h"
+#include "llvm/Function.h"
+#include "llvm/iTerminators.h"
+#include "llvm/Type.h"
+#include "llvm/CodeGen/MFunction.h"
+#include "llvm/CodeGen/MInstBuilder.h"
+#include "llvm/Support/InstVisitor.h"
+#include <map>
+
+namespace {
+ struct ISel : public InstVisitor<ISel> { // eventually will be a FunctionPass
+ MFunction *F; // The function we are compiling into
+ MBasicBlock *BB; // The current basic block we are compiling
+
+ unsigned CurReg;
+ std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs
+
+ ISel(MFunction *f)
+ : F(f), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
+
+ /// runOnFunction - Top level implementation of instruction selection for
+ /// the entire function.
+ ///
+ bool runOnFunction(Function &F) {
+ visit(F);
+ RegMap.clear();
+ return false; // We never modify the LLVM itself.
+ }
+
+ /// visitBasicBlock - This method is called when we are visiting a new basic
+ /// block. This simply creates a new MBasicBlock to emit code into and adds
+ /// it to the current MFunction. Subsequent visit* for instructions will be
+ /// invoked for all instructions in the basic block.
+ ///
+ void visitBasicBlock(BasicBlock &LLVM_BB) {
+ BB = new MBasicBlock();
+ // FIXME: Use the auto-insert form when it's available
+ F->getBasicBlockList().push_back(BB);
+ }
+
+ // Visitation methods for various instructions. These methods simply emit
+ // fixed X86 code for each instruction.
+ //
+ void visitReturnInst(ReturnInst &RI);
+ void visitAdd(BinaryOperator &B);
+
+ void visitInstruction(Instruction &I) {
+ std::cerr << "Cannot instruction select: " << I;
+ abort();
+ }
+
+ /// getReg - This method turns an LLVM value into a register number. This
+ /// is guaranteed to produce the same register number for a particular value
+ /// every time it is queried.
+ ///
+ unsigned getReg(Value &V) { return getReg(&V); } // Allow references
+ unsigned getReg(Value *V) {
+ unsigned &Reg = RegMap[V];
+ if (Reg == 0)
+ Reg = CurReg++;
+
+ // FIXME: Constants should be thrown into registers here and appended to
+ // the end of the current basic block!
+
+ return Reg;
+ }
+
+ };
+}
+
+/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such,
+/// we have the following possibilities:
+///
+/// ret void: No return value, simply emit a 'ret' instruction
+/// ret sbyte, ubyte : Extend value into EAX and return
+/// ret short, ushort: Extend value into EAX and return
+/// ret int, uint : Move value into EAX and return
+/// ret pointer : Move value into EAX and return
+/// ret long, ulong : Move value into EAX/EDX (?) and return
+/// ret float/double : ? Top of FP stack? XMM0?
+///
+void ISel::visitReturnInst(ReturnInst &I) {
+ if (I.getNumOperands() != 0) { // Not 'ret void'?
+ // Move result into a hard register... then emit a ret
+ visitInstruction(I); // abort
+ }
+
+ // Emit a simple 'ret' instruction... appending it to the end of the basic
+ // block
+ new MInstruction(BB, X86::RET);
+}
+
+
+/// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
+void ISel::visitAdd(BinaryOperator &B) {
+ unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
+ unsigned DestReg = getReg(B);
+
+ switch (B.getType()->getPrimitiveSize()) {
+ case 1: // UByte, SByte
+ BuildMInst(BB, X86::ADDrr8, DestReg).addReg(Op0r).addReg(Op1r);
+ break;
+ case 2: // UShort, Short
+ BuildMInst(BB, X86::ADDrr16, DestReg).addReg(Op0r).addReg(Op1r);
+ break;
+ case 4: // UInt, Int
+ BuildMInst(BB, X86::ADDrr32, DestReg).addReg(Op0r).addReg(Op1r);
+ break;
+
+ case 8: // ULong, Long
+ default:
+ visitInstruction(B); // abort
+ }
+}
+
+
+
+/// X86SimpleInstructionSelection - This function converts an LLVM function into
+/// a machine code representation is a very simple peep-hole fashion. The
+/// generated code sucks but the implementation is nice and simple.
+///
+MFunction *X86SimpleInstructionSelection(Function &F) {
+ MFunction *Result = new MFunction();
+ ISel(Result).runOnFunction(F);
+ return Result;
+}
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
new file mode 100644
index 0000000..f718534
--- /dev/null
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -0,0 +1,29 @@
+//===- X86InstructionInfo.cpp - X86 Instruction Information ---------------===//
+//
+// This file contains the X86 implementation of the MInstructionInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86InstructionInfo.h"
+#include "llvm/CodeGen/MInstruction.h"
+#include <ostream>
+
+// X86Insts - Turn the InstructionInfo.def file into a bunch of instruction
+// descriptors
+//
+static const MInstructionDesc X86Insts[] = {
+#define I(ENUM, NAME, FLAGS, TSFLAGS) { NAME, FLAGS, TSFLAGS },
+#include "X86InstructionInfo.def"
+};
+
+X86InstructionInfo::X86InstructionInfo()
+ : MInstructionInfo(X86Insts, sizeof(X86Insts)/sizeof(X86Insts[0])) {
+}
+
+
+// print - Print out an x86 instruction in GAS syntax
+void X86InstructionInfo::print(const MInstruction *MI, std::ostream &O) const {
+ // FIXME: This sucks.
+ O << get(MI->getOpcode()).Name << "\n";
+}
+
diff --git a/lib/Target/X86/X86InstrInfo.def b/lib/Target/X86/X86InstrInfo.def
new file mode 100644
index 0000000..5ba0e6f
--- /dev/null
+++ b/lib/Target/X86/X86InstrInfo.def
@@ -0,0 +1,40 @@
+//===-- X86InstructionInfo.def - X86 Instruction Information ----*- C++ -*-===//
+//
+// This file describes all of the instructions that the X86 backend uses. It
+// relys on an external 'I' macro being defined that takes the arguments
+// specified below, and is used to make all of the information relevant to an
+// instruction be in one place.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: No include guards desired
+
+#ifndef I
+#errror "Must define I macro before including X86/X86InstructionInfo.def!"
+#endif
+
+// Arguments to be passed into the I macro
+// #1: Enum name - This ends up being the opcode symbol in the X86 namespace
+// #2: Opcode name, as used by the gnu assembler
+// #3: Instruction Flags - This should be a field or'd together that contains
+// constants from the MInstructionInfo.h file.
+// #4: Target Specific Flags - Another bitfield containing X86 specific flags
+// that we are interested in for each instruction
+//
+
+// The first instruction must always be the PHI instruction:
+I(PHI , "phi", 0, 0)
+
+// The second instruction must always be the noop instruction
+I(NOOP , "nop", 0, 0) // nop 90
+
+// Miscellaneous instructions
+I(RET , "ret", MIF::RET, 0) // ret CB
+
+I(ADDrr8 , "add", 0, 0) // R8 += R8 00/r
+I(ADDrr16 , "add", 0, 0) // R16 += R16 01/r
+I(ADDrr32 , "addl", 0, 0) // R32 += R32 02/r
+
+
+// At this point, I is dead to undefine the macro
+#undef I
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
new file mode 100644
index 0000000..116e6b1
--- /dev/null
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -0,0 +1,30 @@
+//===- X86InstructionInfo.h - X86 Instruction Information ---------*-C++-*-===//
+//
+// This file contains the X86 implementation of the MInstructionInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86INSTRUCTIONINFO_H
+#define X86INSTRUCTIONINFO_H
+
+#include "llvm/Target/MInstructionInfo.h"
+#include "X86RegisterInfo.h"
+
+class X86InstructionInfo : public MInstructionInfo {
+ const X86RegisterInfo RI;
+public:
+ X86InstructionInfo();
+
+ /// getRegisterInfo - MInstructionInfo is a superset of MRegister info. As
+ /// such, whenever a client has an instance of instruction info, it should
+ /// always be able to get register info as well (through this method).
+ ///
+ virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
+
+ /// print - Print out an x86 instruction in GAS syntax
+ ///
+ virtual void print(const MInstruction *MI, std::ostream &O) const;
+};
+
+
+#endif
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
new file mode 100644
index 0000000..1dfa723
--- /dev/null
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -0,0 +1,19 @@
+//===- X86RegisterInfo.cpp - X86 Register Information ---------------------===//
+//
+// This file contains the X86 implementation of the MRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86RegisterInfo.h"
+
+// X86Regs - Turn the X86RegisterInfo.def file into a bunch of register
+// descriptors
+//
+static const MRegisterDesc X86Regs[] = {
+#define R(ENUM, NAME, FLAGS, TSFLAGS) { NAME, FLAGS, TSFLAGS },
+#include "X86RegisterInfo.def"
+};
+
+X86RegisterInfo::X86RegisterInfo()
+ : MRegisterInfo(X86Regs, sizeof(X86Regs)/sizeof(X86Regs[0])) {
+}
diff --git a/lib/Target/X86/X86RegisterInfo.def b/lib/Target/X86/X86RegisterInfo.def
new file mode 100644
index 0000000..09da9f3
--- /dev/null
+++ b/lib/Target/X86/X86RegisterInfo.def
@@ -0,0 +1,68 @@
+//===-- X86RegisterInfo.def - X86 Register Information ----------*- C++ -*-===//
+//
+// This file describes all of the registers that the X86 backend uses. It relys
+// on an external 'R' macro being defined that takes the arguments specified
+// below, and is used to make all of the information relevant to an registers be
+// in one place.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: No include guards desired
+
+#ifndef R
+#errror "Must define R macro before including X86/X86RegisterInfo.def!"
+#endif
+
+// Arguments passed into the R macro
+// #1: Enum Name - This ends up being a symbol in the X86 namespace
+// #2: Register name - The name of the register as used by the gnu assembler
+// #3: Register Flags - A bitfield of flags or'd together from the
+// MRegisterInfo.h file.
+// #4: Target Specific Flags - Another bitfield containing X86 specific flags
+// as neccesary.
+
+
+// The first register must always be a 'noop' register for all backends. This
+// is used as the destination register for instructions that do not produce a
+// value. Some frontends may use this as an operand register to mean special
+// things, for example, the Sparc backend uses R#0 to mean %g0 which always
+// PRODUCES the value 0. The X86 backend does not use this value as an operand
+// register.
+//
+R(NoReg, "none", 0, 0)
+
+
+// 32 bit registers, ordered as the processor does...
+R(EAX, "eax", MRF::INT32, 0)
+R(ECX, "ecx", MRF::INT32, 0)
+R(EDX, "edx", MRF::INT32, 0)
+R(EBX, "ebx", MRF::INT32, 0)
+R(ESP, "esp", MRF::INT32, 0)
+R(EBP, "ebp", MRF::INT32, 0)
+R(ESI, "esi", MRF::INT32, 0)
+R(EDI, "edi", MRF::INT32, 0)
+
+// 16 bit registers, aliased with the corresponding 32 bit registers above
+R(AX, "ax", MRF::INT16, 0)
+R(CX, "cx", MRF::INT16, 0)
+R(DX, "dx", MRF::INT16, 0)
+R(BX, "bx", MRF::INT16, 0)
+R(SP, "sp", MRF::INT16, 0)
+R(BP, "bp", MRF::INT16, 0)
+R(SI, "si", MRF::INT16, 0)
+R(DI, "di", MRF::INT16, 0)
+
+// 8 bit registers aliased with registers above as well
+R(AL, "al", MRF::INT8, 0)
+R(CL, "cl", MRF::INT8, 0)
+R(DL, "dl", MRF::INT8, 0)
+R(BL, "bl", MRF::INT8, 0)
+R(AH, "ah", MRF::INT8, 0)
+R(CH, "ch", MRF::INT8, 0)
+R(DH, "dh", MRF::INT8, 0)
+R(BH, "bh", MRF::INT8, 0)
+
+// Flags, Segment registers, etc...
+
+// We are now done with the R macro
+#undef R
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
new file mode 100644
index 0000000..243861b
--- /dev/null
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -0,0 +1,17 @@
+//===- X86RegisterInfo.h - X86 Register Information Impl ----------*-C++-*-===//
+//
+// This file contains the X86 implementation of the MRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86REGISTERINFO_H
+#define X86REGISTERINFO_H
+
+#include "llvm/Target/MRegisterInfo.h"
+
+struct X86RegisterInfo : public MRegisterInfo {
+ X86RegisterInfo();
+
+};
+
+#endif