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