llvm-6502/lib/Target/X86
Chris Lattner 9f1b531090 Second half of my fixed-sized-alloca patch. This folds the LEA to compute
the alloca address into common operations like loads/stores.

In a simple testcase like this (which is just designed to excersize the
alloca A, nothing more):

int %test(int %X, bool %C) {
        %A = alloca int
        store int %X, int* %A
        store int* %A, int** %G
        br bool %C, label %T, label %F
T:
        call int %test(int 1, bool false)
        %V = load int* %A
        ret int %V
F:
        call int %test(int 123, bool true)
        %V2 = load int* %A
        ret int %V2
}

We now generate:

test:
        sub %ESP, 12
        mov %EAX, DWORD PTR [%ESP + 16]
        mov %CL, BYTE PTR [%ESP + 20]
***     mov DWORD PTR [%ESP + 8], %EAX
        mov %EAX, OFFSET G
        lea %EDX, DWORD PTR [%ESP + 8]
        mov DWORD PTR [%EAX], %EDX
        test %CL, %CL
        je .LBB2 # PC rel: F
.LBB1:  # T
        mov DWORD PTR [%ESP], 1
        mov DWORD PTR [%ESP + 4], 0
        call test
***     mov %EAX, DWORD PTR [%ESP + 8]
        add %ESP, 12
        ret
.LBB2:  # F
        mov DWORD PTR [%ESP], 123
        mov DWORD PTR [%ESP + 4], 1
        call test
***     mov %EAX, DWORD PTR [%ESP + 8]
        add %ESP, 12
        ret

Instead of:

test:
        sub %ESP, 20
        mov %EAX, DWORD PTR [%ESP + 24]
        mov %CL, BYTE PTR [%ESP + 28]
***     lea %EDX, DWORD PTR [%ESP + 16]
***     mov DWORD PTR [%EDX], %EAX
        mov %EAX, OFFSET G
        mov DWORD PTR [%EAX], %EDX
        test %CL, %CL
***     mov DWORD PTR [%ESP + 12], %EDX
        je .LBB2 # PC rel: F
.LBB1:  # T
        mov DWORD PTR [%ESP], 1
        mov %EAX, 0
        mov DWORD PTR [%ESP + 4], %EAX
        call test
***     mov %EAX, DWORD PTR [%ESP + 12]
***     mov %EAX, DWORD PTR [%EAX]
        add %ESP, 20
        ret
.LBB2:  # F
        mov DWORD PTR [%ESP], 123
        mov %EAX, 1
        mov DWORD PTR [%ESP + 4], %EAX
        call test
***     mov %EAX, DWORD PTR [%ESP + 12]
***     mov %EAX, DWORD PTR [%EAX]
        add %ESP, 20
        ret


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13557 91177308-0d34-0410-b5e6-96231b3b80d8
2004-05-13 15:12:43 +00:00
..
.cvsignore Tell CVS to ignore all .inc files 2003-08-03 15:50:17 +00:00
FloatingPoint.cpp Iterate over the Machine CFG that Brian added instead of the LLVM CFG. 2004-05-01 21:27:53 +00:00
InstSelectPattern.cpp Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering 2003-12-28 21:23:38 +00:00
InstSelectSimple.cpp Second half of my fixed-sized-alloca patch. This folds the LEA to compute 2004-05-13 15:12:43 +00:00
Makefile Tablgen files for really simple instruction selector 2004-04-06 19:34:00 +00:00
PeepholeOptimizer.cpp Add more ADC and SBB variants 2004-04-02 07:11:10 +00:00
Printer.cpp Add support for the printImplicitDefsBefore flag 2004-04-13 17:18:39 +00:00
README.txt Add instruction name description. 2004-02-29 18:44:03 +00:00
X86.h Tablgen files for really simple instruction selector 2004-04-06 19:34:00 +00:00
X86.td Add support for the printImplicitDefsBefore flag 2004-04-13 17:18:39 +00:00
X86AsmPrinter.cpp Add support for the printImplicitDefsBefore flag 2004-04-13 17:18:39 +00:00
X86CodeEmitter.cpp Use emitWordAt() to emit forward-branch fixups. 2004-04-23 17:11:16 +00:00
X86FloatingPoint.cpp Iterate over the Machine CFG that Brian added instead of the LLVM CFG. 2004-05-01 21:27:53 +00:00
X86InstrBuilder.h Add assertion for scale verification. 2004-03-04 18:05:02 +00:00
X86InstrInfo.cpp A big X86 instruction rename. The instructions are renamed to make 2004-02-29 08:50:03 +00:00
X86InstrInfo.h Add support for the printImplicitDefsBefore flag 2004-04-13 17:18:39 +00:00
X86InstrInfo.td Add immediate forms of in/out. Use let to shorten lines 2004-04-13 17:19:31 +00:00
X86InstrSel.td Tablgen files for really simple instruction selector 2004-04-06 19:34:00 +00:00
X86InstrSelInfo.td Tablgen files for really simple instruction selector 2004-04-06 19:34:00 +00:00
X86ISelPattern.cpp Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering 2003-12-28 21:23:38 +00:00
X86ISelSimple.cpp Second half of my fixed-sized-alloca patch. This folds the LEA to compute 2004-05-13 15:12:43 +00:00
X86JITInfo.h Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering 2003-12-28 21:23:38 +00:00
X86PeepholeOpt.cpp Add more ADC and SBB variants 2004-04-02 07:11:10 +00:00
X86RegisterInfo.cpp Add more ADC and SBB variants 2004-04-02 07:11:10 +00:00
X86RegisterInfo.h Another API change to MRegisterInfo::foldMemoryOperand. Instead of a 2004-03-14 20:14:27 +00:00
X86RegisterInfo.td Improve allocation order: 2004-02-29 09:17:01 +00:00
X86SimpInstrSelector.cpp file based off InstSelectSimple.cpp, slowly being replaced by generated code from the really simple X86 instruction selector tablegen backend 2004-04-06 19:35:17 +00:00
X86TargetMachine.cpp Tablgen files for really simple instruction selector 2004-04-06 19:34:00 +00:00
X86TargetMachine.h Add emitInstruction() API so that we can get the bytes of a simple instruction 2004-03-09 03:34:53 +00:00

//===- README.txt - Information about the X86 backend and related files ---===//
//
// This file contains random notes and points of interest about the X86 backend.
//
//===----------------------------------------------------------------------===//

===========
I. Overview
===========

This directory contains a machine description for the X86 processor family.
Currently this machine description is used for a high performance code generator
used by the LLVM JIT and static code generators.  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 X86 code generator, along with
implementation notes, design decisions, and other stuff.


===================================
II. Architecture / Design Decisions
===================================

We designed the infrastructure into the generic LLVM machine specific
representation, which allows us 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 LLVM, and ensures that the
JIT and static compiler backends are largely shared.

At the high-level, LLVM code is translated to a machine specific representation
formed out of MachineFunction, MachineBasicBlock, and MachineInstr instances
(defined in include/llvm/CodeGen).  This representation is completely target
agnostic, representing instructions in their most abstract form: an opcode 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 Machine* 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.

Note that there is some amount of complexity that the X86 backend contains due
to the Sparc backend's legacy requirements.  These should eventually fade away
as the project progresses.


SSA Instruction Representation
------------------------------
Target machine instructions are represented as instances of MachineInstr, and
all specific machine instruction types should have an entry in the
X86InstrInfo.td file.  In the X86 backend, there are two particularly
interesting forms of machine instruction: those that produce a value (such as
add), and those that do not (such as a store).

Instructions that produce a value use Operand #0 as the "destination" register.
When printing the assembly code with the built-in machine instruction printer,
these destination registers will be printed to the left side of an '=' sign, as
in: %reg1027 = add %reg1026, %reg1025

This `add' MachineInstruction contains three "operands": the first is the
destination register (#1027), the second is the first source register (#1026)
and the third is the second source register (#1025).  Never forget the
destination register will show up in the MachineInstr operands vector.  The code
to generate this instruction looks like this:

  BuildMI(BB, X86::ADD32rr, 2, 1027).addReg(1026).addReg(1025);

The first argument to BuildMI is the basic block to append the machine
instruction to, the second is the opcode, the third is the number of operands,
the fourth is the destination register.  The two addReg calls specify operands
in order.

MachineInstrs that do not produce a value do not have this implicit first
operand, they simply have #operands = #uses.  To create them, simply do not
specify a destination register to the BuildMI call.


======================
IV. Source Code Layout
======================

The LLVM code generator 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, such as
register allocation internals.

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.  The only classes used by the X86 backend so far are
the TargetMachine, TargetData, MachineInstrInfo, and MRegisterInfo classes.

lib/CodeGen
-----------
This directory will contain all of the target independent transformations (for
example, register allocation) that we write.  These transformations should only
use information exposed through the Target interface, they 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 truly specific to
the X86 backend, for example the instruction selector and machine code emitter.

lib/ExecutionEngine/JIT
-----------------------
This directory contains the top-level code for the JIT compiler.  This code
basically boils down to a call to TargetMachine::addPassesToJITCompile, and
handles the compile-dispatch-recompile cycle.

test/Regression/CodeGen/X86
---------------------------
This directory contains regression tests for the X86 code generator.


==================================================
V. Strange Things, or, Things That Should Be Known
==================================================

Representing memory in MachineInstrs
------------------------------------

The x86 has a very, uhm, flexible, way of accessing memory.  It is capable of
addressing memory addresses of the following form directly in integer
instructions (which use ModR/M addressing):

   Base+[1,2,4,8]*IndexReg+Disp32

Wow, that's crazy.  In order to represent this, LLVM tracks no less that 4
operands for each memory operand of this form.  This means that the "load" form
of 'mov' has the following "Operands" in this order:

Index:        0     |    1        2       3           4
Meaning:   DestReg, | BaseReg,  Scale, IndexReg, Displacement
OperandTy: VirtReg, | VirtReg, UnsImm, VirtReg,   SignExtImm

Stores and all other instructions treat the four memory operands in the same
way, in the same order.


======================
VI. Instruction naming
======================

An instruction name consists of the base name, a default operand size
followed by a character per operand with an optional special size. For
example:

ADD8rr -> add, 8-bit register, 8-bit register

IMUL16rmi -> imul, 16-bit register, 16-bit memory, 16-bit immediate

IMUL16rmi8 -> imul, 16-bit register, 16-bit memory, 8-bit immediate

MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory


==========================
VII. TODO / Future Projects
==========================

Ideas for Improvements:
-----------------------
1. Implement an *optimal* linear time instruction selector
2. Implement lots of nifty runtime optimizations
3. Implement new targets: IA64? X86-64? M68k? MMIX?  Who knows...

Infrastructure Improvements:
----------------------------

1. X86/Printer.cpp and Sparc/EmitAssembly.cpp both have copies of what is
   roughly the same code, used to output constants in a form the assembler
   can understand. These functions should be shared at some point. They
   should be rewritten to pass around iostreams instead of strings. The
   list of functions is as follows:

   isStringCompatible
   toOctal
   ConstantExprToString
   valToExprString
   getAsCString
   printSingleConstantValue (with TypeToDataDirective inlined)
   printConstantValueOnly