X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86InstrInfo.cpp;h=31a4f6fe2e7e7f87e436ce0ddb9b0effbf0594d2;hb=2dadaea5d2613125c0f7de33febdc44d97ae9648;hp=a13498e3ae4b9561dedc1629225345fd3febd138;hpb=5aee0b97aa46cb25ccfe157a3a5612d155519b28;p=oota-llvm.git diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index a13498e3ae4..31a4f6fe2e7 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1,10 +1,10 @@ //===- X86InstrInfo.cpp - X86 Instruction Information -----------*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file contains the X86 implementation of the TargetInstrInfo class. @@ -28,7 +28,13 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI, unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); if (oc == X86::MOV8rr || oc == X86::MOV16rr || oc == X86::MOV32rr || - oc == X86::FpMOV) { + oc == X86::FpMOV || oc == X86::MOVSSrr || oc == X86::MOVSDrr || + oc == X86::FsMOVAPSrr || oc == X86::FsMOVAPDrr || + oc == X86::MOVAPSrr || oc == X86::MOVAPDrr || + oc == X86::MOVSS2PSrr || oc == X86::MOVSD2PDrr || + oc == X86::MOVPS2SSrr || oc == X86::MOVPD2SDrr || + oc == X86::MOVDI2PDIrr || oc == X86::MOVQI2PQIrr || + oc == X86::MOVPDI2DIrr) { assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && @@ -40,6 +46,58 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI, return false; } +unsigned X86InstrInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case X86::MOV8rm: + case X86::MOV16rm: + case X86::MOV32rm: + case X86::FpLD64m: + case X86::MOVSSrm: + case X86::MOVSDrm: + case X86::MOVAPSrm: + case X86::MOVAPDrm: + if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && + MI->getOperand(3).isRegister() && MI->getOperand(4).isImmediate() && + MI->getOperand(2).getImmedValue() == 1 && + MI->getOperand(3).getReg() == 0 && + MI->getOperand(4).getImmedValue() == 0) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} + +unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case X86::MOV8mr: + case X86::MOV16mr: + case X86::MOV32mr: + case X86::FpSTP64m: + case X86::MOVSSmr: + case X86::MOVSDmr: + case X86::MOVAPSmr: + case X86::MOVAPDmr: + if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && + MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() && + MI->getOperand(1).getImmedValue() == 1 && + MI->getOperand(2).getReg() == 0 && + MI->getOperand(3).getImmedValue() == 0) { + FrameIndex = MI->getOperand(0).getFrameIndex(); + return MI->getOperand(4).getReg(); + } + break; + } + return 0; +} + + + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target /// may be able to convert a two-address instruction into a true @@ -55,8 +113,8 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr *MI) const { unsigned Dest = MI->getOperand(0).getReg(); unsigned Src = MI->getOperand(1).getReg(); - // FIXME: None of these instructions are promotable to LEAs without - // additional information. In particular, LEA doesn't set the flags that + // FIXME: None of these instructions are promotable to LEAs without + // additional information. In particular, LEA doesn't set the flags that // add and inc do. :( return 0; @@ -121,6 +179,35 @@ MachineInstr *X86InstrInfo::convertToThreeAddress(MachineInstr *MI) const { return 0; } +/// commuteInstruction - We have a few instructions that must be hacked on to +/// commute them. +/// +MachineInstr *X86InstrInfo::commuteInstruction(MachineInstr *MI) const { + switch (MI->getOpcode()) { + case X86::SHRD16rri8: // A = SHRD16rri8 B, C, I -> A = SHLD16rri8 C, B, (16-I) + case X86::SHLD16rri8: // A = SHLD16rri8 B, C, I -> A = SHRD16rri8 C, B, (16-I) + case X86::SHRD32rri8: // A = SHRD32rri8 B, C, I -> A = SHLD32rri8 C, B, (32-I) + case X86::SHLD32rri8:{// A = SHLD32rri8 B, C, I -> A = SHRD32rri8 C, B, (32-I) + unsigned Opc; + unsigned Size; + switch (MI->getOpcode()) { + default: assert(0 && "Unreachable!"); + case X86::SHRD16rri8: Size = 16; Opc = X86::SHLD16rri8; break; + case X86::SHLD16rri8: Size = 16; Opc = X86::SHRD16rri8; break; + case X86::SHRD32rri8: Size = 32; Opc = X86::SHLD32rri8; break; + case X86::SHLD32rri8: Size = 32; Opc = X86::SHRD32rri8; break; + } + unsigned Amt = MI->getOperand(3).getImmedValue(); + unsigned A = MI->getOperand(0).getReg(); + unsigned B = MI->getOperand(1).getReg(); + unsigned C = MI->getOperand(2).getReg(); + return BuildMI(Opc, 3, A).addReg(C).addReg(B).addImm(Size-Amt); + } + default: + return TargetInstrInfo::commuteInstruction(MI); + } +} + void X86InstrInfo::insertGoto(MachineBasicBlock& MBB, MachineBasicBlock& TMBB) const {