191b5ca838ac74ba7756a49b569684f1889cae8afMisha Brukman//===-- X86FloatingPoint.cpp - Floating point Reg -> Stack converter ------===//
20e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
70e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
9a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//
10a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// This file defines the pass which converts floating point instructions from
11e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// pseudo registers into register stack instructions.  This pass uses live
12847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner// variable information to indicate where the FPn registers are used and their
13847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner// lifetimes.
14847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner//
15e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// The x87 hardware tracks liveness of the stack registers, so it is necessary
16e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// to implement exact liveness tracking between basic blocks. The CFG edges are
17e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// partitioned into bundles where the same FP registers must be live in
18e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// identical stack positions. Instructions are inserted at the end of each basic
19e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// block to rearrange the live registers to match the outgoing bundle.
20847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner//
21e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// This approach avoids splitting critical edges at the potential cost of more
22e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen// live register shuffling instructions when critical edges are present.
23a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//
24a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
25a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
26a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#include "X86.h"
27a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#include "X86InstrInfo.h"
280ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/ADT/DepthFirstIterator.h"
29d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
300ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/ADT/SmallPtrSet.h"
310ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/ADT/SmallVector.h"
320ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/ADT/Statistic.h"
338dd070edc2209ecfdae49780ec1596b349e2cbd1Jakob Stoklund Olesen#include "llvm/CodeGen/EdgeBundles.h"
34a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#include "llvm/CodeGen/MachineFunctionPass.h"
35a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#include "llvm/CodeGen/MachineInstrBuilder.h"
3684bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h"
37359b65f782cc323daba4f8c5c21c70a98c9d40eaAlkis Evlogimenos#include "llvm/CodeGen/Passes.h"
380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h"
39551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h"
40c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
410ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/Support/raw_ostream.h"
420ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/Target/TargetInstrInfo.h"
430ea8bf3590d7553179f95e4b0fc47c02f066fcfbBill Wendling#include "llvm/Target/TargetMachine.h"
44a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#include <algorithm>
45f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris Lattnerusing namespace llvm;
46d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "x86-codegen"
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4995b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(NumFXCH, "Number of fxch instructions inserted");
5095b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(NumFP  , "Number of floating point instructions");
51a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
5295b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
536726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  struct FPS : public MachineFunctionPass {
541997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel    static char ID;
5590c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson    FPS() : MachineFunctionPass(ID) {
568dd070edc2209ecfdae49780ec1596b349e2cbd1Jakob Stoklund Olesen      initializeEdgeBundlesPass(*PassRegistry::getPassRegistry());
57b47bb13331fe39aa7827f52397bbe366a158a128Jakob Stoklund Olesen      // This is really only to keep valgrind quiet.
58b47bb13331fe39aa7827f52397bbe366a158a128Jakob Stoklund Olesen      // The logic in isLive() is too much for it.
59b47bb13331fe39aa7827f52397bbe366a158a128Jakob Stoklund Olesen      memset(Stack, 0, sizeof(Stack));
60b47bb13331fe39aa7827f52397bbe366a158a128Jakob Stoklund Olesen      memset(RegMap, 0, sizeof(RegMap));
61b47bb13331fe39aa7827f52397bbe366a158a128Jakob Stoklund Olesen    }
62794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void getAnalysisUsage(AnalysisUsage &AU) const override {
64df09055cdb124a0d53258ad09d3a1d62bdb7dd19Dan Gohman      AU.setPreservesCFG();
658dd070edc2209ecfdae49780ec1596b349e2cbd1Jakob Stoklund Olesen      AU.addRequired<EdgeBundles>();
668b56a90bec639665fc024896d2fc2bdd095c76a3Evan Cheng      AU.addPreservedID(MachineLoopInfoID);
678b56a90bec639665fc024896d2fc2bdd095c76a3Evan Cheng      AU.addPreservedID(MachineDominatorsID);
68bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng      MachineFunctionPass::getAnalysisUsage(AU);
69bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng    }
70bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool runOnMachineFunction(MachineFunction &MF) override;
72a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *getPassName() const override { return "X86 FP Stackifier"; }
74a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
75a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  private:
7632644ac67ce25a06c8c6658746911479d56a894fEvan Cheng    const TargetInstrInfo *TII; // Machine instruction info.
77e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
78e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Two CFG edges are related if they leave the same block, or enter the same
79e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // block. The transitive closure of an edge under this relation is a
80e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // LiveBundle. It represents a set of CFG edges where the live FP stack
81e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // registers must be allocated identically in the x87 stack.
82e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    //
83e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // A LiveBundle is usually all the edges leaving a block, or all the edges
84e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // entering a block, but it can contain more edges if critical edges are
85e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // present.
86e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    //
87e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // The set of live FP registers in a LiveBundle is calculated by bundleCFG,
88e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // but the exact mapping of FP registers to stack slots is fixed later.
89e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    struct LiveBundle {
90e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // Bit mask of live FP registers. Bit 0 = FP0, bit 1 = FP1, &c.
91e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      unsigned Mask;
92e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
93e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // Number of pre-assigned live registers in FixStack. This is 0 when the
94e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // stack order has not yet been fixed.
95e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      unsigned FixCount;
96e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
97e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // Assigned stack order for live-in registers.
98e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // FixStack[i] == getStackEntry(i) for all i < FixCount.
99e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      unsigned char FixStack[8];
100e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
101631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen      LiveBundle() : Mask(0), FixCount(0) {}
102e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
103e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // Have the live registers been assigned a stack order yet?
104e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      bool isFixed() const { return !Mask || FixCount; }
105e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    };
106e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
107e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Numbered LiveBundle structs. LiveBundles[0] is used for all CFG edges
108e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // with no live FP registers.
109e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    SmallVector<LiveBundle, 8> LiveBundles;
110e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
111631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen    // The edge bundle analysis provides indices into the LiveBundles vector.
112631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen    EdgeBundles *Bundles;
113e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
114e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Return a bitmask of FP registers in block's live-in list.
115e845cedf4d1ee97b0e2a14ee68d3863bdd6429dcJakub Staszak    static unsigned calcLiveInMask(MachineBasicBlock *MBB) {
116e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      unsigned Mask = 0;
117e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(),
118e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen           E = MBB->livein_end(); I != E; ++I) {
119a5545bc2b9b1295f8443f6350487ec9b775b2d73Chad Rosier        unsigned Reg = *I;
120a5545bc2b9b1295f8443f6350487ec9b775b2d73Chad Rosier        if (Reg < X86::FP0 || Reg > X86::FP6)
121a5545bc2b9b1295f8443f6350487ec9b775b2d73Chad Rosier          continue;
122a5545bc2b9b1295f8443f6350487ec9b775b2d73Chad Rosier        Mask |= 1 << (Reg - X86::FP0);
123e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      }
124e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      return Mask;
125e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    }
126e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
127e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Partition all the CFG edges into LiveBundles.
128e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    void bundleCFG(MachineFunction &MF);
129e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
13032644ac67ce25a06c8c6658746911479d56a894fEvan Cheng    MachineBasicBlock *MBB;     // Current basic block
1311baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen
1321baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // The hardware keeps track of how many FP registers are live, so we have
1331baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // to model that exactly. Usually, each live register corresponds to an
1341baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // FP<n> register, but when dealing with calls, returns, and inline
135d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    // assembly, it is sometimes necessary to have live scratch registers.
13632644ac67ce25a06c8c6658746911479d56a894fEvan Cheng    unsigned Stack[8];          // FP<n> Registers in each stack slot...
13732644ac67ce25a06c8c6658746911479d56a894fEvan Cheng    unsigned StackTop;          // The current top of the FP stack.
138a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1399bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    enum {
1409bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      NumFPRegs = 16            // Including scratch pseudo-registers.
1419bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    };
1429bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
1431baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // For each live FP<n> register, point to its Stack[] entry.
1441baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // The first entries correspond to FP0-FP6, the rest are scratch registers
1451baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // used when we need slightly different live registers than what the
1461baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    // register allocator thinks.
1479bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned RegMap[NumFPRegs];
1489bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
1499bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Pending fixed registers - Inline assembly needs FP registers to appear
1509bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // in fixed stack slot positions. This is handled by copying FP registers
1519bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // to ST registers before the instruction, and copying back after the
1529bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // instruction.
1539bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
1549bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // This is modeled with pending ST registers. NumPendingSTs is the number
1559bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // of ST registers (ST0-STn) we are tracking. PendingST[n] points to an FP
1569bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // register that holds the ST value. The ST registers are not moved into
1579bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // place until immediately before the instruction that needs them.
1589bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
1599bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // It can happen that we need an ST register to be live when no FP register
1609bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // holds the value:
1619bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
1629bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //   %ST0 = COPY %FP4<kill>
1639bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
1649bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // When that happens, we allocate a scratch FP register to hold the ST
1659bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // value. That means every register in PendingST must be live.
1669bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
1679bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned NumPendingSTs;
1689bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned char PendingST[8];
1691baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen
170e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Set up our stack model to match the incoming registers to MBB.
171e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    void setupBlockStack();
172e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
173e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Shuffle live registers to match the expectations of successor blocks.
174e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    void finishBlockStack();
175e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
176b720be6a50f4e1b3280d2b029ee38dda14577525Manman Ren#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
177a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void dumpStack() const {
178f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene      dbgs() << "Stack contents:";
179a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      for (unsigned i = 0; i != StackTop; ++i) {
180f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene        dbgs() << " FP" << Stack[i];
1810e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman        assert(RegMap[Stack[i]] == i && "Stack[] doesn't match RegMap[]!");
182a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      }
1839bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      for (unsigned i = 0; i != NumPendingSTs; ++i)
1849bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        dbgs() << ", ST" << i << " in FP" << unsigned(PendingST[i]);
185f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene      dbgs() << "\n";
186a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
18777e300e8f0b8db8eec448cae9c87d7c5bfad9757Manman Ren#endif
188e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
189a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// getSlot - Return the stack slot number a particular register number is
190a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// in.
191a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    unsigned getSlot(unsigned RegNo) const {
1929bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(RegNo < NumFPRegs && "Regno out of range!");
193a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      return RegMap[RegNo];
194a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
195a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
196a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// isLive - Is RegNo currently live in the stack?
197e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    bool isLive(unsigned RegNo) const {
198e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      unsigned Slot = getSlot(RegNo);
199e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      return Slot < StackTop && Stack[Slot] == RegNo;
200e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    }
201e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
202a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// getScratchReg - Return an FP register that is not currently in use.
2038c67c03b0cd4bf2421d21e588d131bb0d2023695Jakub Staszak    unsigned getScratchReg() const {
2049bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      for (int i = NumFPRegs - 1; i >= 8; --i)
205e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen        if (!isLive(i))
206e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen          return i;
207e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen      llvm_unreachable("Ran out of scratch FP registers");
208e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen    }
209e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen
2109bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    /// isScratchReg - Returns trus if RegNo is a scratch FP register.
2116f05f21857615fb18c2ce7b14820bcd3b70db1f1Jakub Staszak    static bool isScratchReg(unsigned RegNo) {
2129bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      return RegNo > 8 && RegNo < NumFPRegs;
2139bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
2149bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
215a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// getStackEntry - Return the X86::FP<n> register in register ST(i).
216a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    unsigned getStackEntry(unsigned STi) const {
2173f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng      if (STi >= StackTop)
2183f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng        report_fatal_error("Access past stack top!");
219a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      return Stack[StackTop-1-STi];
220a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
221a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
222a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// getSTReg - Return the X86::ST(i) register which contains the specified
223a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// FP<RegNo> register.
224a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    unsigned getSTReg(unsigned RegNo) const {
225c89c744b69cecac576317a98322fd295e36e9886Craig Topper      return StackTop - 1 - getSlot(RegNo) + X86::ST0;
226a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
227a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
228447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // pushReg - Push the specified FP<n> register onto the stack.
229a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void pushReg(unsigned Reg) {
2309bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(Reg < NumFPRegs && "Register number out of range!");
2313f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng      if (StackTop >= 8)
2323f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng        report_fatal_error("Stack overflow!");
233a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      Stack[StackTop] = Reg;
234a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      RegMap[Reg] = StackTop++;
235a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
236a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
237a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    bool isAtTop(unsigned RegNo) const { return getSlot(RegNo) == StackTop-1; }
238447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    void moveToTop(unsigned RegNo, MachineBasicBlock::iterator I) {
239e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      DebugLoc dl = I == MBB->end() ? DebugLoc() : I->getDebugLoc();
240447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      if (isAtTop(RegNo)) return;
241e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
242447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      unsigned STReg = getSTReg(RegNo);
243447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      unsigned RegOnTop = getStackEntry(0);
244a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
245447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Swap the slots the regs are in.
246447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      std::swap(RegMap[RegNo], RegMap[RegOnTop]);
247a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
248447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Swap stack slot contents.
2493f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng      if (RegMap[RegOnTop] >= StackTop)
2503f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng        report_fatal_error("Access past stack top!");
251447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      std::swap(Stack[RegMap[RegOnTop]], Stack[StackTop-1]);
252a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
253447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Emit an fxch to update the runtime processors version of the state.
2548d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen      BuildMI(*MBB, I, dl, TII->get(X86::XCH_F)).addReg(STReg);
255fe60104ac97f3a8736dcfbfdf9547c7b7cc7b951Dan Gohman      ++NumFXCH;
256a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
257a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
2580526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner    void duplicateToTop(unsigned RegNo, unsigned AsReg, MachineInstr *I) {
259e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      DebugLoc dl = I == MBB->end() ? DebugLoc() : I->getDebugLoc();
260a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      unsigned STReg = getSTReg(RegNo);
261a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      pushReg(AsReg);   // New register on top of stack
262a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
2638d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen      BuildMI(*MBB, I, dl, TII->get(X86::LD_Frr)).addReg(STReg);
264a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
265a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
26666b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    /// duplicatePendingSTBeforeKill - The instruction at I is about to kill
26766b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    /// RegNo. If any PendingST registers still need the RegNo value, duplicate
26866b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    /// them to new scratch registers.
26966b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    void duplicatePendingSTBeforeKill(unsigned RegNo, MachineInstr *I) {
27066b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen      for (unsigned i = 0; i != NumPendingSTs; ++i) {
27166b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen        if (PendingST[i] != RegNo)
27266b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen          continue;
27366b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen        unsigned SR = getScratchReg();
27466b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen        DEBUG(dbgs() << "Duplicating pending ST" << i
27566b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen                     << " in FP" << RegNo << " to FP" << SR << '\n');
27666b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen        duplicateToTop(RegNo, SR, I);
27766b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen        PendingST[i] = SR;
27866b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen      }
27966b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    }
28066b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen
281a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// popStackAfter - Pop the current value off of the top of the FP stack
282a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// after the specified instruction.
283a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void popStackAfter(MachineBasicBlock::iterator &I);
284a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
285a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// freeStackSlotAfter - Free the specified register from the register
286a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// stack, so that it is no longer in a register.  If the register is
287a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// currently at the top of the stack, we just pop the current instruction,
288a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// otherwise we store the current top-of-stack into the specified slot,
289a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// then pop the top of stack.
2900526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner    void freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned Reg);
2910526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner
292a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// freeStackSlotBefore - Just the pop, no folding. Return the inserted
293a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// instruction.
294e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    MachineBasicBlock::iterator
295e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    freeStackSlotBefore(MachineBasicBlock::iterator I, unsigned FPRegNo);
296e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
297a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// Adjust the live registers to be the set in Mask.
298e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    void adjustLiveRegs(unsigned Mask, MachineBasicBlock::iterator I);
299e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
3001baeb006d2bb74dd9f6fa633fcc53e3b1ecbbf35Jakob Stoklund Olesen    /// Shuffle the top FixCount stack entries such that FP reg FixStack[0] is
301a40ce7e394283d78bdda3d7ea728ba2ffae0ef39Chris Lattner    /// st(0), FP reg FixStack[1] is st(1) etc.
302e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    void shuffleStackTop(const unsigned char *FixStack, unsigned FixCount,
303e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen                         MachineBasicBlock::iterator I);
304e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
305a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
306a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
307a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void handleZeroArgFP(MachineBasicBlock::iterator &I);
308a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void handleOneArgFP(MachineBasicBlock::iterator &I);
3094a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    void handleOneArgFPRW(MachineBasicBlock::iterator &I);
310a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void handleTwoArgFP(MachineBasicBlock::iterator &I);
311d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner    void handleCompareFP(MachineBasicBlock::iterator &I);
312c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner    void handleCondMovFP(MachineBasicBlock::iterator &I);
313a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    void handleSpecialFP(MachineBasicBlock::iterator &I);
3147db1e7a527bc74e605da6ea86eb67945d8f17b07Jakob Stoklund Olesen
3159bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Check if a COPY instruction is using FP registers.
3166f05f21857615fb18c2ce7b14820bcd3b70db1f1Jakub Staszak    static bool isFPCopy(MachineInstr *MI) {
3179bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned DstReg = MI->getOperand(0).getReg();
3189bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned SrcReg = MI->getOperand(1).getReg();
3199bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
3209bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      return X86::RFP80RegClass.contains(DstReg) ||
3219bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        X86::RFP80RegClass.contains(SrcReg);
3229bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
323a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  };
3241997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel  char FPS::ID = 0;
325a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
326a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
327f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris LattnerFunctionPass *llvm::createX86FloatingPointStackifierPass() { return new FPS(); }
328a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
3293cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner/// getFPReg - Return the X86::FPx register number for the specified operand.
3303cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner/// For example, this returns 3 for X86::FP3.
3313cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattnerstatic unsigned getFPReg(const MachineOperand &MO) {
332d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isReg() && "Expected an FP register!");
3333cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner  unsigned Reg = MO.getReg();
3343cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner  assert(Reg >= X86::FP0 && Reg <= X86::FP6 && "Expected FP register!");
3353cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner  return Reg - X86::FP0;
3363cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner}
3373cc838433aa9dfe7106c2eef2b2eceb2d3548663Chris Lattner
338a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// runOnMachineFunction - Loop over all of the basic blocks, transforming FP
339a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// register references into FP stack references.
340a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///
341a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerbool FPS::runOnMachineFunction(MachineFunction &MF) {
34242e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  // We only need to run this pass if there are any FP registers used in this
34342e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  // function.  If it is all integer, there is nothing for us to do!
34442e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  bool FPIsUsed = false;
34542e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner
34642e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  assert(X86::FP6 == X86::FP0+6 && "Register enums aren't sorted right!");
34742e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  for (unsigned i = 0; i <= 6; ++i)
34884bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner    if (MF.getRegInfo().isPhysRegUsed(X86::FP0+i)) {
34942e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner      FPIsUsed = true;
35042e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner      break;
35142e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner    }
35242e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner
35342e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  // Early exit.
35442e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner  if (!FPIsUsed) return false;
35542e25b387f9bbae463ddd739c16e4fdc81abb371Chris Lattner
356631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  Bundles = &getAnalysis<EdgeBundles>();
35732644ac67ce25a06c8c6658746911479d56a894fEvan Cheng  TII = MF.getTarget().getInstrInfo();
358e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
359e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Prepare cross-MBB liveness.
360e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  bundleCFG(MF);
361e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
362a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  StackTop = 0;
363a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
364847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner  // Process the function in depth first order so that we process at least one
365847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner  // of the predecessors for every reachable block in the function.
366eaa009d963f0715257a26c6bf32ce6dd14326415Owen Anderson  SmallPtrSet<MachineBasicBlock*, 8> Processed;
3672268684f6fef2ef7e5b523d21dbd376f09ec1174Chris Lattner  MachineBasicBlock *Entry = MF.begin();
368847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner
369847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner  bool Changed = false;
370eaa009d963f0715257a26c6bf32ce6dd14326415Owen Anderson  for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*, 8> >
371847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner         I = df_ext_begin(Entry, Processed), E = df_ext_end(Entry, Processed);
372847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner       I != E; ++I)
3732268684f6fef2ef7e5b523d21dbd376f09ec1174Chris Lattner    Changed |= processBasicBlock(MF, **I);
374847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner
375ba3598cb1facb2b5aaa8ec47faf2cd07689a3b86Chris Lattner  // Process any unreachable blocks in arbitrary order now.
376e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (MF.size() != Processed.size())
377e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
378e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      if (Processed.insert(BB))
379e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen        Changed |= processBasicBlock(MF, *BB);
380e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
381e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  LiveBundles.clear();
382ba3598cb1facb2b5aaa8ec47faf2cd07689a3b86Chris Lattner
383a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  return Changed;
384a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
385a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
386e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// bundleCFG - Scan all the basic blocks to determine consistent live-in and
387e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// live-out sets for the FP registers. Consistent means that the set of
388e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// registers live-out from a block is identical to the live-in set of all
389e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// successors. This is not enforced by the normal live-in lists since
390e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// registers may be implicitly defined, or not used by all successors.
391e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesenvoid FPS::bundleCFG(MachineFunction &MF) {
392e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  assert(LiveBundles.empty() && "Stale data in LiveBundles");
393631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  LiveBundles.resize(Bundles->getNumBundles());
394e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
395631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  // Gather the actual live-in masks for all MBBs.
396e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
397e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    MachineBasicBlock *MBB = I;
398e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    const unsigned Mask = calcLiveInMask(MBB);
399e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    if (!Mask)
400e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      continue;
401631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen    // Update MBB ingoing bundle mask.
402631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen    LiveBundles[Bundles->getBundle(MBB->getNumber(), false)].Mask |= Mask;
403e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
404e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen}
405e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
406a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// processBasicBlock - Loop over all of the instructions in the basic block,
407a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// transforming FP instructions into their stack form.
408a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///
409a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerbool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
410a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  bool Changed = false;
411a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  MBB = &BB;
4129bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen  NumPendingSTs = 0;
4130e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman
414e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  setupBlockStack();
415e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
416a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  for (MachineBasicBlock::iterator I = BB.begin(); I != BB.end(); ++I) {
417c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos    MachineInstr *MI = I;
41899405df044f2c584242e711cc9023ec90356da82Bruno Cardoso Lopes    uint64_t Flags = MI->getDesc().TSFlags;
419e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
420e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    unsigned FPInstClass = Flags & X86II::FPTypeMask;
421518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner    if (MI->isInlineAsm())
422e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      FPInstClass = X86II::SpecialFP;
4237db1e7a527bc74e605da6ea86eb67945d8f17b07Jakob Stoklund Olesen
4249bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (MI->isCopy() && isFPCopy(MI))
4257db1e7a527bc74e605da6ea86eb67945d8f17b07Jakob Stoklund Olesen      FPInstClass = X86II::SpecialFP;
4267db1e7a527bc74e605da6ea86eb67945d8f17b07Jakob Stoklund Olesen
42756e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    if (MI->isImplicitDef() &&
42856e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen        X86::RFP80RegClass.contains(MI->getOperand(0).getReg()))
42956e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen      FPInstClass = X86II::SpecialFP;
43056e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen
431e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    if (FPInstClass == X86II::NotFP)
432847df25e7d8876c8a93ff4e4cc72c8f73ed50dbbChris Lattner      continue;  // Efficiently ignore non-fp insts!
433a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineInstr *PrevMI = nullptr;
435f81af21caf9c0f62c60b72762d9a927e8c24f679Alkis Evlogimenos    if (I != BB.begin())
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      PrevMI = std::prev(I);
437a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
438a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    ++NumFP;  // Keep track of # of pseudo instrs
439f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene    DEBUG(dbgs() << "\nFPInst:\t" << *MI);
440a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
441a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // Get dead variables list now because the MI pointer may be deleted as part
442a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // of processing!
443ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng    SmallVector<unsigned, 8> DeadRegs;
444ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
445ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng      const MachineOperand &MO = MI->getOperand(i);
446d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      if (MO.isReg() && MO.isDead())
447ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng        DeadRegs.push_back(MO.getReg());
448ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng    }
449a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
450e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    switch (FPInstClass) {
4514a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    case X86II::ZeroArgFP:  handleZeroArgFP(I); break;
452c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner    case X86II::OneArgFP:   handleOneArgFP(I);  break;  // fstp ST(0)
4534a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    case X86II::OneArgFPRW: handleOneArgFPRW(I); break; // ST(0) = fsqrt(ST(0))
4545cd3e9f4b7caa5a79c6c05633b11144d0ae41771Evan Cheng    case X86II::TwoArgFP:   handleTwoArgFP(I);  break;
455ab8deccb82460527562d1c36a787537e4edaa9ddChris Lattner    case X86II::CompareFP:  handleCompareFP(I); break;
456c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner    case X86II::CondMovFP:  handleCondMovFP(I); break;
4574a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    case X86II::SpecialFP:  handleSpecialFP(I); break;
458c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown FP Type!");
459a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
460a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
461a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // Check to see if any of the values defined by this instruction are dead
462a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // after definition.  If so, pop them.
463ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng    for (unsigned i = 0, e = DeadRegs.size(); i != e; ++i) {
464ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng      unsigned Reg = DeadRegs[i];
465a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      if (Reg >= X86::FP0 && Reg <= X86::FP6) {
466f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene        DEBUG(dbgs() << "Register FP#" << Reg-X86::FP0 << " is dead!\n");
467d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner        freeStackSlotAfter(I, Reg-X86::FP0);
468a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      }
469a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
4700e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman
471a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // Print out all of the instructions expanded to if -debug
472b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos    DEBUG(
473b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos      MachineBasicBlock::iterator PrevI(PrevMI);
474b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos      if (I == PrevI) {
475f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene        dbgs() << "Just deleted pseudo instruction\n";
476b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos      } else {
477b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos        MachineBasicBlock::iterator Start = I;
478b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos        // Rewind to first instruction newly inserted.
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        while (Start != BB.begin() && std::prev(Start) != PrevI) --Start;
480f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene        dbgs() << "Inserted instructions:\n\t";
481f5c95a6ee2525e8043d19502dab85a9d34598e4eDavid Greene        Start->print(dbgs(), &MF.getTarget());
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        while (++Start != std::next(I)) {}
483b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos      }
484b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos      dumpStack();
485b929bca0279869b2b9649463318a68988302c0ceAlkis Evlogimenos    );
4861f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands    (void)PrevMI;
487a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
488a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    Changed = true;
489a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
490a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
491e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  finishBlockStack();
492e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
493a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  return Changed;
494a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
495a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
496631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen/// setupBlockStack - Use the live bundles to set up our model of the stack
497e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// to match predecessors' live out stack.
498e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesenvoid FPS::setupBlockStack() {
499e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  DEBUG(dbgs() << "\nSetting up live-ins for BB#" << MBB->getNumber()
500e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen               << " derived from " << MBB->getName() << ".\n");
501e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  StackTop = 0;
502631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  // Get the live-in bundle for MBB.
503631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  const LiveBundle &Bundle =
504631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen    LiveBundles[Bundles->getBundle(MBB->getNumber(), false)];
505e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
506e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (!Bundle.Mask) {
507e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Block has no FP live-ins.\n");
508e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    return;
509e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
510e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
511e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Depth-first iteration should ensure that we always have an assigned stack.
512e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  assert(Bundle.isFixed() && "Reached block before any predecessors");
513e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
514e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Push the fixed live-in registers.
515e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  for (unsigned i = Bundle.FixCount; i > 0; --i) {
516e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    MBB->addLiveIn(X86::ST0+i-1);
517e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Live-in st(" << (i-1) << "): %FP"
518e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen                 << unsigned(Bundle.FixStack[i-1]) << '\n');
519e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    pushReg(Bundle.FixStack[i-1]);
520e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
521e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
522e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Kill off unwanted live-ins. This can happen with a critical edge.
523e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // FIXME: We could keep these live registers around as zombies. They may need
524e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // to be revived at the end of a short block. It might save a few instrs.
525e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  adjustLiveRegs(calcLiveInMask(MBB), MBB->begin());
526e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  DEBUG(MBB->dump());
527e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen}
528e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
529e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// finishBlockStack - Revive live-outs that are implicitly defined out of
530e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// MBB. Shuffle live registers to match the expected fixed stack of any
531e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// predecessors, and ensure that all predecessors are expecting the same
532e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// stack.
533e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesenvoid FPS::finishBlockStack() {
534e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // The RET handling below takes care of return blocks for us.
535e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (MBB->succ_empty())
536e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    return;
537e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
538e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  DEBUG(dbgs() << "Setting up live-outs for BB#" << MBB->getNumber()
539e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen               << " derived from " << MBB->getName() << ".\n");
540e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
541631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  // Get MBB's live-out bundle.
542631ee4b89f494a3056c62f84e434e1ecf266bb8aJakob Stoklund Olesen  unsigned BundleIdx = Bundles->getBundle(MBB->getNumber(), true);
543e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  LiveBundle &Bundle = LiveBundles[BundleIdx];
544e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
545e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // We may need to kill and define some registers to match successors.
546e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // FIXME: This can probably be combined with the shuffle below.
547e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  MachineBasicBlock::iterator Term = MBB->getFirstTerminator();
548e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  adjustLiveRegs(Bundle.Mask, Term);
549e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
550e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (!Bundle.Mask) {
551e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "No live-outs.\n");
552e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    return;
553e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
554e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
555e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Has the stack order been fixed yet?
556e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  DEBUG(dbgs() << "LB#" << BundleIdx << ": ");
557e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (Bundle.isFixed()) {
558e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Shuffling stack to match.\n");
559e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    shuffleStackTop(Bundle.FixStack, Bundle.FixCount, Term);
560e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  } else {
561e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Not fixed yet, we get to choose.
562e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Fixing stack order now.\n");
563e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    Bundle.FixCount = StackTop;
564e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    for (unsigned i = 0; i < StackTop; ++i)
565e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      Bundle.FixStack[i] = getStackEntry(i);
566e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
567e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen}
568e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
569e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
570a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
571a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// Efficient Lookup Table Support
572a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
573a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
574f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris Lattnernamespace {
575f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris Lattner  struct TableEntry {
57672051bf629087bb7d7e68aa4d553be8137098056Craig Topper    uint16_t from;
57772051bf629087bb7d7e68aa4d553be8137098056Craig Topper    uint16_t to;
578f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris Lattner    bool operator<(const TableEntry &TE) const { return from < TE.from; }
5799471c8a93b117d8ac01c4ef1cb9faa583e03dec0Jeff Cohen    friend bool operator<(const TableEntry &TE, unsigned V) {
5809471c8a93b117d8ac01c4ef1cb9faa583e03dec0Jeff Cohen      return TE.from < V;
5819471c8a93b117d8ac01c4ef1cb9faa583e03dec0Jeff Cohen    }
5822e34b99e59dadea9145af594e4108feeb79c4349Benjamin Kramer    friend bool LLVM_ATTRIBUTE_UNUSED operator<(unsigned V,
5832e34b99e59dadea9145af594e4108feeb79c4349Benjamin Kramer                                                const TableEntry &TE) {
584de78f05cf77a583668d74651f1b3df6154b20199Jakob Stoklund Olesen      return V < TE.from;
585de78f05cf77a583668d74651f1b3df6154b20199Jakob Stoklund Olesen    }
586f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris Lattner  };
587f2e49d4c1a8839f30e8ca9617139d63db173fa80Chris Lattner}
588a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
589a022bdfd99bc092dac9cefb4c2be9de787ea8e0fEvan Cheng#ifndef NDEBUG
590a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic bool TableIsSorted(const TableEntry *Table, unsigned NumEntries) {
591a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  for (unsigned i = 0; i != NumEntries-1; ++i)
592a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    if (!(Table[i] < Table[i+1])) return false;
593a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  return true;
594a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
595a022bdfd99bc092dac9cefb4c2be9de787ea8e0fEvan Cheng#endif
596a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
597a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic int Lookup(const TableEntry *Table, unsigned N, unsigned Opcode) {
598a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  const TableEntry *I = std::lower_bound(Table, Table+N, Opcode);
599a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  if (I != Table+N && I->from == Opcode)
600a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    return I->to;
601a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  return -1;
602a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
603a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
604a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#ifdef NDEBUG
605a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#define ASSERT_SORTED(TABLE)
606a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#else
607a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#define ASSERT_SORTED(TABLE)                                              \
608a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  { static bool TABLE##Checked = false;                                   \
609c06fe8a5ac41ff407af25395f58d15c650f5b266Jim Laskey    if (!TABLE##Checked) {                                                \
610718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson       assert(TableIsSorted(TABLE, array_lengthof(TABLE)) &&              \
611a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner              "All lookup tables must be sorted for efficient access!");  \
612c06fe8a5ac41ff407af25395f58d15c650f5b266Jim Laskey       TABLE##Checked = true;                                             \
613c06fe8a5ac41ff407af25395f58d15c650f5b266Jim Laskey    }                                                                     \
614a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
615a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner#endif
616a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
61758fe459e36605342410e8c11d12ee1901428b14bChris Lattner//===----------------------------------------------------------------------===//
61858fe459e36605342410e8c11d12ee1901428b14bChris Lattner// Register File -> Register Stack Mapping Methods
61958fe459e36605342410e8c11d12ee1901428b14bChris Lattner//===----------------------------------------------------------------------===//
62058fe459e36605342410e8c11d12ee1901428b14bChris Lattner
62158fe459e36605342410e8c11d12ee1901428b14bChris Lattner// OpcodeTable - Sorted map of register instructions to their stack version.
62258fe459e36605342410e8c11d12ee1901428b14bChris Lattner// The first element is an register file pseudo instruction, the second is the
62358fe459e36605342410e8c11d12ee1901428b14bChris Lattner// concrete X86 instruction which uses the register stack.
62458fe459e36605342410e8c11d12ee1901428b14bChris Lattner//
62558fe459e36605342410e8c11d12ee1901428b14bChris Lattnerstatic const TableEntry OpcodeTable[] = {
626e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ABS_Fp32     , X86::ABS_F     },
627e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ABS_Fp64     , X86::ABS_F     },
62859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ABS_Fp80     , X86::ABS_F     },
629afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::ADD_Fp32m    , X86::ADD_F32m  },
630afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::ADD_Fp64m    , X86::ADD_F64m  },
631afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::ADD_Fp64m32  , X86::ADD_F32m  },
63259a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ADD_Fp80m32  , X86::ADD_F32m  },
63359a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ADD_Fp80m64  , X86::ADD_F64m  },
634e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_FpI16m32 , X86::ADD_FI16m },
635e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_FpI16m64 , X86::ADD_FI16m },
63659a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ADD_FpI16m80 , X86::ADD_FI16m },
637e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_FpI32m32 , X86::ADD_FI32m },
638e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_FpI32m64 , X86::ADD_FI32m },
63959a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ADD_FpI32m80 , X86::ADD_FI32m },
640e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CHS_Fp32     , X86::CHS_F     },
641e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CHS_Fp64     , X86::CHS_F     },
64259a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CHS_Fp80     , X86::CHS_F     },
643e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVBE_Fp32  , X86::CMOVBE_F  },
644e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVBE_Fp64  , X86::CMOVBE_F  },
64559a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVBE_Fp80  , X86::CMOVBE_F  },
646e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVB_Fp32   , X86::CMOVB_F   },
647e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVB_Fp64   , X86::CMOVB_F  },
64859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVB_Fp80   , X86::CMOVB_F  },
649e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVE_Fp32   , X86::CMOVE_F  },
650e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVE_Fp64   , X86::CMOVE_F   },
65159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVE_Fp80   , X86::CMOVE_F   },
652e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNBE_Fp32 , X86::CMOVNBE_F },
653e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNBE_Fp64 , X86::CMOVNBE_F },
65459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVNBE_Fp80 , X86::CMOVNBE_F },
655e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNB_Fp32  , X86::CMOVNB_F  },
656e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNB_Fp64  , X86::CMOVNB_F  },
65759a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVNB_Fp80  , X86::CMOVNB_F  },
658e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNE_Fp32  , X86::CMOVNE_F  },
659e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNE_Fp64  , X86::CMOVNE_F  },
66059a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVNE_Fp80  , X86::CMOVNE_F  },
661e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNP_Fp32  , X86::CMOVNP_F  },
662e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVNP_Fp64  , X86::CMOVNP_F  },
66359a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVNP_Fp80  , X86::CMOVNP_F  },
664e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVP_Fp32   , X86::CMOVP_F   },
665e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::CMOVP_Fp64   , X86::CMOVP_F   },
66659a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::CMOVP_Fp80   , X86::CMOVP_F   },
667e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::COS_Fp32     , X86::COS_F     },
668e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::COS_Fp64     , X86::COS_F     },
66959a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::COS_Fp80     , X86::COS_F     },
670e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_Fp32m   , X86::DIVR_F32m },
671e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_Fp64m   , X86::DIVR_F64m },
672afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::DIVR_Fp64m32 , X86::DIVR_F32m },
67359a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIVR_Fp80m32 , X86::DIVR_F32m },
67459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIVR_Fp80m64 , X86::DIVR_F64m },
675e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_FpI16m32, X86::DIVR_FI16m},
676e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_FpI16m64, X86::DIVR_FI16m},
67759a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIVR_FpI16m80, X86::DIVR_FI16m},
678e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_FpI32m32, X86::DIVR_FI32m},
679e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_FpI32m64, X86::DIVR_FI32m},
68059a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIVR_FpI32m80, X86::DIVR_FI32m},
681e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp32m    , X86::DIV_F32m  },
682e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp64m    , X86::DIV_F64m  },
683afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::DIV_Fp64m32  , X86::DIV_F32m  },
68459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIV_Fp80m32  , X86::DIV_F32m  },
68559a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIV_Fp80m64  , X86::DIV_F64m  },
686e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_FpI16m32 , X86::DIV_FI16m },
687e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_FpI16m64 , X86::DIV_FI16m },
68859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIV_FpI16m80 , X86::DIV_FI16m },
689e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_FpI32m32 , X86::DIV_FI32m },
690e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_FpI32m64 , X86::DIV_FI32m },
69159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::DIV_FpI32m80 , X86::DIV_FI32m },
692e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ILD_Fp16m32  , X86::ILD_F16m  },
693e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ILD_Fp16m64  , X86::ILD_F16m  },
69459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ILD_Fp16m80  , X86::ILD_F16m  },
695e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ILD_Fp32m32  , X86::ILD_F32m  },
696e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ILD_Fp32m64  , X86::ILD_F32m  },
69759a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ILD_Fp32m80  , X86::ILD_F32m  },
698e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ILD_Fp64m32  , X86::ILD_F64m  },
699e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ILD_Fp64m64  , X86::ILD_F64m  },
70059a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ILD_Fp64m80  , X86::ILD_F64m  },
701e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ISTT_Fp16m32 , X86::ISTT_FP16m},
702e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ISTT_Fp16m64 , X86::ISTT_FP16m},
703a996d52e3767fb560774dfd8bc911c927ed5ca9fDale Johannesen  { X86::ISTT_Fp16m80 , X86::ISTT_FP16m},
704e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ISTT_Fp32m32 , X86::ISTT_FP32m},
705e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ISTT_Fp32m64 , X86::ISTT_FP32m},
706a996d52e3767fb560774dfd8bc911c927ed5ca9fDale Johannesen  { X86::ISTT_Fp32m80 , X86::ISTT_FP32m},
707e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ISTT_Fp64m32 , X86::ISTT_FP64m},
708e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ISTT_Fp64m64 , X86::ISTT_FP64m},
709a996d52e3767fb560774dfd8bc911c927ed5ca9fDale Johannesen  { X86::ISTT_Fp64m80 , X86::ISTT_FP64m},
710e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_Fp16m32  , X86::IST_F16m  },
711e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_Fp16m64  , X86::IST_F16m  },
71259a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::IST_Fp16m80  , X86::IST_F16m  },
713e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_Fp32m32  , X86::IST_F32m  },
714e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_Fp32m64  , X86::IST_F32m  },
71559a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::IST_Fp32m80  , X86::IST_F32m  },
716e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_Fp64m32  , X86::IST_FP64m },
717e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_Fp64m64  , X86::IST_FP64m },
71859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::IST_Fp64m80  , X86::IST_FP64m },
719e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::LD_Fp032     , X86::LD_F0     },
720e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::LD_Fp064     , X86::LD_F0     },
72159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::LD_Fp080     , X86::LD_F0     },
722e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::LD_Fp132     , X86::LD_F1     },
723e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::LD_Fp164     , X86::LD_F1     },
72459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::LD_Fp180     , X86::LD_F1     },
725e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::LD_Fp32m     , X86::LD_F32m   },
726cdbe4d3ebe50bd3709b08ee59bb09ccf3a1fbd47Dale Johannesen  { X86::LD_Fp32m64   , X86::LD_F32m   },
727cdbe4d3ebe50bd3709b08ee59bb09ccf3a1fbd47Dale Johannesen  { X86::LD_Fp32m80   , X86::LD_F32m   },
728e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::LD_Fp64m     , X86::LD_F64m   },
729cdbe4d3ebe50bd3709b08ee59bb09ccf3a1fbd47Dale Johannesen  { X86::LD_Fp64m80   , X86::LD_F64m   },
73059a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::LD_Fp80m     , X86::LD_F80m   },
731e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp32m    , X86::MUL_F32m  },
732e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp64m    , X86::MUL_F64m  },
733afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::MUL_Fp64m32  , X86::MUL_F32m  },
73459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::MUL_Fp80m32  , X86::MUL_F32m  },
73559a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::MUL_Fp80m64  , X86::MUL_F64m  },
736e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_FpI16m32 , X86::MUL_FI16m },
737e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_FpI16m64 , X86::MUL_FI16m },
73859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::MUL_FpI16m80 , X86::MUL_FI16m },
739e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_FpI32m32 , X86::MUL_FI32m },
740e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_FpI32m64 , X86::MUL_FI32m },
74159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::MUL_FpI32m80 , X86::MUL_FI32m },
742e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SIN_Fp32     , X86::SIN_F     },
743e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SIN_Fp64     , X86::SIN_F     },
74459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SIN_Fp80     , X86::SIN_F     },
745e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SQRT_Fp32    , X86::SQRT_F    },
746e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SQRT_Fp64    , X86::SQRT_F    },
74759a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SQRT_Fp80    , X86::SQRT_F    },
748e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ST_Fp32m     , X86::ST_F32m   },
749e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ST_Fp64m     , X86::ST_F64m   },
750e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ST_Fp64m32   , X86::ST_F32m   },
75159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ST_Fp80m32   , X86::ST_F32m   },
75259a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ST_Fp80m64   , X86::ST_F64m   },
75359a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::ST_FpP80m    , X86::ST_FP80m  },
754e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_Fp32m   , X86::SUBR_F32m },
755e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_Fp64m   , X86::SUBR_F64m },
756afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::SUBR_Fp64m32 , X86::SUBR_F32m },
75759a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUBR_Fp80m32 , X86::SUBR_F32m },
75859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUBR_Fp80m64 , X86::SUBR_F64m },
759e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_FpI16m32, X86::SUBR_FI16m},
760e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_FpI16m64, X86::SUBR_FI16m},
76159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUBR_FpI16m80, X86::SUBR_FI16m},
762e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_FpI32m32, X86::SUBR_FI32m},
763e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_FpI32m64, X86::SUBR_FI32m},
76459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUBR_FpI32m80, X86::SUBR_FI32m},
765e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp32m    , X86::SUB_F32m  },
766e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp64m    , X86::SUB_F64m  },
767afdc7fda65953c0444671dd3e3ce98f5097c1a20Dale Johannesen  { X86::SUB_Fp64m32  , X86::SUB_F32m  },
76859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUB_Fp80m32  , X86::SUB_F32m  },
76959a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUB_Fp80m64  , X86::SUB_F64m  },
770e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_FpI16m32 , X86::SUB_FI16m },
771e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_FpI16m64 , X86::SUB_FI16m },
77259a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUB_FpI16m80 , X86::SUB_FI16m },
773e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_FpI32m32 , X86::SUB_FI32m },
774e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_FpI32m64 , X86::SUB_FI32m },
77559a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::SUB_FpI32m80 , X86::SUB_FI32m },
776e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::TST_Fp32     , X86::TST_F     },
777e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::TST_Fp64     , X86::TST_F     },
77859a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::TST_Fp80     , X86::TST_F     },
779e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_FpIr32  , X86::UCOM_FIr  },
780e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_FpIr64  , X86::UCOM_FIr  },
78159a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::UCOM_FpIr80  , X86::UCOM_FIr  },
782e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_Fpr32   , X86::UCOM_Fr   },
783e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_Fpr64   , X86::UCOM_Fr   },
78459a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen  { X86::UCOM_Fpr80   , X86::UCOM_Fr   },
78558fe459e36605342410e8c11d12ee1901428b14bChris Lattner};
78658fe459e36605342410e8c11d12ee1901428b14bChris Lattner
78758fe459e36605342410e8c11d12ee1901428b14bChris Lattnerstatic unsigned getConcreteOpcode(unsigned Opcode) {
78858fe459e36605342410e8c11d12ee1901428b14bChris Lattner  ASSERT_SORTED(OpcodeTable);
789718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson  int Opc = Lookup(OpcodeTable, array_lengthof(OpcodeTable), Opcode);
79058fe459e36605342410e8c11d12ee1901428b14bChris Lattner  assert(Opc != -1 && "FP Stack instruction not in OpcodeTable!");
79158fe459e36605342410e8c11d12ee1901428b14bChris Lattner  return Opc;
79258fe459e36605342410e8c11d12ee1901428b14bChris Lattner}
793a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
794a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
795a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// Helper Methods
796a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
797a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
798a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// PopTable - Sorted map of instructions to their popping version.  The first
799a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// element is an instruction, the second is the version which pops.
800a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//
801a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic const TableEntry PopTable[] = {
802e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_FrST0 , X86::ADD_FPrST0  },
803113455be9d69f881165abafb6b6b0dd5b4b54aa8Chris Lattner
804e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIVR_FrST0, X86::DIVR_FPrST0 },
805e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_FrST0 , X86::DIV_FPrST0  },
806113455be9d69f881165abafb6b6b0dd5b4b54aa8Chris Lattner
807e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_F16m  , X86::IST_FP16m   },
808e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::IST_F32m  , X86::IST_FP32m   },
809113455be9d69f881165abafb6b6b0dd5b4b54aa8Chris Lattner
810e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_FrST0 , X86::MUL_FPrST0  },
811113455be9d69f881165abafb6b6b0dd5b4b54aa8Chris Lattner
812e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ST_F32m   , X86::ST_FP32m    },
813e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ST_F64m   , X86::ST_FP64m    },
814e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ST_Frr    , X86::ST_FPrr     },
815a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
816e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUBR_FrST0, X86::SUBR_FPrST0 },
817e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_FrST0 , X86::SUB_FPrST0  },
818a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
819e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_FIr  , X86::UCOM_FIPr   },
820c040bca4b9dfaa58cbc0c00f1cc435e3251332ecChris Lattner
821e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_FPr  , X86::UCOM_FPPr   },
822e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::UCOM_Fr   , X86::UCOM_FPr    },
823a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner};
824a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
825a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// popStackAfter - Pop the current value off of the top of the FP stack after
826a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// the specified instruction.  This attempts to be sneaky and combine the pop
827a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// into the instruction itself if possible.  The iterator is left pointing to
828a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// the last instruction, be it a new pop instruction inserted, or the old
829a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// instruction if it was modified in place.
830a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///
831a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnervoid FPS::popStackAfter(MachineBasicBlock::iterator &I) {
8328d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen  MachineInstr* MI = I;
8338d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen  DebugLoc dl = MI->getDebugLoc();
834a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  ASSERT_SORTED(PopTable);
8353f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng  if (StackTop == 0)
8363f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng    report_fatal_error("Cannot pop empty stack!");
837a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  RegMap[Stack[--StackTop]] = ~0;     // Update state
838a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
839a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // Check to see if there is a popping version of this instruction...
840718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson  int Opcode = Lookup(PopTable, array_lengthof(PopTable), I->getOpcode());
841a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  if (Opcode != -1) {
8425080f4d9919d39b367891dc51e739c571a66036cChris Lattner    I->setDesc(TII->get(Opcode));
843e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen    if (Opcode == X86::UCOM_FPPr)
844c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos      I->RemoveOperand(0);
845a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  } else {    // Insert an explicit pop
8468d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen    I = BuildMI(*MBB, ++I, dl, TII->get(X86::ST_FPrr)).addReg(X86::ST0);
847a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
848a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
849a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
8500526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner/// freeStackSlotAfter - Free the specified register from the register stack, so
8510526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner/// that it is no longer in a register.  If the register is currently at the top
8520526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner/// of the stack, we just pop the current instruction, otherwise we store the
8530526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner/// current top-of-stack into the specified slot, then pop the top of stack.
8540526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattnervoid FPS::freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned FPRegNo) {
8550526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  if (getStackEntry(0) == FPRegNo) {  // already at the top of stack? easy.
8560526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner    popStackAfter(I);
8570526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner    return;
8580526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  }
8590526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner
8600526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  // Otherwise, store the top of stack into the dead slot, killing the operand
8610526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  // without having to add in an explicit xchg then pop.
8620526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  //
863e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  I = freeStackSlotBefore(++I, FPRegNo);
864e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen}
865e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
866e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// freeStackSlotBefore - Free the specified register without trying any
867e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// folding.
868e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund OlesenMachineBasicBlock::iterator
869e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund OlesenFPS::freeStackSlotBefore(MachineBasicBlock::iterator I, unsigned FPRegNo) {
8700526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  unsigned STReg    = getSTReg(FPRegNo);
8710526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  unsigned OldSlot  = getSlot(FPRegNo);
8720526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  unsigned TopReg   = Stack[StackTop-1];
8730526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  Stack[OldSlot]    = TopReg;
8740526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  RegMap[TopReg]    = OldSlot;
8750526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  RegMap[FPRegNo]   = ~0;
8760526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner  Stack[--StackTop] = ~0;
877e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  return BuildMI(*MBB, I, DebugLoc(), TII->get(X86::ST_FPrr)).addReg(STReg);
878e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen}
879e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
880e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// adjustLiveRegs - Kill and revive registers such that exactly the FP
881e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// registers with a bit in Mask are live.
882e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesenvoid FPS::adjustLiveRegs(unsigned Mask, MachineBasicBlock::iterator I) {
883e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  unsigned Defs = Mask;
884e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  unsigned Kills = 0;
885e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  for (unsigned i = 0; i < StackTop; ++i) {
886e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    unsigned RegNo = Stack[i];
887e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    if (!(Defs & (1 << RegNo)))
888e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // This register is live, but we don't want it.
889e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      Kills |= (1 << RegNo);
890e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    else
891e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      // We don't need to imp-def this live register.
892e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      Defs &= ~(1 << RegNo);
893e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
894e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  assert((Kills & Defs) == 0 && "Register needs killing and def'ing?");
895e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
896e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Produce implicit-defs for free by using killed registers.
897e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  while (Kills && Defs) {
898c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer    unsigned KReg = countTrailingZeros(Kills);
899c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer    unsigned DReg = countTrailingZeros(Defs);
900e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Renaming %FP" << KReg << " as imp %FP" << DReg << "\n");
901e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    std::swap(Stack[getSlot(KReg)], Stack[getSlot(DReg)]);
902e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    std::swap(RegMap[KReg], RegMap[DReg]);
903e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    Kills &= ~(1 << KReg);
904e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    Defs &= ~(1 << DReg);
905e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
906e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
907e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Kill registers by popping.
908e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (Kills && I != MBB->begin()) {
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineBasicBlock::iterator I2 = std::prev(I);
910d519de082766bb71e13f6a516b305ff841c6b48cJakob Stoklund Olesen    while (StackTop) {
911e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      unsigned KReg = getStackEntry(0);
912e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      if (!(Kills & (1 << KReg)))
913e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen        break;
914e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      DEBUG(dbgs() << "Popping %FP" << KReg << "\n");
915e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      popStackAfter(I2);
916e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      Kills &= ~(1 << KReg);
917e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    }
918e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
919e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
920e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Manually kill the rest.
921e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  while (Kills) {
922c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer    unsigned KReg = countTrailingZeros(Kills);
923e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Killing %FP" << KReg << "\n");
924e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    freeStackSlotBefore(I, KReg);
925e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    Kills &= ~(1 << KReg);
926e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
927e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
928e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Load zeros for all the imp-defs.
929e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  while(Defs) {
930c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer    unsigned DReg = countTrailingZeros(Defs);
931e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Defining %FP" << DReg << " as 0\n");
932e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    BuildMI(*MBB, I, DebugLoc(), TII->get(X86::LD_F0));
933e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    pushReg(DReg);
934e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    Defs &= ~(1 << DReg);
935e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
936e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
937e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Now we should have the correct registers live.
938e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  DEBUG(dumpStack());
939e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  assert(StackTop == CountPopulation_32(Mask) && "Live count mismatch");
940e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen}
941e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
942e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// shuffleStackTop - emit fxch instructions before I to shuffle the top
943e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// FixCount entries into the order given by FixStack.
944e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen/// FIXME: Is there a better algorithm than insertion sort?
945e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesenvoid FPS::shuffleStackTop(const unsigned char *FixStack,
946e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen                          unsigned FixCount,
947e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen                          MachineBasicBlock::iterator I) {
948e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // Move items into place, starting from the desired stack bottom.
949e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  while (FixCount--) {
950e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Old register at position FixCount.
951e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    unsigned OldReg = getStackEntry(FixCount);
952e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // Desired register at position FixCount.
953e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    unsigned Reg = FixStack[FixCount];
954e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    if (Reg == OldReg)
955e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      continue;
956e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // (Reg st0) (OldReg st0) = (Reg OldReg st0)
957e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    moveToTop(Reg, I);
9589bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (FixCount > 0)
9599bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      moveToTop(OldReg, I);
960e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  }
961e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  DEBUG(dumpStack());
9620526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner}
9630526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner
9640526f01fec0945eca49ccd91f22a93af6bb71c17Chris Lattner
965a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
966a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// Instruction transformation implementation
967a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
968a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
969a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// handleZeroArgFP - ST(0) = fld0    ST(0) = flds <mem>
9704a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner///
971a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnervoid FPS::handleZeroArgFP(MachineBasicBlock::iterator &I) {
972c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr *MI = I;
973a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  unsigned DestReg = getFPReg(MI->getOperand(0));
974a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
97558fe459e36605342410e8c11d12ee1901428b14bChris Lattner  // Change from the pseudo instruction to the concrete instruction.
97658fe459e36605342410e8c11d12ee1901428b14bChris Lattner  MI->RemoveOperand(0);   // Remove the explicit ST(0) operand
9775080f4d9919d39b367891dc51e739c571a66036cChris Lattner  MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode())));
978a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
97958fe459e36605342410e8c11d12ee1901428b14bChris Lattner  // Result gets pushed on the stack.
980a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  pushReg(DestReg);
981a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
982a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
9834a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner/// handleOneArgFP - fst <mem>, ST(0)
9844a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner///
985a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnervoid FPS::handleOneArgFP(MachineBasicBlock::iterator &I) {
986c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr *MI = I;
987749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  unsigned NumOps = MI->getDesc().getNumOperands();
988ac0ed5dc082dff9ce359af5422f5b82047b4fe6bChris Lattner  assert((NumOps == X86::AddrNumOperands + 1 || NumOps == 1) &&
989b97046ae4f5979df9fea20216fef0fe67211e0c6Chris Lattner         "Can only handle fst* & ftst instructions!");
990a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
9914a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  // Is this the last use of the source register?
992171d09ea537ac272091a1a2560302074b144fccaEvan Cheng  unsigned Reg = getFPReg(MI->getOperand(NumOps-1));
9936130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsSrc = MI->killsRegister(X86::FP0+Reg);
994a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
99566b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen  if (KillsSrc)
99666b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    duplicatePendingSTBeforeKill(Reg, I);
99766b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen
9982b1527157116ba6045667eb29568f2f460d7b670Evan Cheng  // FISTP64m is strange because there isn't a non-popping versions.
999a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // If we have one _and_ we don't want to pop the operand, duplicate the value
1000a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // on the stack instead of moving it.  This ensure that popping the value is
1001a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // always ok.
1002ca8035e3569afd5a8d0ef406b82dad1b7e673683Dale Johannesen  // Ditto FISTTP16m, FISTTP32m, FISTTP64m, ST_FpP80m.
1003a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  //
10042b1527157116ba6045667eb29568f2f460d7b670Evan Cheng  if (!KillsSrc &&
1005e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen      (MI->getOpcode() == X86::IST_Fp64m32 ||
1006e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen       MI->getOpcode() == X86::ISTT_Fp16m32 ||
1007e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen       MI->getOpcode() == X86::ISTT_Fp32m32 ||
1008e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen       MI->getOpcode() == X86::ISTT_Fp64m32 ||
1009e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen       MI->getOpcode() == X86::IST_Fp64m64 ||
1010e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen       MI->getOpcode() == X86::ISTT_Fp16m64 ||
1011e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen       MI->getOpcode() == X86::ISTT_Fp32m64 ||
101259a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen       MI->getOpcode() == X86::ISTT_Fp64m64 ||
101341de436ca367ee3b4257551754bac236a37a2da5Dale Johannesen       MI->getOpcode() == X86::IST_Fp64m80 ||
1014a996d52e3767fb560774dfd8bc911c927ed5ca9fDale Johannesen       MI->getOpcode() == X86::ISTT_Fp16m80 ||
1015a996d52e3767fb560774dfd8bc911c927ed5ca9fDale Johannesen       MI->getOpcode() == X86::ISTT_Fp32m80 ||
1016a996d52e3767fb560774dfd8bc911c927ed5ca9fDale Johannesen       MI->getOpcode() == X86::ISTT_Fp64m80 ||
101759a587337e1c3bde6c0c560ad34f9ee73bb78328Dale Johannesen       MI->getOpcode() == X86::ST_FpP80m)) {
1018e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen    duplicateToTop(Reg, getScratchReg(), I);
1019a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  } else {
1020a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    moveToTop(Reg, I);            // Move to the top of the stack...
1021a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
1022a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
102358fe459e36605342410e8c11d12ee1901428b14bChris Lattner  // Convert from the pseudo instruction to the concrete instruction.
1024171d09ea537ac272091a1a2560302074b144fccaEvan Cheng  MI->RemoveOperand(NumOps-1);    // Remove explicit ST(0) operand
10255080f4d9919d39b367891dc51e739c571a66036cChris Lattner  MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode())));
10260e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman
1027e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  if (MI->getOpcode() == X86::IST_FP64m ||
1028e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen      MI->getOpcode() == X86::ISTT_FP16m ||
1029e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen      MI->getOpcode() == X86::ISTT_FP32m ||
103088835735f49c3fce20698a72898df83bd84bd1cdDale Johannesen      MI->getOpcode() == X86::ISTT_FP64m ||
103188835735f49c3fce20698a72898df83bd84bd1cdDale Johannesen      MI->getOpcode() == X86::ST_FP80m) {
10323f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng    if (StackTop == 0)
10333f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng      report_fatal_error("Stack empty??");
1034a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    --StackTop;
1035a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  } else if (KillsSrc) { // Last use of operand?
1036a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    popStackAfter(I);
1037a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
1038a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
1039a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
10404a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner
10414cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner/// handleOneArgFPRW: Handle instructions that read from the top of stack and
10424cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner/// replace the value with a newly computed value.  These instructions may have
10434cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner/// non-fp operands after their FP operands.
10444cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner///
10454cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner///  Examples:
10464cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner///     R1 = fchs R2
10474cf15e7a3bed2ff3a7fa87f18cdf65b7eecccee2Chris Lattner///     R1 = fadd R2, [mem]
10484a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner///
10494a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattnervoid FPS::handleOneArgFPRW(MachineBasicBlock::iterator &I) {
1050c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr *MI = I;
1051a022bdfd99bc092dac9cefb4c2be9de787ea8e0fEvan Cheng#ifndef NDEBUG
1052749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  unsigned NumOps = MI->getDesc().getNumOperands();
1053171d09ea537ac272091a1a2560302074b144fccaEvan Cheng  assert(NumOps >= 2 && "FPRW instructions must have 2 ops!!");
1054a022bdfd99bc092dac9cefb4c2be9de787ea8e0fEvan Cheng#endif
10554a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner
10564a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  // Is this the last use of the source register?
10574a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  unsigned Reg = getFPReg(MI->getOperand(1));
10586130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsSrc = MI->killsRegister(X86::FP0+Reg);
10594a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner
10604a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  if (KillsSrc) {
106166b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen    duplicatePendingSTBeforeKill(Reg, I);
10624a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    // If this is the last use of the source register, just make sure it's on
10634a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    // the top of the stack.
10644a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    moveToTop(Reg, I);
10653f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng    if (StackTop == 0)
10663f490f3469dd30b47d7b59a9b84750c31dc19633Evan Cheng      report_fatal_error("Stack cannot be empty!");
10674a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    --StackTop;
10684a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    pushReg(getFPReg(MI->getOperand(0)));
10694a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  } else {
10704a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    // If this is not the last use of the source register, _copy_ it to the top
10714a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    // of the stack.
10724a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner    duplicateToTop(Reg, getFPReg(MI->getOperand(0)), I);
10734a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  }
10744a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner
107558fe459e36605342410e8c11d12ee1901428b14bChris Lattner  // Change from the pseudo instruction to the concrete instruction.
10764a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  MI->RemoveOperand(1);   // Drop the source operand.
10774a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner  MI->RemoveOperand(0);   // Drop the destination operand.
10785080f4d9919d39b367891dc51e739c571a66036cChris Lattner  MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode())));
10794a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner}
10804a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner
10814a06f354843117df344d7b0aacc7114d50d38fe9Chris Lattner
1082a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//===----------------------------------------------------------------------===//
1083a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// Define tables of various ways to map pseudo instructions
1084a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner//
1085a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1086a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// ForwardST0Table - Map: A = B op C  into: ST(0) = ST(0) op ST(i)
1087a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic const TableEntry ForwardST0Table[] = {
1088e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp32  , X86::ADD_FST0r },
1089e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp64  , X86::ADD_FST0r },
10906a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::ADD_Fp80  , X86::ADD_FST0r },
1091e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp32  , X86::DIV_FST0r },
1092e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp64  , X86::DIV_FST0r },
10936a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::DIV_Fp80  , X86::DIV_FST0r },
1094e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp32  , X86::MUL_FST0r },
1095e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp64  , X86::MUL_FST0r },
10966a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::MUL_Fp80  , X86::MUL_FST0r },
1097e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp32  , X86::SUB_FST0r },
1098e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp64  , X86::SUB_FST0r },
10996a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::SUB_Fp80  , X86::SUB_FST0r },
1100a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner};
1101a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1102a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// ReverseST0Table - Map: A = B op C  into: ST(0) = ST(i) op ST(0)
1103a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic const TableEntry ReverseST0Table[] = {
1104e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp32  , X86::ADD_FST0r  },   // commutative
1105e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp64  , X86::ADD_FST0r  },   // commutative
11066a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::ADD_Fp80  , X86::ADD_FST0r  },   // commutative
1107e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp32  , X86::DIVR_FST0r },
1108e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp64  , X86::DIVR_FST0r },
11096a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::DIV_Fp80  , X86::DIVR_FST0r },
1110e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp32  , X86::MUL_FST0r  },   // commutative
1111e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp64  , X86::MUL_FST0r  },   // commutative
11126a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::MUL_Fp80  , X86::MUL_FST0r  },   // commutative
1113e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp32  , X86::SUBR_FST0r },
1114e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp64  , X86::SUBR_FST0r },
11156a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::SUB_Fp80  , X86::SUBR_FST0r },
1116a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner};
1117a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1118a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// ForwardSTiTable - Map: A = B op C  into: ST(i) = ST(0) op ST(i)
1119a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic const TableEntry ForwardSTiTable[] = {
1120e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp32  , X86::ADD_FrST0  },   // commutative
1121e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp64  , X86::ADD_FrST0  },   // commutative
11226a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::ADD_Fp80  , X86::ADD_FrST0  },   // commutative
1123e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp32  , X86::DIVR_FrST0 },
1124e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp64  , X86::DIVR_FrST0 },
11256a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::DIV_Fp80  , X86::DIVR_FrST0 },
1126e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp32  , X86::MUL_FrST0  },   // commutative
1127e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp64  , X86::MUL_FrST0  },   // commutative
11286a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::MUL_Fp80  , X86::MUL_FrST0  },   // commutative
1129e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp32  , X86::SUBR_FrST0 },
1130e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp64  , X86::SUBR_FrST0 },
11316a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::SUB_Fp80  , X86::SUBR_FrST0 },
1132a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner};
1133a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1134a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner// ReverseSTiTable - Map: A = B op C  into: ST(i) = ST(i) op ST(0)
1135a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnerstatic const TableEntry ReverseSTiTable[] = {
1136e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp32  , X86::ADD_FrST0 },
1137e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::ADD_Fp64  , X86::ADD_FrST0 },
11386a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::ADD_Fp80  , X86::ADD_FrST0 },
1139e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp32  , X86::DIV_FrST0 },
1140e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::DIV_Fp64  , X86::DIV_FrST0 },
11416a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::DIV_Fp80  , X86::DIV_FrST0 },
1142e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp32  , X86::MUL_FrST0 },
1143e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::MUL_Fp64  , X86::MUL_FrST0 },
11446a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::MUL_Fp80  , X86::MUL_FrST0 },
1145e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp32  , X86::SUB_FrST0 },
1146e377d4d142d7e2ec9266435087c99ffc43f394aaDale Johannesen  { X86::SUB_Fp64  , X86::SUB_FrST0 },
11476a30811d5c3484883cbcbbda1140f2ac36f7c09cDale Johannesen  { X86::SUB_Fp80  , X86::SUB_FrST0 },
1148a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner};
1149a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1150a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1151a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// handleTwoArgFP - Handle instructions like FADD and friends which are virtual
1152a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// instructions which need to be simplified and possibly transformed.
1153a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///
1154a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// Result: ST(0) = fsub  ST(0), ST(i)
1155a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///         ST(i) = fsub  ST(0), ST(i)
1156a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///         ST(0) = fsubr ST(0), ST(i)
1157a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///         ST(i) = fsubr ST(0), ST(i)
11580e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman///
1159a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnervoid FPS::handleTwoArgFP(MachineBasicBlock::iterator &I) {
1160a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  ASSERT_SORTED(ForwardST0Table); ASSERT_SORTED(ReverseST0Table);
1161a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  ASSERT_SORTED(ForwardSTiTable); ASSERT_SORTED(ReverseSTiTable);
1162c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr *MI = I;
1163a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1164749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  unsigned NumOperands = MI->getDesc().getNumOperands();
1165d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  assert(NumOperands == 3 && "Illegal TwoArgFP instruction!");
1166a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  unsigned Dest = getFPReg(MI->getOperand(0));
1167a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  unsigned Op0 = getFPReg(MI->getOperand(NumOperands-2));
1168a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  unsigned Op1 = getFPReg(MI->getOperand(NumOperands-1));
11696130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsOp0 = MI->killsRegister(X86::FP0+Op0);
11706130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsOp1 = MI->killsRegister(X86::FP0+Op1);
11718d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen  DebugLoc dl = MI->getDebugLoc();
1172a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1173a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  unsigned TOS = getStackEntry(0);
1174a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1175a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // One of our operands must be on the top of the stack.  If neither is yet, we
1176a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // need to move one.
1177a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  if (Op0 != TOS && Op1 != TOS) {   // No operand at TOS?
1178a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // We can choose to move either operand to the top of the stack.  If one of
1179a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // the operands is killed by this instruction, we want that one so that we
1180a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // can update right on top of the old version.
1181a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    if (KillsOp0) {
1182a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      moveToTop(Op0, I);         // Move dead operand to TOS.
1183a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      TOS = Op0;
1184a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    } else if (KillsOp1) {
1185a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      moveToTop(Op1, I);
1186a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      TOS = Op1;
1187a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    } else {
1188a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // All of the operands are live after this instruction executes, so we
1189a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // cannot update on top of any operand.  Because of this, we must
1190a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // duplicate one of the stack elements to the top.  It doesn't matter
1191a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // which one we pick.
1192a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      //
1193a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      duplicateToTop(Op0, Dest, I);
1194a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      Op0 = TOS = Dest;
1195a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      KillsOp0 = true;
1196a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
1197d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  } else if (!KillsOp0 && !KillsOp1) {
1198a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // If we DO have one of our operands at the top of the stack, but we don't
1199a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // have a dead operand, we must duplicate one of the operands to a new slot
1200a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    // on the stack.
1201a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    duplicateToTop(Op0, Dest, I);
1202a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    Op0 = TOS = Dest;
1203a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    KillsOp0 = true;
1204a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
1205a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1206a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // Now we know that one of our operands is on the top of the stack, and at
1207a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // least one of our operands is killed by this instruction.
12080e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman  assert((TOS == Op0 || TOS == Op1) && (KillsOp0 || KillsOp1) &&
12090e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman         "Stack conditions not set up right!");
1210a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1211a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // We decide which form to use based on what is on the top of the stack, and
1212a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // which operand is killed by this instruction.
1213a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  const TableEntry *InstTable;
1214a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  bool isForward = TOS == Op0;
1215a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  bool updateST0 = (TOS == Op0 && !KillsOp1) || (TOS == Op1 && !KillsOp0);
1216a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  if (updateST0) {
1217a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    if (isForward)
1218a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      InstTable = ForwardST0Table;
1219a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    else
1220a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      InstTable = ReverseST0Table;
1221a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  } else {
1222a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    if (isForward)
1223a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      InstTable = ForwardSTiTable;
1224a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    else
1225a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      InstTable = ReverseSTiTable;
1226a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
12270e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman
1228718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson  int Opcode = Lookup(InstTable, array_lengthof(ForwardST0Table),
1229718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson                      MI->getOpcode());
1230a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  assert(Opcode != -1 && "Unknown TwoArgFP pseudo instruction!");
1231a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1232a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // NotTOS - The register which is not on the top of stack...
1233a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  unsigned NotTOS = (TOS == Op0) ? Op1 : Op0;
1234a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1235a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // Replace the old instruction with a new instruction
1236c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  MBB->remove(I++);
12378d13f8f1043d8b47940ecab7bac838ff1e8166f8Dale Johannesen  I = BuildMI(*MBB, I, dl, TII->get(Opcode)).addReg(getSTReg(NotTOS));
1238a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1239a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // If both operands are killed, pop one off of the stack in addition to
1240a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // overwriting the other one.
1241a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  if (KillsOp0 && KillsOp1 && Op0 != Op1) {
1242a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    assert(!updateST0 && "Should have updated other operand!");
1243a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    popStackAfter(I);   // Pop the top of stack
1244a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
1245a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1246a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // Update stack information so that we know the destination register is now on
1247a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  // the stack.
1248d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  unsigned UpdatedSlot = getSlot(updateST0 ? TOS : NotTOS);
1249d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  assert(UpdatedSlot < StackTop && Dest < 7);
1250d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  Stack[UpdatedSlot]   = Dest;
1251d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  RegMap[Dest]         = UpdatedSlot;
12528e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MBB->getParent()->DeleteMachineInstr(MI); // Remove the old instruction
1253d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner}
1254d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner
12550ca2c8e02c40c5fad9faeb725e8ab5df5e76ec06Chris Lattner/// handleCompareFP - Handle FUCOM and FUCOMI instructions, which have two FP
1256d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner/// register arguments and no explicit destinations.
12570e0a7a45d3d0a8c865a078459d2e1c6d8967a100Misha Brukman///
1258d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattnervoid FPS::handleCompareFP(MachineBasicBlock::iterator &I) {
1259d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  ASSERT_SORTED(ForwardST0Table); ASSERT_SORTED(ReverseST0Table);
1260d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  ASSERT_SORTED(ForwardSTiTable); ASSERT_SORTED(ReverseSTiTable);
1261d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  MachineInstr *MI = I;
1262d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner
1263749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  unsigned NumOperands = MI->getDesc().getNumOperands();
12640ca2c8e02c40c5fad9faeb725e8ab5df5e76ec06Chris Lattner  assert(NumOperands == 2 && "Illegal FUCOM* instruction!");
1265d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  unsigned Op0 = getFPReg(MI->getOperand(NumOperands-2));
1266d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  unsigned Op1 = getFPReg(MI->getOperand(NumOperands-1));
12676130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsOp0 = MI->killsRegister(X86::FP0+Op0);
12686130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsOp1 = MI->killsRegister(X86::FP0+Op1);
1269d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner
1270d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  // Make sure the first operand is on the top of stack, the other one can be
1271d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  // anywhere.
1272d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  moveToTop(Op0, I);
1273d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner
127458fe459e36605342410e8c11d12ee1901428b14bChris Lattner  // Change from the pseudo instruction to the concrete instruction.
127557790422ca6f4d2af23a4e29af3c48a19a5cfbd8Chris Lattner  MI->getOperand(0).setReg(getSTReg(Op1));
127657790422ca6f4d2af23a4e29af3c48a19a5cfbd8Chris Lattner  MI->RemoveOperand(1);
12775080f4d9919d39b367891dc51e739c571a66036cChris Lattner  MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode())));
127857790422ca6f4d2af23a4e29af3c48a19a5cfbd8Chris Lattner
1279d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  // If any of the operands are killed by this instruction, free them.
1280d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  if (KillsOp0) freeStackSlotAfter(I, Op0);
1281d62d5d7e5bb353785784fc40c088836c4cf160b4Chris Lattner  if (KillsOp1 && Op0 != Op1) freeStackSlotAfter(I, Op1);
1282a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
1283a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1284c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner/// handleCondMovFP - Handle two address conditional move instructions.  These
128594c22716d60ff5edf6a98a3c67e0faa001be1142Sylvestre Ledru/// instructions move a st(i) register to st(0) iff a condition is true.  These
1286c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner/// instructions require that the first operand is at the top of the stack, but
1287c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner/// otherwise don't modify the stack at all.
1288c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattnervoid FPS::handleCondMovFP(MachineBasicBlock::iterator &I) {
1289c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  MachineInstr *MI = I;
1290c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner
1291c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  unsigned Op0 = getFPReg(MI->getOperand(0));
12926cdb1ea610c2d802696da55c55bf73c44202a2dbChris Lattner  unsigned Op1 = getFPReg(MI->getOperand(2));
12936130f66eaae89f8878590796977678afa8448926Evan Cheng  bool KillsOp1 = MI->killsRegister(X86::FP0+Op1);
1294c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner
1295c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  // The first operand *must* be on the top of the stack.
1296c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  moveToTop(Op0, I);
1297c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner
1298c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  // Change the second operand to the stack register that the operand is in.
129958fe459e36605342410e8c11d12ee1901428b14bChris Lattner  // Change from the pseudo instruction to the concrete instruction.
1300c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  MI->RemoveOperand(0);
13016cdb1ea610c2d802696da55c55bf73c44202a2dbChris Lattner  MI->RemoveOperand(1);
1302c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  MI->getOperand(0).setReg(getSTReg(Op1));
13035080f4d9919d39b367891dc51e739c571a66036cChris Lattner  MI->setDesc(TII->get(getConcreteOpcode(MI->getOpcode())));
1304a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1305c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner  // If we kill the second operand, make sure to pop it from the stack.
1306ddd2a4556a0b4d0e364de7087ccf1475fa23f39fEvan Cheng  if (Op0 != Op1 && KillsOp1) {
130776eb08bcda869413d4e730dce290874762d5bfd3Chris Lattner    // Get this value off of the register stack.
130876eb08bcda869413d4e730dce290874762d5bfd3Chris Lattner    freeStackSlotAfter(I, Op1);
130976eb08bcda869413d4e730dce290874762d5bfd3Chris Lattner  }
1310c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner}
1311c1bab32bc56e6d27d1223431716523bbe35e4d2eChris Lattner
1312a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1313a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// handleSpecialFP - Handle special instructions which behave unlike other
1314cf00c4ab3ba308d45d98c5ccab87362cf802facbMisha Brukman/// floating point instructions.  This is primarily intended for use by pseudo
1315a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner/// instructions.
1316a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner///
1317a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattnervoid FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
1318c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  MachineInstr *MI = I;
1319a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  switch (MI->getOpcode()) {
1320c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown SpecialFP instruction!");
13219bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen  case TargetOpcode::COPY: {
13229bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // We handle three kinds of copies: FP <- FP, FP <- ST, and ST <- FP.
13239bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    const MachineOperand &MO1 = MI->getOperand(1);
13249bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    const MachineOperand &MO0 = MI->getOperand(0);
13259bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned DstST = MO0.getReg() - X86::ST0;
13269bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned SrcST = MO1.getReg() - X86::ST0;
13279bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    bool KillsSrc = MI->killsRegister(MO1.getReg());
13289bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
13299bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // ST = COPY FP. Set up a pending ST register.
13309bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (DstST < 8) {
13319bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned SrcFP = getFPReg(MO1);
13329bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(isLive(SrcFP) && "Cannot copy dead register");
13339bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(!MO0.isDead() && "Cannot copy to dead ST register");
13349bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
13359bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      // Unallocated STs are marked as the nonexistent FP255.
13369bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      while (NumPendingSTs <= DstST)
13379bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        PendingST[NumPendingSTs++] = NumFPRegs;
13389bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
13399bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      // STi could still be live from a previous inline asm.
13409bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (isScratchReg(PendingST[DstST])) {
13419bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        DEBUG(dbgs() << "Clobbering old ST in FP" << unsigned(PendingST[DstST])
13429bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen                     << '\n');
13439bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        freeStackSlotBefore(MI, PendingST[DstST]);
13449bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      }
134524e0a546b40d67dd3662273eb4aef30c230a15efChris Lattner
13469bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      // When the source is killed, allocate a scratch FP register.
13479bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (KillsSrc) {
134866b0f515d5f7d4b830c3407a273facde405e4f86Jakob Stoklund Olesen        duplicatePendingSTBeforeKill(SrcFP, I);
13499bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        unsigned Slot = getSlot(SrcFP);
13509bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        unsigned SR = getScratchReg();
13519bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        PendingST[DstST] = SR;
13529bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        Stack[Slot] = SR;
13539bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        RegMap[SR] = Slot;
13549bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      } else
13559bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        PendingST[DstST] = SrcFP;
135624e0a546b40d67dd3662273eb4aef30c230a15efChris Lattner      break;
13571c3329f7072356c8da84534ed0a7033b10f73062Rafael Espindola    }
13589bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
13599bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // FP = COPY ST. Extract fixed stack value.
13609bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Any instruction defining ST registers must have assigned them to a
13619bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // scratch register.
13629bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (SrcST < 8) {
13639bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned DstFP = getFPReg(MO0);
13649bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(!isLive(DstFP) && "Cannot copy ST to live FP register");
13659bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(NumPendingSTs > SrcST && "Cannot copy from dead ST register");
13669bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned SrcFP = PendingST[SrcST];
13679bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(isScratchReg(SrcFP) && "Expected ST in a scratch register");
13689bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      assert(isLive(SrcFP) && "Scratch holding ST is dead");
13699bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
13709bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      // DstFP steals the stack slot from SrcFP.
13719bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned Slot = getSlot(SrcFP);
13729bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      Stack[Slot] = DstFP;
13739bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      RegMap[DstFP] = Slot;
13749bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
13759bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      // Always treat the ST as killed.
13769bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      PendingST[SrcST] = NumFPRegs;
13779bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      while (NumPendingSTs && PendingST[NumPendingSTs - 1] == NumFPRegs)
13789bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        --NumPendingSTs;
13799bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      break;
1380a0eedac226e79d818ce1124fe500a6e354e3444aEvan Cheng    }
1381fb11288109329cb736d9f49769581a0d0c23fe19Evan Cheng
13829bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // FP <- FP copy.
13839bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned DstFP = getFPReg(MO0);
13849bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned SrcFP = getFPReg(MO1);
13859bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    assert(isLive(SrcFP) && "Cannot copy dead register");
13869bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (KillsSrc) {
1387a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // If the input operand is killed, we can just change the owner of the
1388a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // incoming stack slot into the result.
13899bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned Slot = getSlot(SrcFP);
13909bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      Stack[Slot] = DstFP;
13919bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      RegMap[DstFP] = Slot;
1392a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    } else {
13939bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      // For COPY we just duplicate the specified value to a new stack slot.
1394a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner      // This could be made better, but would require substantial changes.
13959bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      duplicateToTop(SrcFP, DstFP, I);
1396a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    }
13979bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    break;
13989bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen  }
13999bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
140056e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen  case TargetOpcode::IMPLICIT_DEF: {
140156e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    // All FP registers must be explicitly defined, so load a 0 instead.
140256e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    unsigned Reg = MI->getOperand(0).getReg() - X86::FP0;
140356e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    DEBUG(dbgs() << "Emitting LD_F0 for implicit FP" << Reg << '\n');
140456e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    BuildMI(*MBB, I, MI->getDebugLoc(), TII->get(X86::LD_F0));
140556e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    pushReg(Reg);
140656e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen    break;
140756e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen  }
140856e3232d5a5206f8b554eccd4aea2e75e59d4314Jakob Stoklund Olesen
14099bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen  case X86::FpPOP_RETVAL: {
14109bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // The FpPOP_RETVAL instruction is used after calls that return a value on
14119bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // the floating point stack. We cannot model this with ST defs since CALL
14129bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // instructions have fixed clobber lists. This instruction is interpreted
14139bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // to mean that there is one more live register on the stack than we
14149bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // thought.
14159bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14169bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // This means that StackTop does not match the hardware stack between a
14179bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // call and the FpPOP_RETVAL instructions.  We do tolerate FP instructions
14189bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // between CALL and FpPOP_RETVAL as long as they don't overflow the
14199bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // hardware stack.
14209bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned DstFP = getFPReg(MI->getOperand(0));
14219bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
14229bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Move existing stack elements up to reflect reality.
14239bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    assert(StackTop < 8 && "Stack overflowed before FpPOP_RETVAL");
14249bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (StackTop) {
14259bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      std::copy_backward(Stack, Stack + StackTop, Stack + StackTop + 1);
14269bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      for (unsigned i = 0; i != NumFPRegs; ++i)
14279bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        ++RegMap[i];
14283c78697a3cb6e98d904535606fbebab7746d1161Nick Lewycky    }
14299bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    ++StackTop;
14309bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
14319bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // DstFP is the new bottom of the stack.
14329bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    Stack[0] = DstFP;
14339bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    RegMap[DstFP] = 0;
14349bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
14359bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // DstFP will be killed by processBasicBlock if this was a dead def.
1436a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner    break;
14379bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen  }
14389bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
1439518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner  case TargetOpcode::INLINEASM: {
1440e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // The inline asm MachineInstr currently only *uses* FP registers for the
1441e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // 'f' constraint.  These should be turned into the current ST(x) register
14429bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // in the machine instr.
14439bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14449bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // There are special rules for x87 inline assembly. The compiler must know
14459bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // exactly how many registers are popped and pushed implicitly by the asm.
14469bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Otherwise it is not possible to restore the stack state after the inline
14479bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // asm.
14489bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14499bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // There are 3 kinds of input operands:
14509bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14519bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // 1. Popped inputs. These must appear at the stack top in ST0-STn. A
14529bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    popped input operand must be in a fixed stack slot, and it is either
14539bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    tied to an output operand, or in the clobber list. The MI has ST use
14549bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    and def operands for these inputs.
14559bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14569bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // 2. Fixed inputs. These inputs appear in fixed stack slots, but are
14579bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    preserved by the inline asm. The fixed stack slots must be STn-STm
14589bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    following the popped inputs. A fixed input operand cannot be tied to
14599bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    an output or appear in the clobber list. The MI has ST use operands
14609bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    and no defs for these inputs.
14619bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14629bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // 3. Preserved inputs. These inputs use the "f" constraint which is
14639bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    represented as an FP register. The inline asm won't change these
14649bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //    stack slots.
14659bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    //
14669bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Outputs must be in ST registers, FP outputs are not allowed. Clobbered
14679bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // registers do not count as output operands. The inline asm changes the
14689bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // stack as if it popped all the popped inputs and then pushed all the
14699bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // output operands.
14709bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
14719bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Scan the assembly for ST registers used, defined and clobbered. We can
14729bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // only tell clobbers from defs by looking at the asm descriptor.
14739bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned STUses = 0, STDefs = 0, STClobbers = 0, STDeadDefs = 0;
14749bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned NumOps = 0;
14759bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = InlineAsm::MIOp_FirstOperand, e = MI->getNumOperands();
14769bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen         i != e && MI->getOperand(i).isImm(); i += 1 + NumOps) {
14779bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned Flags = MI->getOperand(i).getImm();
14789bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      NumOps = InlineAsm::getNumOperandRegisters(Flags);
14799bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (NumOps != 1)
14809bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
14819bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      const MachineOperand &MO = MI->getOperand(i + 1);
14829bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (!MO.isReg())
14839bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
14849bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned STReg = MO.getReg() - X86::ST0;
14859bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (STReg >= 8)
14869bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
14879bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
14889bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      switch (InlineAsm::getKind(Flags)) {
14899bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      case InlineAsm::Kind_RegUse:
14909bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        STUses |= (1u << STReg);
14919bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        break;
14929bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      case InlineAsm::Kind_RegDef:
14939bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      case InlineAsm::Kind_RegDefEarlyClobber:
14949bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        STDefs |= (1u << STReg);
14959bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        if (MO.isDead())
14969bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          STDeadDefs |= (1u << STReg);
14979bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        break;
14989bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      case InlineAsm::Kind_Clobber:
14999bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        STClobbers |= (1u << STReg);
15009bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        break;
15019bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      default:
15029bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        break;
15039bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      }
15049bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
15059bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15069bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (STUses && !isMask_32(STUses))
15070d3d95662f5a5b43045e8707b773048a7c317f13Jakob Stoklund Olesen      MI->emitError("fixed input regs must be last on the x87 stack");
15089bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned NumSTUses = CountTrailingOnes_32(STUses);
15099bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15109bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Defs must be contiguous from the stack top. ST0-STn.
1511d519de082766bb71e13f6a516b305ff841c6b48cJakob Stoklund Olesen    if (STDefs && !isMask_32(STDefs)) {
15120d3d95662f5a5b43045e8707b773048a7c317f13Jakob Stoklund Olesen      MI->emitError("output regs must be last on the x87 stack");
1513d519de082766bb71e13f6a516b305ff841c6b48cJakob Stoklund Olesen      STDefs = NextPowerOf2(STDefs) - 1;
1514d519de082766bb71e13f6a516b305ff841c6b48cJakob Stoklund Olesen    }
15159bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned NumSTDefs = CountTrailingOnes_32(STDefs);
15169bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15179bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // So must the clobbered stack slots. ST0-STm, m >= n.
15189bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (STClobbers && !isMask_32(STDefs | STClobbers))
15190d3d95662f5a5b43045e8707b773048a7c317f13Jakob Stoklund Olesen      MI->emitError("clobbers must be last on the x87 stack");
15209bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15219bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Popped inputs are the ones that are also clobbered or defined.
15229bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned STPopped = STUses & (STDefs | STClobbers);
15239bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    if (STPopped && !isMask_32(STPopped))
15240d3d95662f5a5b43045e8707b773048a7c317f13Jakob Stoklund Olesen      MI->emitError("implicitly popped regs must be last on the x87 stack");
15259bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned NumSTPopped = CountTrailingOnes_32(STPopped);
15269bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15279bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    DEBUG(dbgs() << "Asm uses " << NumSTUses << " fixed regs, pops "
15289bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen                 << NumSTPopped << ", and defines " << NumSTDefs << " regs.\n");
15299bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15309bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Scan the instruction for FP uses corresponding to "f" constraints.
15319bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Collect FP registers to kill afer the instruction.
15329bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Always kill all the scratch regs.
15339bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned FPKills = ((1u << NumFPRegs) - 1) & ~0xff;
15349bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    unsigned FPUsed = 0;
1535e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1536e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      MachineOperand &Op = MI->getOperand(i);
1537d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
1538e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner        continue;
15399bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (!Op.isUse())
15400d3d95662f5a5b43045e8707b773048a7c317f13Jakob Stoklund Olesen        MI->emitError("illegal \"f\" output constraint");
1541e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      unsigned FPReg = getFPReg(Op);
15429bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      FPUsed |= 1U << FPReg;
15439bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
1544e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      // If we kill this operand, make sure to pop it from the stack after the
1545e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      // asm.  We just remember it for now, and pop them all off at the end in
1546e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      // a batch.
1547e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner      if (Op.isKill())
15489bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        FPKills |= 1U << FPReg;
15499bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
15509bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15519bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // The popped inputs will be killed by the instruction, so duplicate them
15529bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // if the FP register needs to be live after the instruction, or if it is
15539bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // used in the instruction itself. We effectively treat the popped inputs
15549bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // as early clobbers.
15559bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = 0; i < NumSTPopped; ++i) {
15569bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if ((FPKills & ~FPUsed) & (1u << PendingST[i]))
15579bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
15589bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned SR = getScratchReg();
15599bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      duplicateToTop(PendingST[i], SR, I);
15609bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      DEBUG(dbgs() << "Duplicating ST" << i << " in FP"
15619bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen                   << unsigned(PendingST[i]) << " to avoid clobbering it.\n");
15629bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      PendingST[i] = SR;
15639bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
15649bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15659bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Make sure we have a unique live register for every fixed use. Some of
15669bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // them could be undef uses, and we need to emit LD_F0 instructions.
15679bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = 0; i < NumSTUses; ++i) {
15689bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (i < NumPendingSTs && PendingST[i] < NumFPRegs) {
15699bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        // Check for shared assignments.
15709bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        for (unsigned j = 0; j < i; ++j) {
15719bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          if (PendingST[j] != PendingST[i])
15729bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen            continue;
15739bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          // STi and STj are inn the same register, create a copy.
15749bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          unsigned SR = getScratchReg();
15759bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          duplicateToTop(PendingST[i], SR, I);
15769bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          DEBUG(dbgs() << "Duplicating ST" << i << " in FP"
15779bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen                       << unsigned(PendingST[i])
15789bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen                       << " to avoid collision with ST" << j << '\n');
15799bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen          PendingST[i] = SR;
15809bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        }
15819bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
15829bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      }
15839bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned SR = getScratchReg();
15849bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      DEBUG(dbgs() << "Emitting LD_F0 for ST" << i << " in FP" << SR << '\n');
15859bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      BuildMI(*MBB, I, MI->getDebugLoc(), TII->get(X86::LD_F0));
15869bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      pushReg(SR);
15879bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      PendingST[i] = SR;
15889bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (NumPendingSTs == i)
15899bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        ++NumPendingSTs;
15909bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
15919bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    assert(NumPendingSTs >= NumSTUses && "Fixed registers should be assigned");
15929bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15939bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Now we can rearrange the live registers to match what was requested.
15949bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    shuffleStackTop(PendingST, NumPendingSTs, I);
15959bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    DEBUG({dbgs() << "Before asm: "; dumpStack();});
15969bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
15979bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // With the stack layout fixed, rewrite the FP registers.
15989bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
15999bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      MachineOperand &Op = MI->getOperand(i);
16009bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
16019bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
16029bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned FPReg = getFPReg(Op);
16039bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      Op.setReg(getSTReg(FPReg));
1604e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    }
1605e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner
16069bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Simulate the inline asm popping its inputs and pushing its outputs.
16079bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    StackTop -= NumSTPopped;
16089bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
16099bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // Hold the fixed output registers in scratch FP registers. They will be
16109bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // transferred to real FP registers by copies.
16119bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    NumPendingSTs = 0;
16129bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = 0; i < NumSTDefs; ++i) {
16139bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      unsigned SR = getScratchReg();
16149bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      pushReg(SR);
16159bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      FPKills &= ~(1u << SR);
16169bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
16179bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = 0; i < NumSTDefs; ++i)
16189bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      PendingST[NumPendingSTs++] = getStackEntry(i);
16199bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    DEBUG({dbgs() << "After asm: "; dumpStack();});
16209bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
16219bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // If any of the ST defs were dead, pop them immediately. Our caller only
16229bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    // handles dead FP defs.
16239bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    MachineBasicBlock::iterator InsertPt = MI;
16249bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    for (unsigned i = 0; STDefs & (1u << i); ++i) {
16259bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (!(STDeadDefs & (1u << i)))
16269bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        continue;
16279bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      freeStackSlotAfter(InsertPt, PendingST[i]);
16289bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      PendingST[i] = NumFPRegs;
16299bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    }
16309bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    while (NumPendingSTs && PendingST[NumPendingSTs - 1] == NumFPRegs)
16319bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      --NumPendingSTs;
16329bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
1633e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // If this asm kills any FP registers (is the last use of them) we must
1634e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // explicitly emit pop instructions for them.  Do this now after the asm has
1635e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // executed so that the ST(x) numbers are not off (which would happen if we
1636e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // did this inline with operand rewriting).
1637e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    //
1638e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // Note: this might be a non-optimal pop sequence.  We might be able to do
1639e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // better by trying to pop in stack order or something.
16409bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen    while (FPKills) {
1641c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer      unsigned FPReg = countTrailingZeros(FPKills);
16429bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      if (isLive(FPReg))
16439bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen        freeStackSlotAfter(InsertPt, FPReg);
16449bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen      FPKills &= ~(1U << FPReg);
16457261fb2a6f1458a70e55ba03fb71f7ab70af8103Jakob Stoklund Olesen    }
1646e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    // Don't delete the inline asm!
1647e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner    return;
1648e12ecf272d90c366e15531c15b6681ab5399ba33Chris Lattner  }
16499bbe4d6c004f25bc491e2583cce7bc91891f68c7Jakob Stoklund Olesen
16501a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer  case X86::WIN_FTOL_32:
16511a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer  case X86::WIN_FTOL_64: {
16521a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    // Push the operand into ST0.
16531a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    MachineOperand &Op = MI->getOperand(0);
16541a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    assert(Op.isUse() && Op.isReg() &&
16551a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      Op.getReg() >= X86::FP0 && Op.getReg() <= X86::FP6);
16561a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    unsigned FPReg = getFPReg(Op);
16571a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    if (Op.isKill())
16581a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      moveToTop(FPReg, I);
16591a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    else
16601a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      duplicateToTop(FPReg, FPReg, I);
16611a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer
16621a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    // Emit the call. This will pop the operand.
16631a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    BuildMI(*MBB, I, MI->getDebugLoc(), TII->get(X86::CALLpcrel32))
16641a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      .addExternalSymbol("_ftol2")
16651a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      .addReg(X86::ST0, RegState::ImplicitKill)
16663cd645701a2948e3d423ca6f98f872e8dd40f403Craig Topper      .addReg(X86::ECX, RegState::ImplicitDefine)
16671a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      .addReg(X86::EAX, RegState::Define | RegState::Implicit)
16681a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      .addReg(X86::EDX, RegState::Define | RegState::Implicit)
16691a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer      .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
16701a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    --StackTop;
16711a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer
16721a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer    break;
16731a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer  }
16741a2d061ec08b86ba91d7009b6ffcf08d5bac3f42Michael J. Spencer
167536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case X86::RETQ:
167636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case X86::RETL:
167736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case X86::RETIL:
167836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case X86::RETIQ:
1679447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // If RET has an FP register use operand, pass the first one in ST(0) and
1680447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // the second one in ST(1).
1681e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
1682447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // Find the register operands.
1683447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    unsigned FirstFPRegOp = ~0U, SecondFPRegOp = ~0U;
1684e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    unsigned LiveMask = 0;
1685e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
1686447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1687447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      MachineOperand &Op = MI->getOperand(i);
1688d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman      if (!Op.isReg() || Op.getReg() < X86::FP0 || Op.getReg() > X86::FP6)
1689447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner        continue;
169035831d06fdd17f42897a9931555c17af490c06eeChris Lattner      // FP Register uses must be kills unless there are two uses of the same
169135831d06fdd17f42897a9931555c17af490c06eeChris Lattner      // register, in which case only one will be a kill.
169235831d06fdd17f42897a9931555c17af490c06eeChris Lattner      assert(Op.isUse() &&
169335831d06fdd17f42897a9931555c17af490c06eeChris Lattner             (Op.isKill() ||                        // Marked kill.
169435831d06fdd17f42897a9931555c17af490c06eeChris Lattner              getFPReg(Op) == FirstFPRegOp ||       // Second instance.
169535831d06fdd17f42897a9931555c17af490c06eeChris Lattner              MI->killsRegister(Op.getReg())) &&    // Later use is marked kill.
169635831d06fdd17f42897a9931555c17af490c06eeChris Lattner             "Ret only defs operands, and values aren't live beyond it");
1697447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner
1698447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      if (FirstFPRegOp == ~0U)
1699447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner        FirstFPRegOp = getFPReg(Op);
1700447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      else {
1701447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner        assert(SecondFPRegOp == ~0U && "More than two fp operands!");
1702447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner        SecondFPRegOp = getFPReg(Op);
1703447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      }
1704e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen      LiveMask |= (1 << getFPReg(Op));
1705447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner
1706447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Remove the operand so that later passes don't see it.
1707447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      MI->RemoveOperand(i);
1708447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      --i, --e;
1709447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    }
1710e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
1711e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // We may have been carrying spurious live-ins, so make sure only the returned
1712e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    // registers are left live.
1713e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    adjustLiveRegs(LiveMask, MI);
1714e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    if (!LiveMask) return;  // Quick check to see if any are possible.
1715e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
1716447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // There are only four possibilities here:
1717447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // 1) we are returning a single FP value.  In this case, it has to be in
1718447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    //    ST(0) already, so just declare success by removing the value from the
1719447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    //    FP Stack.
1720447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    if (SecondFPRegOp == ~0U) {
1721447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Assert that the top of stack contains the right FP register.
1722447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      assert(StackTop == 1 && FirstFPRegOp == getStackEntry(0) &&
1723447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner             "Top of stack not the right register for RET!");
1724a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1725447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Ok, everything is good, mark the value as not being on the stack
1726447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // anymore so that our assertion about the stack being empty at end of
1727447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // block doesn't fire.
1728447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      StackTop = 0;
1729447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      return;
1730447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    }
1731a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1732447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // Otherwise, we are returning two values:
1733447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    // 2) If returning the same value for both, we only have one thing in the FP
1734447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    //    stack.  Consider:  RET FP1, FP1
1735447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    if (StackTop == 1) {
1736447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      assert(FirstFPRegOp == SecondFPRegOp && FirstFPRegOp == getStackEntry(0)&&
1737447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner             "Stack misconfiguration for RET!");
1738a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1739447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // Duplicate the TOS so that we return it twice.  Just pick some other FPx
1740447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      // register to hold it.
1741e098e7a96d869367f95df0dbcafa3ededce765b6Jakob Stoklund Olesen      unsigned NewReg = getScratchReg();
1742447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      duplicateToTop(FirstFPRegOp, NewReg, MI);
1743447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      FirstFPRegOp = NewReg;
1744447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    }
1745a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1746447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    /// Okay we know we have two different FPx operands now:
1747447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    assert(StackTop == 2 && "Must have two values live!");
1748a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1749447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    /// 3) If SecondFPRegOp is currently in ST(0) and FirstFPRegOp is currently
1750447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    ///    in ST(1).  In this case, emit an fxch.
1751447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    if (getStackEntry(0) == SecondFPRegOp) {
1752447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      assert(getStackEntry(1) == FirstFPRegOp && "Unknown regs live");
1753447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner      moveToTop(FirstFPRegOp, MI);
1754447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    }
1755a20e1e7ef596842127794372244fd5c646f71296Chad Rosier
1756447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    /// 4) Finally, FirstFPRegOp must be in ST(0) and SecondFPRegOp must be in
1757447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    /// ST(1).  Just remove both from our understanding of the stack and return.
1758447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    assert(getStackEntry(0) == FirstFPRegOp && "Unknown regs live");
17590353526ed11fc308cf34465e4d14a6cadf8cfb62Chris Lattner    assert(getStackEntry(1) == SecondFPRegOp && "Unknown regs live");
1760447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    StackTop = 0;
1761447ff68c08bc01aa040ae6d0291af69b55bb8e57Chris Lattner    return;
1762a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner  }
1763a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner
1764c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos  I = MBB->erase(I);  // Remove the pseudo instruction
1765e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen
1766e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // We want to leave I pointing to the previous instruction, but what if we
1767e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  // just erased the first instruction?
1768e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  if (I == MBB->begin()) {
1769e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    DEBUG(dbgs() << "Inserting dummy KILL\n");
1770e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    I = BuildMI(*MBB, I, DebugLoc(), TII->get(TargetOpcode::KILL));
1771e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen  } else
1772e928ec9480072ed1298fba2fbd8faa0e89253bf1Jakob Stoklund Olesen    --I;
1773a960d95253be892d5f2e3017ba5df989c247a0c1Chris Lattner}
1774