//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an instruction selector for the V8 target
//
//===----------------------------------------------------------------------===//
#include "SparcV8.h"
#include "SparcV8TargetMachine.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/Debug.h"
#include <iostream>
using namespace llvm;
//===----------------------------------------------------------------------===//
// TargetLowering Implementation
//===----------------------------------------------------------------------===//
namespace V8ISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
CMPICC, // Compare two GPR operands, set icc.
CMPFCC, // Compare two FP operands, set fcc.
BRICC, // Branch to dest on icc condition
BRFCC, // Branch to dest on fcc condition
SELECT_ICC, // Select between two values using the current ICC flags.
SELECT_FCC, // Select between two values using the current FCC flags.
Hi, Lo, // Hi/Lo operations, typically on a global address.
FTOI, // FP to Int within a FP register.
ITOF, // Int to FP within a FP register.
CALL, // A V8 call instruction.
RET_FLAG, // Return with a flag operand.
};
}
/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC
/// condition.
static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
switch (CC) {
default: assert(0 && "Unknown integer condition code!");
case ISD::SETEQ: return V8CC::ICC_E;
case ISD::SETNE: return V8CC::ICC_NE;
case ISD::SETLT: return V8CC::ICC_L;
case ISD::SETGT: return V8CC::ICC_G;
case ISD::SETLE: return V8CC::ICC_LE;
case ISD::SETGE: return V8CC::ICC_GE;
case ISD::SETULT: return V8CC::ICC_CS;
case ISD::SETULE: return V8CC::ICC_LEU;
case ISD::SETUGT: return V8CC::ICC_GU;
case ISD::SETUGE: return V8CC::ICC_CC;
}
}
/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC
/// FCC condition.
static V8CC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
switch (CC) {
default: assert(0 && "Unknown fp condition code!");
case ISD::SETEQ: return V8CC::FCC_E;
case ISD::SETNE: return V8CC::FCC_NE;
case ISD::SETLT: return V8CC::FCC_L;
case ISD::SETGT: return V8CC::FCC_G;
case ISD::SETLE: return V8CC::FCC_LE;
case ISD::SETGE: return V8CC::FCC_GE;
case ISD::SETULT: return V8CC::FCC_UL;
case ISD::SETULE: return V8CC::FCC_ULE;
case ISD::SETUGT: return V8CC::FCC_UG;
case ISD::SETUGE: return V8CC::FCC_UGE;
case ISD::SETUO: return V8CC::FCC_U;
case ISD::SETO: return V8CC::FCC_O;
case ISD::SETONE: return V8CC::FCC_LG;
case ISD::SETUEQ: return V8CC::FCC_UE;
}
}
namespace {
class SparcV8TargetLowering : public TargetLowering {
int VarArgsFrameOffset; // Frame offset to start of varargs area.
public:
SparcV8TargetLowering(TargetMachine &TM);
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
/// be zero. Op is expected to be a target specific node. Used by DAG
/// combiner.
virtual bool isMaskedValueZeroForTargetNode(const SDOperand &Op,
<